reactos操作系统实现(170)
co_IntPeekMessage主要实现内核里获取窗口消息,具体实现代码如下: #001 BOOL FASTCALL #002 co_IntPeekMessage(PUSER_MESSAGE Msg, #003 HWND hWnd, #004 UINT MsgFilterMin, #005 UINT MsgFilterMax, #006 UINT RemoveMsg) #007 { #008 PTHREADINFO pti; #009 LARGE_INTEGER LargeTickCount; #010 PUSER_MESSAGE_QUEUE ThreadQueue; #011 PUSER_MESSAGE Message; #012 BOOL Present,RemoveMessages; #013 USER_REFERENCE_ENTRY Ref; #014 USHORT HitTest; #015 MOUSEHOOKSTRUCT MHook; #016 #017 /* The queues and order in which they are checked are documented in the MSDN #018 article on GetMessage() */ #019
获取当前线程信息。 #020 pti = PsGetCurrentThreadWin32Thread();
取得线程的消息队列。 #021 ThreadQueue = pti->MessageQueue; #022 #023 /* Inspect RemoveMsg flags */ #024 /* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */
消息是否删除的标志。 #025 RemoveMessages = RemoveMsg & PM_REMOVE; #026 #027 CheckMessages: #028 #029 Present = FALSE; #030
获取内核计数。 #031 KeQueryTickCount(&LargeTickCount);
设置线程最后读取消息的时间。 #032 ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart; #033
分发线程的消息。 #034 /* Dispatch sent messages here. */ #035 while (co_MsqDispatchOneSentMessage(ThreadQueue)) #036 ; #037 #038 /* Now look for a quit message. */ #039
是否退出标志,如果是就构造退出消息。 #040 if (ThreadQueue->QuitPosted) #041 { #042 /* According to the PSDK,WM_QUIT messages are always returned,regardless #043 of the filter specified */
构造退出消息。 #044 Msg->Msg.hwnd = NULL; #045 Msg->Msg.message = WM_QUIT; #046 Msg->Msg.wParam = ThreadQueue->QuitExitCode; #047 Msg->Msg.lParam = 0; #048 Msg->FreeLParam = FALSE; #049 if (RemoveMessages) #050 { #051 ThreadQueue->QuitPosted = FALSE; #052 } #053 goto MsgExit; #054 } #055
查找一般的消息是否出现。 #056 /* Now check for normal messages. */ #057 Present = co_MsqFindMessage(ThreadQueue, #058 FALSE, #059 RemoveMessages, #060 hWnd, #061 MsgFilterMin, #062 MsgFilterMax, #063 &Message);
如果找到消息,就拷贝消息到用户结构里。 #064 if (Present) #065 { #066 RtlCopyMemory(Msg,Message,sizeof(USER_MESSAGE)); #067 if (RemoveMessages) #068 {
删除内核里的消息结构。 #069 MsqDestroyMessage(Message); #070 } #071 goto MessageFound; #072 } #073
检查是否硬件的事件消息。 #074 /* Check for hardware events. */ #075 Present = co_MsqFindMessage(ThreadQueue, #076 TRUE, #077 RemoveMessages, #078 hWnd, #079 MsgFilterMin, #080 MsgFilterMax, #081 &Message); #082 if (Present) #083 { #084 RtlCopyMemory(Msg,sizeof(USER_MESSAGE)); #085 if (RemoveMessages) #086 { #087 MsqDestroyMessage(Message); #088 } #089 goto MessageFound; #090 } #091
重复分发消息。 #092 /* Check for sent messages again. */ #093 while (co_MsqDispatchOneSentMessage(ThreadQueue)) #094 ; #095
检查是否窗口绘制的消息。 #096 /* Check for paint messages. */ #097 if (IntGetPaintMessage(hWnd,MsgFilterMin,MsgFilterMax,pti,&Msg->Msg,RemoveMessages)) #098 { #099 Msg->FreeLParam = FALSE; #100 goto MsgExit; #101 } #102
定时器消息,再回去检查消息。 #103 if (ThreadQueue->WakeMask & QS_TIMER) #104 if (PostTimerMessages(hWnd)) // If there are timers ready, #105 goto CheckMessages; // go back and process them. #106
检查系统定时器消息是否出现。 #107 // LOL! Polling Timer Queue? How much time is spent doing this? #108 /* Check for WM_(SYS)TIMER messages */ #109 Present = MsqGetTimerMessage(ThreadQueue,hWnd, #110 &Msg->Msg,RemoveMessages); #111 if (Present) #112 { #113 Msg->FreeLParam = FALSE; #114 goto MessageFound; #115 } #116
如果有消息出现,就进入下面处理。 #117 if(Present) #118 { #119 MessageFound: #120
如果要删除消息,就进入处理。 #121 if(RemoveMessages) #122 { #123 PWINDOW_OBJECT MsgWindow = NULL; #124
获取消息的窗口。 #125 if(Msg->Msg.hwnd && (MsgWindow = UserGetWindowObject(Msg->Msg.hwnd)) && #126 Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST) #127 { #128 USHORT HitTest; #129 #130 UserRefObjectCo(MsgWindow,&Ref); #131
转换鼠标的消息。 #132 if(co_IntTranslateMouseMessage(ThreadQueue,&HitTest,TRUE)) #133 /* FIXME - check message filter again,if the message doesn't match anymore, #134 search again */ #135 { #136 UserDerefObjectCo(MsgWindow); #137 /* eat the message,search again */ #138 goto CheckMessages; #139 } #140
如果接收消息的队列窗口为空,就发送到当前活动的窗口。 #141 if(ThreadQueue->CaptureWindow == NULL) #142 { #143 co_IntSendHitTestMessages(ThreadQueue,&Msg->Msg); #144 if((Msg->Msg.message != WM_MOUSEMOVE && Msg->Msg.message != WM_NCMOUSEMOVE) && #145 IS_BTN_MESSAGE(Msg->Msg.message,DOWN) && #146 co_IntActivateWindowMouse(ThreadQueue,MsgWindow,&HitTest)) #147 { #148 UserDerefObjectCo(MsgWindow); #149 /* eat the message,search again */ #150 goto CheckMessages; #151 } #152 } #153 #154 UserDerefObjectCo(MsgWindow); #155 } #156 else #157 { #158 co_IntSendHitTestMessages(ThreadQueue,&Msg->Msg); #159 } #160 #161 // if(MsgWindow) #162 // { #163 // UserDereferenceObject(MsgWindow); #164 // } #165 #166 goto MsgExit; #167 } #168 #169 if((Msg->Msg.hwnd && Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST) && #170 co_IntTranslateMouseMessage(ThreadQueue,FALSE)) #171 /* FIXME - check message filter again, #172 search again */ #173 { #174 /* eat the message,search again */ #175 goto CheckMessages; #176 }
下面开始处理鼠标消息的功能函数。 #177 MsgExit: #178 if ( ISITHOOKED(WH_MOUSE) && #179 Msg->Msg.message >= WM_MOUSEFIRST && #180 Msg->Msg.message <= WM_MOUSELAST ) #181 { #182 MHook.pt = Msg->Msg.pt; #183 MHook.hwnd = Msg->Msg.hwnd; #184 MHook.wHitTestCode = HitTest; #185 MHook.dwExtraInfo = 0; #186 if (co_HOOK_CallHooks( WH_MOUSE, #187 RemoveMsg ? HC_ACTION : HC_NOREMOVE, #188 Msg->Msg.message, #189 (LPARAM)&MHook )) #190 { #191 if (ISITHOOKED(WH_CBT)) #192 { #193 MHook.pt = Msg->Msg.pt; #194 MHook.hwnd = Msg->Msg.hwnd; #195 MHook.wHitTestCode = HitTest; #196 MHook.dwExtraInfo = 0; #197 co_HOOK_CallHooks( WH_CBT,HCBT_CLICKSKIPPED, #198 Msg->Msg.message,(LPARAM)&MHook); #199 } #200 return FALSE; #201 } #202 }
键盘的消息过滤功能函数。 #203 if ( ISITHOOKED(WH_KEYBOARD) && #204 (Msg->Msg.message == WM_KEYDOWN || Msg->Msg.message == WM_KEYUP) ) #205 { #206 if (co_HOOK_CallHooks( WH_KEYBOARD, #207 RemoveMsg ? HC_ACTION : HC_NOREMOVE, #208 LOWORD(Msg->Msg.wParam), #209 Msg->Msg.lParam)) #210 { #211 if (ISITHOOKED(WH_CBT)) #212 { #213 /* skip this message */ #214 co_HOOK_CallHooks( WH_CBT,HCBT_KEYSKIPPED, #215 LOWORD(Msg->Msg.wParam),Msg->Msg.lParam ); #216 } #217 return FALSE; #218 } #219 } #220 // The WH_GETMESSAGE hook enables an application to monitor messages about to #221 // be returned by the GetMessage or PeekMessage function. #222 if (ISITHOOKED(WH_GETMESSAGE)) #223 { #224 //DPRINT1("Peek WH_GETMESSAGE -> %x/n",&Msg); #225 co_HOOK_CallHooks( WH_GETMESSAGE,HC_ACTION,RemoveMsg & PM_REMOVE,(LPARAM)&Msg->Msg); #226 } #227 return TRUE; #228 } #229 #230 return Present; #231} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |