Базовые элементы Windows-приложений. Проект типа Win32 Application, страница 7

WPARAM wParam,  //запакованы: HIWORD - если сообщение от элемента управления - нотификационный код,, если сообщение от акселератора – «1», если от элемента меню, то «0». LOWORD - идентификатор элемента управления, пункта меню или акселератора

LPARAM lParam); //HWND элемента управления, пославшего сообщение или NULL

Когда пользователь выбирает пункт меню, или нажимает кнопку (а это тоже окно), или что-либо делает с любым элементом управления, оконная процедура данного окна обрабатывает стандартное сообщение WM_LBUTTONDOWN и должна как-то отреагировать. Обычно при таких действиях требуется “уведомить” родительское окно, что нужно выполнить определенное действие.

В простейшем случае “окно-отправитель” посылает “окну-получателю” самое распространенное уведомляющее сообщение Message = WM_COMMAND, а в качестве дополнительной информации в wParam запаковываются нотификационный код (в нашем случае BN_CLICKED) и идентификатор того окна-кнопки, которое послало сообщение, и lParam - дескриптор окна-кнопки.

Пример на уровне API:

#define IDC_BUTTON 1000

...

void My_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)

{        //в нашем случае wParam: LOWORD==IDC_BUTTON, HIWORD==BN_CLICKED (код уведомления) lParam – дескриптор окна-кнопки

switch(id)    // LOWORD

{

case IDC_BUTTON:

...

break;

...

}

}

LRESULT CALLBACK WndProc(HWND hWindow, UINT            Message, WPARAM wParam, LPARAM lParam)

{

switch(Message)

{

HANDLE_MSG(hWindow, WM_COMMAND, My_OnCommand);

...

}

}

Обратите внимание: - при этом wParam и lParam задействованы целиком и нет никакой возможности послать родителю еще какую-нибудь дополнительную информацию – например, координаты мыши, при которых была нажата кнопка. Поэтому, когда под Windows 3.x требовалось передать дополнительную информацию, напридумывали много «специализированных» нотификационных сообщений типа WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM..., которые продолжают жить для сохранения совместимости или медленно отмирают (obsolete). Следует отметить, что перечисленные сообщения обычно требуют от родителя реакции на посланное сообщение (reflection).

  WM_NOTIFY

Чем дальше развивались Windows, тем сложнее становились элементы управления => тем чаще возникала потребность передавать дополнительную информацию «получателю» в уведомляющих сообщениях. Можно было бы пойти по пути добавления новых сообщений типа WM_* для каждого нового нотификационного сообщения, для которого требуется дополнительная информация, но разработчики Win32 API пошли другим путем, добавив только одно сообщение WM_NOTIFY, которое может передавать любое количество дополнительной информации в стандартном формате.

Сообщения WM_NOTIFY содержат идентификатор элемента управления в wParam и указатель на структуру в lParam. Сама структура может быть типа NMHDR или структура более сложного типа, первым элементом которой является структура NMHDR. Заметьте, что именно потому, что структура NMHDR является первой, полученный указатель может быть использован как указатель на структуру NMHDR, так и большую структуру в зависимости от того, как Вы его приведете (cast). Следует отметить, что структура NMHDR используется в достаточно малом количестве уведомляющих сообщений, имена которых начинаются с NM_, а также  в уведомлениях TTN_SHOW and TTN_POP.

Формат структуры NMHDR:

typedef struct tagNMHDR {

HWND hwndFrom;

UINT idFrom;

UINT code;

} NMHDR;

Большинство уведомляющих сообщений передают указатель на большую структуру. Например от list view – элемента управления при нажатии клавиши родительскому окну посылается сообщение LVN_KEYDOWN, при этом указатель содержит адрес структуры LV_KEYDOWN:

typedef struct tagLV_KEYDOWN {

NMHDR hdr;  

WORD wVKey; 

UINT flags; 

} LV_KEYDOWN;