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, Message, 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, MsgFilterMin, MsgFilterMax,

#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, &Msg->Msg, &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, &Msg->Msg, 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, &Msg->Msg, &HitTest, FALSE))

#171           /* FIXME - check message filter again, if the message doesn't match anymore,

#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  }

 

你可能感兴趣的:(reactos操作系统实现(170))