MFC消息_为什么发消息对方不回

MFC消息_为什么发消息对方不回由arain于星期二,11/02/2010-10:44发表MSGmessage;  if(::PeekMessage(&message,NULL,0,0,PM_REMOVE)){      ::TranslateMessage(&message); //把键盘消息翻译成字符消息      ::DispatchMessage(&message

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

MSG message ;  

if (::PeekMessage(&message ,NULL , 0, 0 ,PM_REMOVE))

{

       ::TranslateMessage(&message);  //把键盘消息翻译成字符消息

      ::DispatchMessage(&message);  //通过窗口类把控制交给MFC消息处理器

}

PeekMessage (&msg, NULL, 0, 0, PM_REMOVE) ;

前面的四个参数(一个指向MSG结构的指针、一个窗口句柄、两个值指示消息范围)与GetMessage的参数相同。将第二、三、四个参数设定为NULL或0时,表明我们想让PeekMessage传回程序中所有窗口的所有消息。如果要将消息从消息队列中删除,则将PeekMessage的最后一个参数设定为PM_REMOVE。如果您不希望删除消息,那么您可以将这个参数设定为PM_NOREMOVE。它使得程序可以检查程序的队列中的下一个消息,而不实际删除它。

GetMessage不将控制传回给程序,直到从程序的消息队列中取得消息,但是PeekMessage总是立刻传回,而不论一个消息是否出现。当消息队列中有一个消息时,PeekMessage的传回值为TRUE(非0),并且将按通常方式处理消息。当队列中没有消息时,PeekMessage传回FALSE(0)。

这使得我们可以改写普通的消息循环。我们可以将如下所示的循环:

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

{       

    TranslateMessage (&msg) ;       

    DispatchMessage (&msg) ;       

}       

return msg.wParam ;

替换为下面的循环:

while (TRUE)       

{       

    if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))       

    {       

            if (msg.message == WM_QUIT)       

                   break ;       

            TranslateMessage (&msg) ;        

            DispatchMessage (&msg) ;       

    }       

    else       

    {       

            // 完成某些工作的其它行程序       

    }       

}       

return msg.wParam ;

注意,WM_QUIT消息被另外挑出来检查。在普通的消息循环中您不必这么作,因为如果GetMessage接收到一个WM_QUIT消息,它将传回0,但是PeekMessage用它的传回值来指示是否得到一个消息,所以需要对WM_QUIT进行检查。

如果PeekMessage的传回值为TRUE,则消息按通常方式进行处理。如果传回值为FALSE,则在将控制传回给Windows之前,还可以作一点工作(如显示另一个随机矩形)。

(尽管Windows文件上说,您不能用PeekMessage从消息队列中删除WM_PAINT消息,但是这并不是什么大不了的问题。毕竟,GetMessage并不从消息队列中删除WM_PAINT消息。从队列中删除WM_PAINT消息的唯一方法是令窗口显示区域的失效区域变得有效,这可以用ValidateRect和ValidateRgn或者BeginPaint和EndPaint对来完成。如果您在使用PeekMessage从队列中取出WM_PAINT消息后,同平常一样处理它,那么就不会有问题了。所不能作的是使用如下所示的程序代码来清除消息队列中的所有消息:

while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) ;

这行叙述从消息队列中删除WM_PAINT之外的所有消息。如果队列中有一个WM_PAINT消息,程序就会永远地陷在while循环中。)

另外补充:

peekMessage:

   函数功能:该函数为一个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构。
  
函数原型:BOOL PeekMessage(LPMSG IpMsg,HWND hWnd,UINT wMSGfilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);

参数:

