加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactos操作系统实现(170)

发布时间:2020-12-15 04:58:51 所属栏目:百科 来源:网络整理
导读: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;

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}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读