Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

Функция:

BitBlt (hdc, 100, 0, 50, 100, hdc, 0, 0, SRCCOPY);

копирует прямоугольник с вершиной в логической точке (0, 0), шириной 50 и высотой 100 логических единиц в прямоугольную область с вершиной в логической точке (100,0).

Функция DrawBitmap

Функция BitBlt наиболее эффективна при работе с битовыми образами, которые выбраны в контекст памяти. Когда выполняется перенос блока битов (bit block transfer) из контекста памяти в контекст устройства рабочей области, битовый образ, выбранный в контексте памяти переносится в рабочую область.

Ранее упоминалась гипотетическая функция DrawBitmap, которая выводила бы битовый образ на поверхность отображения. Такая функция должна иметь следующий синтаксис:

DrawBitmap (hdc, hBitmap, xStart, yStart);

void DrawBitmap (HDC hdc, HBITMAP hBitmap, int xStart, int yStart)

{

BITMAP bm;

HDC hdcMem;

DWORD dwSize;

POINT ptSize, ptOrg;

hdcMem = CreateCompatibleDC (hdc);

SelectObject (hdcMem, hBitmap);

SetMapMode (hdcMem, GetMapMode (hdc));

GetObject (hBitmap, sizeof (BITMAP), (LPVOID) &bm);

ptSize. x = bm. bmWidth;

ptSize. y = bm. bmHeight;

DPtoLP (hdc, &ptSize, 1);

ptOrg. x = 0;

ptOrg. y = 0;

DPtoLP (hdcMem, &ptOrg, 1);

BitBlt (hdc, xStart, yStart, ptSize. x, ptSize. y,

hdcMem, ptOrg. x, ptOrg. y, SRCCOPY);

DeleteDC (hdcMem);

}

Здесь предполагается, что нет надобности растягивать или сжимать высоту или ширину битового образа. Таким образом, если битовый образ имеет ширину 100 пикселей, то вы сможно с его помощью закрыть любой прямоугольник, имеющий ширину 100 пикселей, независимо от режима отображения.

НЕ нашли? Не то? Что вы ищете?

Функция DrawBitmap сначала создает контекст памяти, используя функцию CreateCompatibleDC, затем выбирает в него битовый образ с использованием функции SelectObject. Режим отображения контекста памяти устанавливается таким же, как режим отображения контекста устройства вывода. Поскольку функция BitBlt работает с логическими координатами и логическими размерами, и учитывая то, что не предполагается растягивать или сжимать битовый образ, параметры xWidth и yHeight функции BitBlt должны иметь значения в логических координатах, соответствующих размерам битового образа в физических координатах. Поэтому, функция DrawBitmap определяет размеры битового образа, используя функцию GetObject, и создает структуру POINT для сохранения в ней ширины и высоты. Затем она преобразует эту точку в логические координаты. Аналогичные действия осуществляются и в отношении начала координат битового образа — точки (0, 0) в координатах устройства.

Растяжение битовых образов с помощью функции StretchBlt

Функция StretchBlt имеет два дополнительных параметра по сравнению с функцией BitBlt :

StretchBlt (hdcDest, xDest, yDest, xDestWidth, yDestHeight,

hdcSrc, xSrc, ySrc, xSrcWidth, ySrcHeight, dwROP);

Поскольку функция StretchBlt имеет различные параметры ширины и высоты исходного и приемного прямоугольников, становится возможным растяжение или сжатие битового образа исходного контекста устройства для того, чтобы занять большую или меньшую область в приемном контексте устройства.

Так же как функция BitBlt — есть расширение функции PatBlt, так и функция StretchBlt — есть расширение функции BitBlt, позволяющее задавать раздельно размеры исходного и приемного прямоугольника. Как и у функций PatBlt и BitBlt все координаты и значения в функции StretchBlt задаются в логических единицах. Функция StretchBlt также позволяет переворачивать изображение по горизонтали и вертикали. Если знаки xSrcWidth и xDestWidth (при преобразовании в единицы устройства) различны, то функция StretchBlt создает зеркальное изображение: левая часть становится правой, правая часть — левой. Если знаки ySrcHeight и yDestHeight (при преобразовании в единицы устройства) различны, то функция StretchBlt переворачивает изображение по вертикали.

