当前位置:   article > 正文

微软MFC技术中的消息队列及消息处理(下)_mfc消息队列

mfc消息队列

 

我是荔园微风,作为一名在IT界整整25年的老兵,今天来聊聊微软MFC技术中的消息队列及消息处理。

MFC应用程序中由Windows 系统以消息的形式发送给应用程序的窗口。窗口接收和处理消息之后,把控制返回给Windows。Windows系统在同一时间可显示多个窗口。此系统利用消息队列来记录鼠标和键盘输入到相应窗口等消息。如果用户移动鼠标或敲一下键盘,鼠标或键盘的设备驱动器都会把此输入转换成消息,并把它们放到系统消息队列中去。Windows从系统队列中每次读取一条消息, 然后将其从队列中删除,之后处理它们发送到相应的窗口过程。

消息队列是一种先进先出的队列型数据结构,它实际上是系统内核中的一个内部链表。用户可以从消息队列中添加消息和读取消息,而消息则被顺序地插入到队列中。其中发送进程将消息添加到队列末尾,接收进程会从队列头读取消息。

今天我们接之前的《微软MFC技术中的消息队列及消息处理(上)》继续往下讲。

详解具体实例——消息的处理

首先用visual studio 2022新建一个工程名为Win32_message的Win32应用程序。工程建好后,新建一个源文件,命名为 Win32_message.cpp。此程序实现的功能是创建一个窗口,当按键盘上的按键时,会出现一个消息盒子,如“所按键的字符值是98”。如果按下Backspace键时,一旦消息发送成功,会出现有“发送后退消息成功”提示语句的消息盒子,否则,会出现“发送后退消息失败”等类似其他消息响应。我们来看看下面的代码,先看此程序的入口函数WinMain()。

Win32应用程序入口函数示例:Win32_message.cpp

  1. //Win32应用程序入口函数WinMain()
  2. int WINAPI WinMain(
  3.   HINSTANCE hInstance, //指向当前实例的句柄
  4.   HINSTANCE hPrevInstance, //指向先前实例的句柄
  5.   LPSTR lpCmdLine, //命令行
  6.   int nCmdShow   //显示状态
  7. )
  8. {
  9.   WNDCLASS wndclass; //创建一个窗口类 
  10.   wndclass. cbClsExtra=0; //窗口类无扩展
  11.   wndclass. cbWndExtra=0;   //窗口实例无扩展
  12.   wndclass. hbrBackground=(HBRUSH)GetStockObject (BLACK_BRUSH);  //窗口背景为黑
  13.   wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); //窗口采用箭头光标
  14. wndclass. hIcon=LoadIcon(NULL, IDI_APPLICATION);  //窗口的最小化图标为缺省
  15.   wndclass. hInstance=hInstance:  //当前实例句柄
  16.   wndclass. lpfnWndProc=WinHouProc //定义窗口处理函数
  17.   wndclass.lpszClassName="VC++"; //窗口类为“VC++”
  18.   wndclass.lpszMenuName=NULL; //窗口无菜单
  19.   wndclass.style=CS_HREDRAW|CS_PARENTDC; //设置窗口类型
  20.   RegisterClass(&wndclass);   //注册窗口类
  21.   HWND hwnd;
  22.   hwnd=CreateWindow("VC++","消息机制",WS_OVERLAPPEDWINDOW,0,0, 600, 400, NULL, NULL, hInstance, NULL);   //创建窗口
  23.   ShowWindow(hwnd, SW_SHOWNORMAL);   //显示窗口
  24.   UpdateWindow(hwnd);   //更新窗口
  25.   MSG msg;
  26.   while(GetMessage 6msg, NULL,0,0))   //获取消息
  27.   {
  28.   TranslateMessage (&msg);
  29.    DispatchMessage (&msg);
  30. }
  31.   return 0;
  32. }

从代码可以大致看出此程序的运行机制。要想显示一个窗口并执行各种命令,应先创建一个窗口。第9行对应创建窗口类这一步,而第16行表明将函数 WinHouProc()赋给此窗口的消息响应函数。第20行对应注册窗口类,这样一个窗口类已形成。接下来第23行就要定义一个窗口的大小、位置、窗口显示名字等信息。窗口也创建好之后,第26~27行就要显示窗口并实时更新此窗口的状态。最后第30行就是要处理关联此窗口的各种消息,判断当前是否得到消息,并形成循环。

讨论完入口函数,就要介绍此窗口的消息响应函数,代码为下面所示的消息响应函数WinHouProc()。

Win32应用程序消息响应函数示例:Win32_message.cpp

  1. LRESULT CALLBACK WinHouProc(
  2.   HWND hwnd, //窗口句柄
  3.   UINT uMsg, //消息标识符
  4.   WPARAM WParam, //第一个消息参数
  5.   LPARAM lParam //第二个消息参数
  6. {
  7.   switch(uMsg)
  8.   {
  9.   case WM_CHAR:
  10.   switch(wParam) //显示所按键值
  11.     {
  12.   case 0x08:   //后退键
  13.   if(PostMessage (hwnd, WM_KEYDOWN, VK_DELETE, 1L))
  14.   MessageBox(hwnd,"发送后退消息成功""VC++"0);
  15. else
  16. MessageBox(hwnd,"发送后退消息失败""VC++"0);
  17. break;
  18.   default:
  19.   break;
  20. }
  21.     char szChar[20];
  22.     sprintf(szChar,"所按字符值是%d",wParam);   //转换按键值类型
  23.     MessageBox(hwnd, szChar, "VC++", 0);    //显示按键的值
  24.    break;
  25. case WM_CLOSE:   //有提示消息的关闭窗口
  26.   if(IDYES=MessageBox(hwnd,"是否结束?""VC++",MB_YESNO) //判断
  27.   DestroyWindow(hwnd); //銷毀窗口
  28.   break;
  29.   case WM_DESTROY: //强制关闭
  30.     PostQuitMessage(0);   //发送关闭消息
  31.     break;
  32.   default:
  33.     return DefWindowProc(hwnd,uMsg,wParam,lParam); //返回窗口过程
  34. }
  35.   return 0;
  36. }

代码说明了3种功能:显示按键值、有提示消息的关闭、强制关闭。第14行是PostMessage()函数的应用,如果后退消息发送成功,就提示“发送后退消息成功”。第31行 PostQuitMessage()是 PostMessage()传递关闭消息的一种简单形式。

但是要注意的是,如果是在比VC++6.0和VS2003高级的版本上运行以上所编的程序时,就是立刻报一大堆错,应修改一下工程的编码选项:项目属性——常规——字符集——使用多字节字符集。否认显示文字部分会出现乱码。因为VC++6.0与VS2003默认使用ANSI编码,而VS2022及以上版本默认采用 Unicode。

作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/495207
推荐阅读
相关标签
  

闽ICP备14008679号