lpMsg:接收消息信息的MSG结构指针。
  
  hWnd:其消息被检查的窗口的句柄。
  
  wMsgFilterMin:指定被检查的消息范围里的第一个消息。
  
  wMsgFilterMax:指定被检查的消息范围里的最后一个消息。
  
  wRemoveMsg:确定消息如何被处理。此参数可取下列值之一:
  
  PM_NOREMOVE:PeekMessage处理后,消息不从队列里除掉。
  
  PM_REMOVE:PeekMessage处理后,消息从队列里除掉。
  
  可将PM_NOYIELD随意组合到PM_NOREMOVE或PM_REMOVE。此标志使系统不释放等待调用程序空闲的线程。
  
  缺省地,处理所有类型的消息。若只处理某些消息,指定一个或多个下列值:
  
  PM_QS_INPUT:Windows NT5.0和Windows 98:处理鼠标和键盘消息。
  
  PM_QS_PAINT:Windows NT 5.0和Windows 98:处理画图消息。
  
  PM_QS_POSTMESSAGE:Windows NT 5.0和Windows 98:处理所有被寄送的消息,包括计时器和热键。
  
  PM_QS_SENDMESSAGE:Windows NT 5.0和Windows 98:处理所有发送消息。
  
  返回值:如果消息可得到,返回非零值;如果没有消息可得到,返回值是零。
  
  备注:和函数GetMessage不一样的是,函数PeekMesssge在返回前不等待消息被放到队列里。
PeekMesssge只得到那些与参数hWnd标识的窗口相联系的消息或被lsChild确定为其子窗口相联系的消息,并且该消息要在由参数wMsgFiterMin和wMsgFiherMax确定的范围内。如果hWnd为NULL,则PeekMessage接收属于当前调用线程的窗口的消息(PeekMessage不接收属于其他线程的窗口的消息)。如果hWnd为C1,PeekMessage只返回hWnd值为NULL的消息,该消息由函数PostThreadMessage寄送。如果wMsgFilterMin和wMsgFilterMax都为零,GetMessage返回所有可得的消息(即,无范围过滤)。
  
  常数WM_KEYFIRST和WMKEYLAST可作为过滤值取得所有键盘消息;常数WM_MOUSEFIRST和WM_MOUSELAST可用来接收所有的鼠标消息。
  
  PeekMessage通常不从队列里清除WM_PANT消息。该消息将保留在队列里直到处理完毕。但如果WM_PAINT消息有一个空更新区,PeekMessage将从队列里清除WM_PAINT消息。
  
  Windows CE:有一个NULL更新区的WM_PAINT消息不从队列里清除。

 

TranslateMessage函数

TranslateMessage是用来把虚拟键消息转换为字符消息。由于Windows对所有键盘编码都是采用虚拟键的定义,这样当按键按下时,并不得字符消息,需要键盘映射转换为字符的消息。
TranslateMessage函数用于将虚拟键消息转换为字符消息。字符消息被投递到调用线程的消息队列中,当下一次调用GetMessage函数时被取出。当我们敲击键盘上的某个字符键时,系统将产生WM_KEYDOWN和WM_KEYUP消息。这两个消息的附加参数(wParam和lParam)包含的是虚拟键代码和扫描码等信息,而我们在程序中往往需要得到某个字符的ASCII码,TranslateMessage这个函数就可以将WM_KEYDOWN和WM_ KEYUP消息的组合转换为一条WM_CHAR消息(该消息的wParam附加参数包含了字符的ASCII码),并将转换后的新消息投递到调用线程的消息队列中。注意,TranslateMessage函数并不会修改原有的消息,它只是产生新的消息并投递到消息队列中。
也就是说TranslateMessage会发现消息里是否有字符键的消息,如果有字符键的消息,就会产生WM_CHAR消息,如果没有就会产生什么消息。

函数TranslateMessage声明如下:
WINUSERAPI
BOOL
WINAPI
TranslateMessage(
__in CONST MSG *lpMsg);
lpMsg是检查需要转换的消息。

DispatchMessage函数

前面已经介绍从系统队列里获取一条消息,然后经过快捷键的函数检查,又通过字符消息函数的转换,最后要做的事情就是调用DispatchMessage函数,它的意思就是说要把这条消息发送到窗口里的消息处理函数WindowProc。

函数DispatchMessage声明如下:
WINUSERAPI
LRESULT
WINAPI
DispatchMessageA(
__in CONST MSG *lpMsg);
WINUSERAPI
LRESULT
WINAPI
DispatchMessageW(
__in CONST MSG *lpMsg);
#ifdef UNICODE
#define DispatchMessage DispatchMessageW
#else
#define DispatchMessage DispatchMessageA
#endif // !UNICODE

lpMsg是指向想向消息处理函数WindowProc发送的消息。