Функция StretchBlt может работать достаточно медленно, особенно с большими битовыми образами. Кроме того, существуют проблемы, связанные с трудностями масштабирования битовых образов. При растяжении битового образа функция StretchBlt должна дублировать строки или столбцы пикселей. Если растяжение происходит не в целое число раз, то в результате может получиться искаженный образ.

При сжатии битового образа функция StretchBlt должна комбинировать две или более строки или столбца пикселей в одну строку или столбец. Она делает это одним из трех способов в зависимости от атрибута режима растяжения в контексте устройства. Можно использовать функцию SetStretchBltMode для изменения этого атрибута:

SetStretchBltMode (hdc, iMode);

Величина iMode может принимать следующие значения:

q BLACKONWHITE (по умолчанию) — Если два или более пикселей должны быть преобразованы в один пиксель, то функция StretchBlt выполняет логическую операцию AND над пикселями. Результирующий пиксель будет белым только в том случае, если все исходные пиксели были белыми, что на практике означает, что черные пиксели преобладают над белыми.

q WHITEONBLACK — Если два или более пикселей должны быть преобразованы в один пиксель, то функция StretchBlt выполняет логическую операцию OR над пикселями. Результирующий пиксель будет черным только в том случае, если все исходные пиксели были черными, что означает, что белые пиксели преобладают над черными.

q COLORONCOLOR — функция StretchBlt просто уничтожает строки или столбцы пикселей без выполнения логических операций. Иногда, это лучший подход для цветных битовых образов, поскольку два других режима могут вызвать искажения цветов.

Кисти и битовые образы

Когда используются функции CreatePatternBrush или CreateBrushIndirect с полем lbStyle, установленным в значение BS_PATTERN, необходимо сначала получить описатель битового образа. Битовый образ должен быть размером как минимум 8 на 8 пикселей. Если он больше, то Windows использует только левый верхний угол битового образа для кисти.

Поскольку кисти и битовые образы — объекты GDI, необходимо удалить все объекты, созданные до того, как программа завершится. Когда создается кисть на базе битового образа, Windows делает копию данных битового образа для использования при рисовании кистью. Можно удалить битовый образ сразу же после вызова функций CreatePatternBrush или CreateBrushIndirect без какого-либо влияния на кисть. Аналогично, можно удалить кисть без влияния на битовый образ.

Можно создать битовый образ в виде небольшого файла в программе Microsoft Developer Studio и определить его в программе как ресурс. При его загрузке получается описатель битового образа:

hBitmap = LoadBitmap (hInstance, "Brick");

hBrush = CreatePatternBrush (hBitmap);

Когда будет действительный контекст устройства, надо выбрать кисть в контекст устройства и отобразить прямоугольник:

SelectObject (hdc, hBrush);

Rectangle (hdc, xLeft, yTop, xRight, yBottom);

Когда освободится контекст устройства, удалить кисть и битовый образ:

DeleteObject (hBrush);

DeleteObject (hBitmap);

Для удаления битового образа не нужно ждать, пока освободится контекст устройства. Можно сделать это в любой момент после создания кисти на основе битового образа.

Можно также описать пиксели битового образа в программе как массив восьми беззнаковых целых. Каждое целое соответствует скан-линии в шаблоне битового образа. Бит, равный 1, используется для задания белого цвета, бит, равный 0 — для черного:

HBITMAP hBitmap;

HBRUSH hBrush;

static WORD wBrickBits [] =

{ 0xFF, 0x0C, 0x0C, 0x0C, 0xFF, 0xC0, 0xC0, 0xC0 };

Битовый образ создается функцией CreateBitmap с параметром — ссылкой на массив целых:

hBitmap = CreateBitmap (8, 8, 1, 1, (LPVOID) &wBrickBits);

hBrush = CreatePatternBrush (hBitmap);

Основанная на сообщениях архитектура Windows идеальна для работы с клавиатурой. Программа узнает о нажатиях клавиш посредством сообщений, которые посылаются оконной процедуре.

На самом деле все происходит не столь просто: когда пользователь нажимает и отпускает клавиши, драйвер клавиатуры передает информацию о нажатии клавиш в Windows. Windows сохраняет эту информацию (в виде сообщений) в системной очереди сообщений. Затем она передает сообщения клавиатуры, по одному за раз, в очередь сообщений программы, содержащей окно, имеющее "фокус ввода" (input focus) (о котором вскоре будет рассказано). Затем программа отправляет сообщения соответствующей оконной процедуре.

