

Программирование на языке MFC
Мой второй блог в серии программирования
Макрос BEGIN_MESSAGE_MAP
Во-первых, этот макрос завершает таблицу сообщений записью с нулевой сигнатурой. Во-вторых, он ставит ту самую завершающую фигурную скобку, которой мы недосчитались при анализе текста макроса BEGIN_MESSAGE_MAP. На этом наше знакомство с таблицей сообщений можно завершить.
Перед началом рассмотрения таблицы сообщений мы остановились на методе DispatchThreadMessageEx() класса CWinThread. Итак, вернемся к коду этого метода и продолжим работу.
Итак, что происходит в этом методе? Сначала метод выбирает указатель на таблицу сообщений при помощи метода GetMessageMap(), а затем входит в цикл для поиска необходимого обработчика сообщений. При этом обработка сообщений с кодом менее OxCOOO несколько отличается от обработки сообщений с кодом от OxCOOO и выше.
Если обрабатывается сообщение с кодом менее OxCOOO, это означает, что сообщение является сообщением Windows. Для поиска необходимого обработчика вызывается функция AfxFind-MessageEntry(). Исходный код этой функции находится в файле wincore.cpp:

AfxFindMessageEntry(const AFX_MSGMAP_ENTRY* IpEntry,
UINT nMsg, UINT nCode, UINT nID)
{
#if defined(_M_IX86) && !defined(_AFX_PORTABLE) // 32-bit Intel 386/486 version.
ASSERT(offsetof(AFX_MSGMAP_ENTRY, nMessage) == 0) ;
ASSERT(offsetof(AFX_MSGMAP_ENTRY, nCode) == 4);
ASSERT(offsetof(AFX_MSGMAPJ2NTRY, nIDl == 8);
ASSERT(offsetof(AFX_MSGMAP_ENTRY, nLastID) == 12);
ASSERT(offsetof(AFX_MSGMAP_ENTRY, nSig) == 16);
asm
MOV EBX,IpEntry
MOV EAX, nMsg
MOV EDX,nCode
MOV ECX,nID
loop:
CMP DWORD PTR [EBX+16],0
JZ _ failed
CMP EAX,DWORD PTR [EBX]
JE found_message
nSig (0 => end)
nMessage
next:
ADD EBX,SIZE AFX_MSGMAP_ENTRY
JMP short loop
found_message:
CMP EDX,DWORD PTR [EBX+4]
JNE next
nCode
// message and code good so far // check the ID
CMP ECX,DWORD PTR [EBX+8]
JB _ next
CMP ECX,DWORD PTR [EBX+12]
JA next
nID
nLastID
// found a match
MOV IpEntry,EBX
JMP short end
return EBX
failed:
XOR EAX,EAX
MOV IpEntry,EAX
return NULL
end:
return IpEntry; #else // _AFX_PORTABLE
// С version of search routine while (lpEntry->nSig != AfxSig_end) {
if (lpEntry->nMessage — nMsg && lpEntry->nCode == nCode && nID >= lpEntry->nID && nID <= lpEntry->nLastID)
{
return IpEntry;
}
lpEntry++;
}
return NULL; // not found #endif // _AFX_PORTABLE }
Похожие статьи: Макрос BEGIN_MESSAGE_MAP
