Win32消息检索

来源:互联网 发布:数据图表ppt 编辑:程序博客网 时间:2024/05/21 19:37

Win32模式下,消息传递的主要函数有:PostMessageSendMessageGetMessagePeekMessageWaitMessage。其中PostMessageSendMessage是消息的投递和发送函数,而GetMessagePeekMessageWaitMessage是消息的接收函数。在VC中进行Win32编程时,要经常遇到到一段代码如下:

     // 主消息循环

     while (GetMessage(&msg, NULL, 0, 0))

     {

         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

         {

              TranslateMessage(&msg);

              DispatchMessage(&msg);

         }

     }

示意代码段1

VC中称之为主消息循环,它的工作模式为:利用while循环,GetMessage按照时间次序,不断地从进程消息队列中读取消息,读取的方式是从消息队列的指定消息中拷贝数据到传入的msg消息变量中,完成第一步。如果进程消息队列为空,则GetMessage一直处于等待状态,直到有消息到来后,GetMessage才会返回,返回值为非零值。如果GetMessage接到的消息为WM_QUIT,则函数返回零值,如果函数返回零值,则while循环就会结束,进而应用程序也会终结。

根据代码流程,被GetMessage所取得msg消息变量被传入到函数TranslateAccelerator中,而TranslateAcclerator要判断消息是否为菜单命令消息或者加速键消息(什么叫做加速键消息?用过Word的朋友都知道,当你选中文档中的一段文字后,选择菜单编辑—>复制,跟同时按下CTRLC键,所起作用是一样的,所以称Ctrl + C就是复制的加速键,也叫快捷键)。

如果判断是,则该函数将把WM_KEYDOWN或者WM_SYSKEYDOWN转换成一个WM_COMMAND消息,根据msg.hWnd的参数值,将其发送给指定窗口的事件发布函数,直到窗口事件发布函数处理完该WM_COMMAND消息之后,TranslateAccelerator才返回。处理了加速键之后,系统继续while循环,执行新的一轮GetMessage

如果判断不是,则执行TranslateMessage函数,该函数将虚拟键消息转换为字符消息,字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessagePeekMessage时被读出(TranslateMessage 只能用于转换该while循环所接收的消息)。经过TranslateMessage处理之后(其实消息并没有发生变化),消息还要经过DispatchMessage的处理,该函数把消息发送给窗口的WndProc()函数。而所谓的窗口的WndProc函数就是事件发布函数,如示意代码段2所示。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

         int wmId, wmEvent;

         PAINTSTRUCT ps;

         HDC hdc;

 

         switch (message)

         {

         case WM_COMMAND:  // 命令消息

             wmId    = LOWORD(wParam);  wmEvent = HIWORD(wParam);

             // 解析具体命令

             switch (wmId)

             {

             case IDM_ABOUT: // 打开关于对话框

                  DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

                  break;

             case IDM_EXIT:  // 发出退出命令

                  DestroyWindow(hWnd);

                  break;

             default:

                  return DefWindowProc(hWnd, message, wParam, lParam);

             }

             break;

 

         case WM_PAINT:  // 窗口消息

             hdc = BeginPaint(hWnd, &ps);

             // TODO: Add any drawing code here...

             EndPaint(hWnd, &ps);

             break;

         case WM_DESTROY: // 通知消息(也包含了窗口消息成分)

             PostQuitMessage(0);

             break;

         default:

             return DefWindowProc(hWnd, message, wParam, lParam);

         }

         return 0;

}

 示意代码段2

 

 

 

GetMessage函数的工作状态还跟其参数有关,该函数用来获取与hWnd参数所指定的窗口相关的且wMsgFilterMinwMsgFilterMax参数所限范围内的消息。如果hWnd为空,则GetMessage获取所属进程内的消息,如果wMsgFilterMinwMsgFilterMax都是0(按照字面意思就是不经过消息过滤),则GetMessage可获取进程内所有的消息。例如在示意代码段2中,GetMessage就是为获取整个进程内所有的消息的。GetMessage函数获取消息之后,将会使该消息被消息队列所删除(WM_PAINT消息除外,至于WM_PAINT则只有在其被合并处理之后才被删除)。GetMessage只检索呼叫进程的消息,不检索属于其它进程的消息。

原创粉丝点击