发送WM_QUIT消息可以让Window程序关闭,但经测试用下面程序却无法达到目的:
CWnd *pWnd = CWnd::FindWindow(NULL, “My Window”);
HWND hWnd = pWnd->GetSafeHwnd();
SendMessage(hWnd, WM_QUIT, 0, 0);
而经过尝试,发现用PostMessage却可以:
PostMessage(hWnd, WM_QUIT, 0, 0);
不知道原因,当然要查MSDN了,看一下MSDN的介绍:
TheSendMessagefunction sends the specified message to a window or windows. It calls the window procedure for the specified window and does not return until the window procedure has processed the message.
ThePostMessagefunction places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.
从MSDN的解释上看,感觉SendMessage比PostMessage更加安全,因为,SendMessage要等到窗体消息处理完才返回,而PostMessage发送消息后就立即返回,这更令人茫然。既然从这上面看不出SendMessage无法实现的原因,那么就从消息WM_QUIT上查。
TheWM_QUITmessage indicates a request to terminate an application and is generated when the application calls thePostQuitMessagefunction. It causes theGetMessagefunction to return zero.
当应用程序调用PostQuitMessage函数的时候, WM_QUIT消息终止一个程序的,它促使GetMessage函数返回0。
可这里根本就没提SendMessage无法完成终止程序的原因。但在Remark中,却有这样一句:
Do not post theWM_QUITmessage using thePostMessagefunction; usePostQuitMessage。至于为什么,就得看PostQuitMessage做什么事了。现在不讨论为什么不让使用PostMessage发送WM_QUIT消息,但就为什么SendMessage无法完成PostMessage能完成的功能来做一下研究。
注意到WM_QUIT消息让消息循环终止归根结底是让GetMessage返回为0,而GetMessage函数是从消息对列里取一条消息,然后再返回,只能当消息为WM_QUIT时才返回0结束消息循环。再仔细看一下SendMessage的注释发现,SendMessage直接发送到窗口,并调用窗口处理程序,完成消息响应,即SendMessage根本就没有将消息发到消息对列中,因此GetMessage无法从消息对列中收到WM_QUIT的消息。而PostMessage却直接发送消息到消息对列中,然后立即返回,这一点点的区别就解决了我们上面的问题。
了解了这一点,就不难理解上面注释中说的为什么不让直接使用PostMessage来发送WM_QUIT消息来终止程序了。
另外需要注意的是,发送消息让对话框关闭,应该发送WM_CLOSE消息,这样可以让对话框完成它自身的资源释放回收。
分享到:
相关推荐
本文对WM_CLOSE、WM_DESTROY、WM_QUIT及各种消息投递函数的功能及区别做出了分析比对,有助于读者更好的对消息投递函数加以理解。详情如下: 一、WM_CLOSE、WM_DESTROY、WM_QUIT区别 WM_CLOSE:关闭应用程序窗口 WM_...
通过响应WM_GETDLGCODE消息,应用程序可以把他当成一个特殊的输入控件并能处理它 WM_NCMOUSEMOVE = $00A0 //当光标在一个窗口的非客户区内移动时发送此消息给这个窗口//非客户区为:窗体的标题栏及窗 的边框体 WM...
除了键盘、鼠标消息以外,队列消息还有WM_PAINT、WM_TIMER和WM_QUIT。 这些队列消息以外的绝大多数消息是非队列消息。 系统消息和应用程序消息 从消息的来源来看,可以分为:系统定义的消息和应用程序定义...
atl 开发指南第四张Server和Client的例子,但是运行时,Client返回错误,Server端自动退出,受到WM_QUIT消息
当用户选择结束对话框或程序自己调用ExitWindows函数WM_QUIT = 18;用来结束程序运行或当程序调用postquitmessage函数WM_QUERYOPEN = 19;当用户窗口恢复以前的大小位置时,把此消息发送给某个图标WM_ERASEBKGND = 20;...
Post WM_QUIT 时,应使用 PostQuitMessage 代替。 4、系统只整编(marshal)系统消息(0 到 WM_USER 之间的消息),发送用户消息(WM_USER 以上)到别的进程时,需要自己做整编。 用 PostMessage、...
if(msg.message==WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg) }else{ if(AppPaused) WaitMessage(); else{ // 这里进行任何不基于消息循环的处理 // 例如动画制作 } } } ...
if(msg.message == WM_QUIT) { break; } TranslateMessage(&msg); DispatchMessage(&msg); } 在这段代码下方增加如下的代码: // 画点测试 { HDC hdc = ::GetDC(g_hwnd); // 获得设备句柄 ...
如果msg.message等于WM_QUIT,返回0,否则返回非0 { TranslateMessage(&msg);//将msg返回给windows已进行某些键盘消息的转换 DispatchMessage(&msg);//将msg再次返回给windows }*/ return msg.wParam;//msg....
WM_QUIT,则GetMessage函数返回FALSE,整 WndProc 注册: 程序设计中有许许多多的结构体。其中 是用于注册窗口类的。 窗口类型 窗口处理函数 窗口扩展 窗口实例扩展 实例句柄 窗口的最小化图标 窗口鼠标...
自保护 <br>主要是在ring3模式下HOOK了NtOpenThread,NtOpenProcess,NtTerminateThread,NtTerminateProcess,还有 子类了 WM_CLOSE,WM_QUIT 消息.可防止被一些菜鸟所写的恶意程序Kill掉.但对于ring0无效.. ...
NULL))) // Dont Pass Anything To WM_CREATE { KillGLWindow(); // Reset The Display MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; // Return FALSE } ...
// 等待若干时间 Sleep(MAX_QUIT_TIME); } } 当然以上介绍的只是一种较为简单的方法,仅在于描述这种原理。 <br> (三) 实现自动朗读英文 实现自动朗读实际上是响应剪贴板消息的过程,当...
Quit Or Use Windowed Mode. if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) { ...
这个函数很特殊,它本身是个消息响应函数,当我们点击ID为ID_FILE_NEW的菜单时,会产生一个命令消息,由于命令消息可以被CCmdTarget类及其派生类来捕获,而CWinApp是从CCmdTarget派生出来的,因此可以捕获这个消息。...
例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的高字中(HIWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。 2、谁将收到...
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; ...
#include <windows.h> #include <list> #include <cstdio> #include <ctime> using namespace std; class CMap { public: CMap();...m_bmpOfFood[3]= (HBITMAP)LoadImage(NULL, foodBmp[3...
= WM_QUIT) { if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } // Render a single frame DoFrame(); } } // Call shutdown DoShutdown(); // ...