Смысл этого двухступенчатого процесса — сохранение сообщений в системной очереди сообщений, и дальнейшая их передача в очередь сообщений приложения — в синхронизации. Если пользователь печатает на клавиатуре быстрее, чем программа может обрабатывать поступающую информацию, Windows сохраняет информацию о дополнительных нажатиях клавиш в системной очереди сообщений, поскольку одно из этих дополнительных нажатий может быть переключением фокуса ввода на другую программу. Информацию о последующих нажатиях следует затем направлять в другую программу. Таким образом, Windows корректно синхронизирует такие сообщения клавиатуры.

Для отражения различных событий клавиатуры, Windows посылает программам восемь различных сообщений. Это может показаться излишним, и программа вполне может игнорировать многие из них. Кроме того, в большинстве случаев, в этих сообщениях от клавиатуры содержится значительно больше закодированной информации, чем нужно программе. Залог успешной работы с клавиатурой — это знание того, какие сообщения важны, а какие нет.

Аппаратные и символьные сообщения

Сообщения, которые приложение получает от Windows о событиях, относящихся к клавиатуре, различаются на "аппаратные" (keystrokes) и "символьные" (characters). Такое положение соответствует двум представлениям о клавиатуре. Во-первых, можно считать клавиатуру набором клавиш. В клавиатуре имеется только одна клавиша <A>. Нажатие на эту клавишу является аппаратным событием. Отпускание этой клавиши является аппаратным событием. Но клавиатура также является устройством ввода, генерирующем отображаемые символы. Клавиша <А>, в зависимости от состояния клавиш <Ctrl>, <Shift> и <CapsLock>, может стать источником нескольких символов. Обычно, этим символом является строчное ‘a’. Если нажата клавиша <Shift> или установлен режим Caps Lock, то этим символом является прописное <А>. Если нажата клавиша <Ctrl>, этим символом является <Ctrl>+<А>. На клавиатуре, поддерживающей иностранные языки, аппаратному событию ‘А’ может предшествовать либо специальная клавиша, либо <Shift>, либо <Ctrl>, либо <Alt>, либо их различные сочетания. Эти сочетания могут стать источником вывода строчного ‘а’ или прописного ‘А’ с символом ударения.

Для сочетаний аппаратных событий, которые генерируют отображаемые символы, Windows посылает программе и оба аппаратных и символьное сообщения. Некоторые клавиши не генерируют символов. Это такие клавиши, как клавиши переключения, функциональные клавиши, клавиши управления курсором и специальные клавиши, такие как Insert и Delete. Для таких клавиш Windows вырабатывает только аппаратные сообщения.

Когда нажимается клавиша, Windows помещает либо сообщение WM_KEYDOWN, либо сообщение WM_SYSKEYDOWN в очередь сообщений окна, имеющего фокус ввода. Когда отпускается клавиша, Windows помещает либо сообщение WM_KEYUP, либо сообщение WM_SYSKEYUP в очередь сообщений.

Клавиша нажата

Клавиша отпущена

Несистемные аппаратные сообщения

WM_KEYDOWN

WM_KEYUP

Системные аппаратные сообщения

WM_SYSKEYDOWN

WM_SYSKEYUP

Обычно сообщения о "нажатии" (down) и "отпускании" (up) появляются парами. Однако, если оставить клавишу нажатой так, чтобы включился автоповтор, то Windows посылает оконной процедуре серию сообщений WM_KEYDOWN (или WM_SYSKEYDOWN) и одно сообщение WM_KEYUP (или WM_SYSKEYUP), когда в конце концов клавиша будет отпущена. Также как и все синхронные сообщения, аппаратные сообщения клавиатуры также становятся в очередь. Можно с помощью функции GetMessageTime получить время нажатия и отпускания клавиши относительно старта системы.

Системные и несистемные аппаратные
сообщения клавиатуры

