当应用程序更新窗口后,就需要不断地接收系统发过来的消息,然后处理消息,最后发送消息出去,这样就构成了应用程序的消息循环处理。不断地获取系统消息的函数是GetMessage函数,下面就是它的实现代码:
#001 BOOL WINAPI
#002 GetMessageW(LPMSG lpMsg,
#003 HWND hWnd,
#004 UINT wMsgFilterMin,
#005 UINT wMsgFilterMax)
#006 {
#007 BOOL Res;
#008 MSGCONVERSION Conversion;
#009 NTUSERGETMESSAGEINFO Info;
获取线程相关的数据。
#010 PUSER32_THREAD_DATA ThreadData = User32GetThreadData();
#011
消息转换清除。
#012 MsgConversionCleanup(lpMsg, FALSE, FALSE, NULL);
调用函数NtUserGetMessage来获取窗口的消息。
#013 Res = NtUserGetMessage(&Info, hWnd, wMsgFilterMin, wMsgFilterMax);
#014 if (-1 == (int) Res)
#015 {
#016 return Res;
#017 }
#018 Conversion.LParamSize = Info.LParamSize;
#019 Conversion.KMMsg = Info.Msg;
#020
把内核的消息方式转换用户的消息方式。
#021 if (! MsgiKMToUMMessage(&Conversion.KMMsg, &Conversion.UnicodeMsg))
#022 {
#023 return (BOOL) -1;
#024 }
#025 if (!lpMsg)
#026 {
#027 SetLastError( ERROR_NOACCESS );
#028 return FALSE;
#029 }
添加消息到转换队列。
#030 *lpMsg = Conversion.UnicodeMsg;
#031 Conversion.Ansi = FALSE;
#032 Conversion.FinalMsg = lpMsg;
#033 MsgConversionAdd(&Conversion);
#034 if (Res && lpMsg->message != WM_PAINT && lpMsg->message != WM_QUIT)
#035 {
在线程相关结构里保存最后接收的消息。
#036 ThreadData->LastMessage = Info.Msg;
#037 }
#038
#039 return Res;
#040 }