调用这个函数的例子如下:
#001 //主程序入口
#002 //
#003 // 蔡军生 2007/07/19
#004 // QQ: 9073204
#005 //
#006 int APIENTRY _tWinMain(HINSTANCE hInstance,
#007 HINSTANCE hPrevInstance,
#008 LPTSTR lpCmdLine,
#009 int nCmdShow)
#010 {

#011 UNREFERENCED_PARAMETER(hPrevInstance);
#012 UNREFERENCED_PARAMETER(lpCmdLine);
#013
#014 //
#015 MSG msg;
#016 HACCEL hAccelTable;
#017
#018 // 加载全局字符串。
#019 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
#020 LoadString(hInstance, IDC_TESTWIN, szWindowClass, MAX_LOADSTRING);
#021 MyRegisterClass(hInstance);
#022
#023 // 应用程序初始化:
#024 if (!InitInstance (hInstance, nCmdShow))
#025 {

#026 return FALSE;
#027 }
#028
#029 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTWIN));
#030
#031 // 消息循环:
#032 BOOL bRet;
#033 while ( (bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
#034 {

#035 if (bRet == -1)
#036 {

#037 //处理出错。
#038
#039 }
#040 else if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
#041 {

#042 TranslateMessage(&msg);
#043 DispatchMessage(&msg);
#044 }
#045 }
#046
#047 return (int) msg.wParam;
#048 }
#049

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/194485.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 混沌皇帝系统_时滞系统ppt

    混沌皇帝系统_时滞系统ppt时滞混沌系统时滞混沌系统即具有混沌运动的时滞系统。时滞系统是系统中一处或几处的信号传递有时间延迟的系统。所谓混沌是指具有以下特点的一类现象:由确定性产生;具有有界性;具有非周期性;初始条件具有极端敏感性。时滞系统在工程中.许多动力系统可由状态变量随时间演化的微分方程来描述。随着混沌研究的不断深入,研究人员发现相当一部分动力系统的状态变量之间存在时间滞后现象,即系统的演化趋势不仅与系统当前的状态相关,而且还与过去某一时刻或若干时刻的状态有关。于是将这类动力学系统通称为时滞动力学系统。时滞动力学系统已

  • flask中jsonify和json.dumps的区别「建议收藏」

    flask中jsonify和json.dumps的区别「建议收藏」flask提供了jsonify函数供用户处理返回的序列化json数据,而python自带的json库中也有dumps方法可以序列化json对象,那么在flask的视图函数中return它们会有什么不同之处呢?想必开始很多人和我一样搞不清楚,只知道既然框架提供了方法就用,肯定不会错。但作为开发人员,我们需要弄清楚开发过程中各种实现方式的特点和区别,这样在我们面对不同的需求时才能做出相对合理的选择,而…

  • Node.js实战:Express实现简单后台登录系统

    Node.js实战:Express实现简单后台登录系统1.建立Express项目在进行以下操作之前,请确保你的电脑已经装好Node.js和Express框架。首先打开命令行提示符,输入express–view=ejs-ewww其中–view=ejs表示使用ejs模版引擎,-e指定项目名称,此处设为www。回车之后,当前文件夹下会多出一个名为www的文件夹,这个就是我们项目所在的地方。此时,www文件夹中默认已经有了基本的文件,但是相关

  • Centos7:修改IP出现Job for network.service failed because the control process exited with error code问题

    Centos7:修改IP出现Job for network.service failed because the control process exited with error code问题centos7克隆之后,发现无ip。因为是克隆的,首先修改一些配置文件。vim /etc/sysconfig/network-scripts/ifcfg-xxxIPADDR=192.168.135.131GATEWAY=192.168.135.2NETMASK=255.255.255.0DNS1=192.168.135.2排查:1、查看mac地址是否冲突2…

  • Layui弹出层 加载 做编辑页面「建议收藏」

    Layui弹出层 加载 做编辑页面「建议收藏」先上效果图基本准备,引入layui的layui.css,layui.js文件<linkrel="stylesheet"href="../../../Publics/others/layui/css/layui.css"media="all"><scriptsrc="../../../Publics/others/layui/layui.js">&a

  • Java基础面试题50题

    1,””空字符串的作用packagecom.neuedu.nineteen;publicclassTest{publicstaticvoidmain(String[]args){Strings=””;for(chari=’a’;i<‘d’;i++){s=s+i;//输出…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号