Префикс "SYS" в WM_SYSKEYDOWN и WM_SYSKEYUP означает "системное" (system) и относится к аппаратным сообщениям клавиатуры, которые больше важны для Windows, чем для приложений Windows. Сообщения WM_SYSKEYDOWN и WM_SYSKEYUP обычно вырабатываются при нажатии клавиш в сочетании с клавишей <Alt>. Эти сообщения вызывают опции меню программы или системного меню, или используются для системных функций, таких как смена активного окна (<Alt>+<Tab> или <Alt>+<Esc>), или как быстрые клавиши системного меню (<Alt> в сочетании с функциональной клавишей). Программы обычно игнорируют сообщения WM_SYSKEYDOWN и WM_SYSKEYUP и передают их DefWindowProc. Поскольку Windows отрабатывает всю логику Alt-клавиш, то фактически не нужно обрабатывать эти сообщения. оконная процедура в конце концов получит другие сообщения, являющиеся результатом этих аппаратных сообщений клавиатуры (например, выбор меню). Если необходимо включить в код оконной процедуры инструкции для обработки аппаратных сообщений клавиатуры (как мы это сделаем в программе KEYLOOK, представленной далее в этой главе), то после обработки этих сообщений передайте их в DefWindowProc, чтобы Windows могла по-прежнему их использовать в обычных целях.

Но подумайте немного об этом. Почти все, что влияет на окно программы, в первую очередь проходит через оконную процедуру. Windows каким-то образом обрабатывает сообщения только в том случае, если они передаются в DefWindowProc. Например, если добавить строки:

case WM_SYSKEYDOWN;

case WM_SYSKEYUP;

case WM_SYSCHAR;

return 0;

в оконную процедуру, то запретяться все операции с клавишей <Alt> (команды меню, <Alt>+<Tab>, <Alt>+<Esc> и т. д.), когда программа имеет фокус ввода.

Сообщения WM_KEYDOWN и WM_KEYUP обычно вырабатываются для клавиш, которые нажимаются и отпускаются без участия клавиши <Alt>. программа может использовать или не использовать эти сообщения клавиатуры. Сама Windows их игнорирует.

Переменная lParam

Для всех аппаратных сообщений клавиатуры, 32-разрядная переменная lParam, передаваемая в оконную процедуру, состоит из шести полей: счетчика повторений (Repeat Count), cкан‑кода OEM (Original Equipment Manufacturer Scan Code), флага расширенной клавиатуры (Extended Key Flag), кода контекста (Context Code), флага предыдущего состояния клавиши (Previous Key State) и флага состояния клавиши (Transition State).

Шесть полей переменной lParam аппаратных сообщений
клавиатуры

Код контекста

Код контекста устанавливается в 1, если нажата клавиша <Alt>. Этот разряд всегда равен 1 для сообщений WM_SYSKEYDOWN и WM_SYSKEYUP и 0 для сообщений WM_KEYDOWN и WM_KEYUP с двумя исключениями:

q Если активное окно минимизировано, оно не имеет фокус ввода. Все нажатия клавиш вырабатывают сообщения WM_SYSKEYDOWN и WM_SYSKEYUP. Если не нажата клавиша <Alt>, поле кода контекста устанавливается в 0. (Windows использует SYS сообщения клавиатуры так, чтобы активное окно, которое минимизировано, не обрабатывало эти сообщения.)

q На некоторых иноязычных клавиатурах некоторые символы генерируются комбинацией клавиш <Shift>, <Ctrl> или <Alt> с другой клавишей. В этих случаях, у переменной lParam, которая сопровождает сообщения WM_KEYDOWN и WM_KEYUP, в поле кода контекста ставится 1, но эти сообщения не являются системными сообщениями клавиатуры.

Использование сообщений клавиатуры

Идея программы, получающей информацию о нажатии любой клавиши несомненно привлекательна; однако, большинство программ для Windows игнорируют все, кроме нескольких сообщений о нажатии и отпускании клавиш. Сообщения WM_SYSKEYUP и WM_SYSKEYDOWN адресованы системным функциям Windows, и не нужно их отслеживать. Если вы обрабатываете сообщения WM_KEYDOWN, то сообщения WM_KEYUP обычно также можно игнорировать.

Программы для Windows обычно используют сообщения WM_KEYDOWN для нажатия и отпускания клавиш, которые не генерируют символьные сообщения. Хотя можно подумать, что есть возможность использовать сообщения о нажатии клавиш в сочетании с информацией о состоянии клавиш сдвига для преобразования сообщений о нажатии клавиш в символьные сообщения, не делайте так. Будут проблемы из-за отличий международных клавиатур. Например, если получается сообщение WM_KEYDOWN с wParam равным 33H, то пользователь нажал клавишу <3>. Если используется GetKeyState и обнаруживаете, что клавиша <Shift> нажата, то можно было бы предположить, что пользователь печатает знак фунта стерлингов <£>. Вовсе необязательно. Британский пользователь печатает знак <&>. Поэтому сообщения WM_KEYDOWN более удобны для клавиш управления курсором, функциональных клавиш и специальных клавиш, таких как <Insert> и <Delete>. Однако, иногда клавиши <Insert> и <Delete>, а также функциональные клавиши используются в качестве быстрых клавиш меню. Поскольку Windows преобразует быстрые клавиши меню в сообщения команд меню, не надо обрабатывать эти сообщения. Некоторые программы, написанные не для Windows, широко используют функциональные клавиши в сочетании с клавишами <Shift>, <Ctrl> и <Alt>. Можно сделать что-то похожее в программах для Windows, но это не рекомендуется. Если необходимо использовать функциональные клавиши, то лучше, чтобы они дублировали команды меню. Одна из задач Windows — обеспечить такой пользовательский интерфейс, для которого не требуется заучивание или использование сложного набора команд.

Мы собираемся отказаться от всего, за исключением последнего пункта: большую часть времени вы будете обрабатывать сообщения WM_KEYDOWN только для клавиш управления курсором. Если используется клавиши управления курсором, то можно контролировать состояние клавиш <Shift> и <Ctrl> с помощью функции GetKeyState. Функции Windows часто используют клавишу <Shift> в сочетании с клавишами управления курсором для расширения выбора, например, в программах текстовых редакторов. Клавиша <Ctrl> часто используется для изменения значения клавиш управления курсором. (Например, <Ctrl> в сочетании с клавишей стрелки вправо могло бы означать перемещение курсора на одно слово вправо.)

Одним из лучших способов выяснить то, как использовать клавиатуру должно быть изучение использования клавиатуры в существующих популярных программах для Windows. Если это не подходит, можно действовать как-то иначе. Но в этом случае можно помешать пользователю быстро изучить программу.

Windows поддерживает однокнопочную, двухкнопочную или трехкнопочную мышь, а также позволяет использовать джойстик или световое перо для имитации однокнопочной мыши. Поскольку однокнопочная мышь является простейшей, то многие программисты, работающие под Windows, традиционно не работают со второй и третьей кнопками. Однако, двухкнопочная мышь стала стандартом де-факто, поэтому традиционная сдержанность в использовании второй кнопки неоправданна. Действительно, вторая кнопка мыши нажимается или для появления "контекстного меню", т. е. меню, которое появляется в окне помимо обычной строки меню, или для специальных операций перетаскивания. (Перетаскивание будет рассмотрено ниже.)

Можно определить наличие мыши с помощью функции GetSystemMetrics:

fMouse = GetSystemMetrics (SM_MOUSEPRESENT);

Значение fMouse будет равным TRUE (ненулевым), если мышь установлена. Для определения количества кнопок установленной мыши используйте следующий вызов:

cButtons = GetSystemMetrics (SM_CMOUSEBUTTONS);

Если мышь не инсталлирована, то возвращаемым значением этой функции будет 0.

Пользователи-левши могут поменять назначение кнопок мыши с помощью программы Control Panel. Хотя приложение может определить, было ли такое переключение, передав в функцию GetSystemMetrics параметр SM_SWAPBUTTON, но обычно это не нужно. Кнопка, нажимаемая указательным пальцем, считается левой кнопкой, даже если физически она находится на правой стороне мыши. Однако в обучающих программах можно нарисовать мышь на экране, и в этом случае надо будет узнать, менялось ли назначение кнопок мыши.

Несколько кратких определений

Когда пользователь Windows перемещает мышь, Windows перемещает по экрану маленькую растровую картинку, которая называется "курсор мыши" (mouse cursor). Курсор мыши имеет "вершину" (hot spot) размером в один пиксель, точно указывающее положение мыши на экране.

В драйвере дисплея содержатся несколько ранее определенных курсоров мыши, которые могут использоваться в программах. Наиболее типичным курсором является наклонная стрелка, которая называется IDC_ARROW и определяется в заголовочных файлах Windows. Вершина — это конец стрелки. Курсор IDC_CROSS (используемый в приведенных в этой главе программах BLOKOUT) имеет вершину в центре крестообразного шаблона. Курсор IDC_WAIT в виде песочных часов обычно используется программами для индикации того, что они чем-то заняты. Программисты также могут спроектировать свои собственные курсоры. Курсор, устанавливаемый по умолчанию, для конкретного окна задается при определении структуры класса окна. Например:

wndclass. hCursor = LoadCursor (NULL, IDC_ARROW);

Ниже приведены определения терминов, соответствующих вашим действиям над кнопками мыши:

· Щелчок — нажатие и отпускание кнопки мыши

· Двойной щелчок — двойное быстрое одно за другим нажатие и отпускание кнопки мыши

· Перетаскивание — перемещение мыши при нажатой кнопке

На трехкнопочной мыши кнопки называются левой кнопкой, средней кнопкой и правой кнопкой. В связанных с мышью идентификаторах, определенных в заголовочных файлах Windows, используются аббревиатуры LBUTTON, MBUTTON и RBUTTON. Двухкнопочная мышь имеет только левую и правую кнопки. Единственная кнопка однокнопочной мыши является левой.

Оконная процедура получает сообщения мыши и когда мышь проходит через окно и при щелчке внутри окна, даже если окно неактивно или не имеет фокуса ввода. В Windows для мыши определен набор из 21 сообщения. Однако, 11 из этих сообщений не относятся к рабочей области, и программы для Windows обычно игнорируют их.

Если мышь перемещается по рабочей области окна, оконная процедура получает сообщение WM_MOUSEMOVE. Если кнопка мыши нажимается или отпускается внутри рабочей области окна, оконная процедура получает следующие сообщения:

Кнопка

Нажатие

Отпускание

Нажатие
(Второй щелчок)

Левая

WM_LBUTTONDOWN

WM_LBUTTONUP

WM_LBUTTONDBLCLK

Средняя

WM_MBUTTONDOWN

WM_MBUTTONUP

WM_MBUTTONDBLCLK

Правая

WM_RBUTTONDOWN

WM_RBUTTONUP

WM_RBUTTONDBLCLK

оконная процедура получает сообщения "MBUTTON" только при наличии трехкнопочной мыши и сообщения "RBUTTON" только при наличии двух - или трехкнопочной мыши. Оконная процедура получает сообщения "DBLCLK" (двойной щелчок) только в том случае, если класс окна был определен так, чтобы их можно было получать.

Для всех этих сообщений значение параметра lParam содержит положение мыши. Младшее слово — это координата х, а старшее слово — координата y относительно верхнего левого угла рабочей области окна. Можно извлечь координаты х и y из параметра lParam с помощью макросов LOWORD и HIWORD, определенных в заголовочных файлах Windows. Значение параметра wParam показывает состояние кнопок мыши и клавиш <Shift> и <Ctrl>. Можно проверить параметр wParam с помощью битовых масок, определенных в заголовочных файлах. Префикс MK означает "клавиша мыши" (mouse key).

MK_LBUTTON

Левая кнопка нажата

MK_MBUTTON

Средняя кнопка нажата

MK_RBUTTON

Правая кнопка нажата

MK_SHIFT

Клавиша <Shift> нажата

MK_CONTROL

Клавиша <Ctrl> нажата

При движении мыши по рабочей области окна, Windows не вырабатывает сообщение WM_MOUSEMOVE для всех возможных положений мыши. Количество сообщений WM_MOUSEMOVE, которые получает программа, зависит от устройства мыши и от скорости, с которой оконная процедура может обрабатывать сообщения о движении мыши.

Если щелкнуть левой кнопкой мыши в рабочей области неактивного окна, Windows сделает активным окно, в котором произвели щелчок, и затем передаст оконной процедуре сообщение WM_LBUTTONDOWN. Если оконная процедура получает сообщение WM_LBUTTONDOWN, то программа может уверенно считать, что ее окно активно. Однако, оконная процедура может получить сообщение WM_LBUTTONUP, не получив вначале сообщения WM_LBUTTONDOWN. Это может случиться, если кнопка мыши нажимается в одном окне, мышь перемещается в ваше окно, и кнопка отпускается. Аналогично, оконная процедура может получить сообщение WM_LBUTTONDOWN без соответствующего ему сообщения WM_LBUTTONUP, если кнопка мыши отпускается во время нахождения в другом окне.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8