user-0 提问: 关闭窗口后，创建该窗口的进程为什么会一直收到0（WM_NULL）?

回复:
user: user-1
content: 线程不调用界面函数是不会建立消息队列的 消息发给线程进入线程的消息队列，消息循环将消息取出并分发给相应的窗口处理函数 如你所说，线程需要这个定时器消息干啥 还有窗口的也是可以接收并处理自己的定时器消息的

user: user-0
content: 引用 14 楼 Intel0011 的回复:GetMessage确实收到了0x113消息，具体不知干嘛用的，对界面编程不熟悉，其实Windows有很多内部处理，不同版本的Windows内部也有区别，虽然表面看上去没变化 我觉得应该没吧，我既然指定窗口句柄它就没有，指定NULL它就有，应该是0x113消息不是发给窗口h的，所以GetMessage只接收窗口h的消息时没有0x113，如果0x113是发给线程的就说得通了，而且GetMessage指定NULL时是可以接收发给本线程的所有消息，能接收到0x113也是情理之中，您对这个推论怎么看？  （其实我还试过不创建窗口就捕获消息，结果没有消息，更没有0x113，所以这个0x113是有窗口的线程才有的？）

user: user-1
content: GetMessage确实收到了0x113消息，具体不知干嘛用的，对界面编程不熟悉，其实Windows有很多内部处理，不同版本的Windows内部也有区别，虽然表面看上去没变化

user: user-1
content: 引用 2 楼 六道佩恩 的回复:[quote=引用 1 楼 user-2 的回复:] GetMessage 有这样的说明 If the function retrieves the WM_QUIT message, the return value is zero. 你误会了，我还分不清返回值和消息？ 你看看代码：  	while( GetMessage(&msg, h, 0, 0) ) 	{ 		printf("收到消息%d\n", msg.message); 		DispatchMessage ( &msg ); 	}  当关闭窗口后，会不断收到消息0，返回值0的话早跳出循环了[/quote] 关闭窗口后一般的处理是结束消息循环、进程退出，难道你没有结束循环，还是创建了多个窗口，将你的完整代码贴出来看看 还有这等怪事

user: user-0
content: 引用 12 楼 Intel0011 的回复:1、改为NULL表示接收这个线程创建的所有窗口的消息，见MSDN，是的，一个线程可以创建多个窗口 2、系统在创建窗口的过程中会向窗口发送很多消息来完成创建的动作，没关闭窗口的时候却反而一直收到0x113号定时器消息可能就是其中之一，至于是干啥没关注 3、如果消息循环中无法收到WM_CLOSE，那肯定是非队列消息，直接发给窗口过程处理，没有经过消息循环 我测试了下，窗口过程中没有捕获到这个0x113消息，也只有在GetMessage指定为句柄为NULL时才会在消息循环中不断收到这个消息，所以这个消息是发给线程而不是窗口的吗？（其实指定句柄为h时没有收到此消息应该也可以推出这一点吧）

user: user-1
content: 引用 11 楼 六道佩恩 的回复:[quote=引用 9 楼 Intel0011 的回复:] while( GetMessage(&msg, h, 0, 0) ) ---> 这个也有问题  改为 while( GetMessage(&msg, NULL, 0, 0) ) 理论上改为NULL的话，关闭窗口应该会阻塞吧？关闭窗口的确没再收到消息了，但没关闭窗口的时候却反而一直收到0x113号定时器消息，可我没设置定时器呀。 还有个问题就是，我在消息循环中竟然无法收到WM_CLOSE，窗口过程却能收到，难道WM_CLOSE是非队列消息吗？[/quote] 1、改为NULL表示接收这个线程创建的所有窗口的消息，见MSDN，是的，一个线程可以创建多个窗口 2、系统在创建窗口的过程中会向窗口发送很多消息来完成创建的动作，没关闭窗口的时候却反而一直收到0x113号定时器消息可能就是其中之一，至于是干啥没关注 3、如果消息循环中无法收到WM_CLOSE，那肯定是非队列消息，直接发给窗口过程处理，没有经过消息循环

user: user-0
content: 引用 9 楼 Intel0011 的回复:while( GetMessage(&msg, h, 0, 0) ) ---> 这个也有问题  改为 while( GetMessage(&msg, NULL, 0, 0) ) 理论上改为NULL的话，关闭窗口应该会阻塞吧？关闭窗口的确没再收到消息了，但没关闭窗口的时候却反而一直收到0x113号定时器消息，可我没设置定时器呀。 还有个问题就是，我在消息循环中竟然无法收到WM_CLOSE，窗口过程却能收到，难道WM_CLOSE是非队列消息吗？

user: user-1
content: 更正一下： 系统默认的DefWindowProc窗口处理函数是不会帮你处理WM_QUIT消息的 改为 DefWindowProc不处理WM_DESTROY消息 因为 窗口处理函数根本收不到WM_QUIT消息

user: user-1
content: while( GetMessage(&msg, h, 0, 0) ) ---> 这个也有问题  改为 while( GetMessage(&msg, NULL, 0, 0) )

user: user-1
content: 不过理论上关闭窗口的话，不是会转换成WM_QIUT消息而结束消息循环吗？ ---> 这句话是有问题的  系统默认的DefWindowProc窗口处理函数是不会帮你处理WM_QUIT消息的 所以要写成 LRESULT MyProc( HWND h, UINT msg, WPARAM wParam, LPARAM lParam) {     switch (msg)    {       case WM_DESTROY:          PostQuitMessage(0);          return 0;    }     return DefWindowProc( h, msg, wParam, lParam); }  另外 while( GetMessage(&msg, h, 0, 0) ) ---> 这个也有问题 改为 while( GetMessage(&msg, NULL, 0, 0) ) 关闭窗口后，句柄h变为无效，while( GetMessage(&msg, h, 0, 0) ) 死循环，此时消息队列中没什么有用的消息可以取得

user: user-0
content: 引用 3 楼 user-2 的回复:If the function retrieves a message other than WM_QUIT, the return value is nonzero.  If the function retrieves the WM_QUIT message, the return value is zero.   If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle or lpMsg is an invalid pointer. To get extended error information, call GetLastError.  Warning   Because the return value can be nonzero, zero, or -1, avoid code like this:  while (GetMessage( lpMsg, hWnd, 0, 0)) ... The possibility of a -1 return value means that such code can lead to fatal application errors. Instead, use code like this:  Hide Example  BOOL bRet;  while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0) {      if (bRet == -1)     {         // handle the error and possibly exit     }     else     {         TranslateMessage(&msg);          DispatchMessage(&msg);      } } 抱歉抱歉，的确是返回值的问题，我之前一直没考虑到这点，以为是一直在发送WM_NULL。不过理论上关闭窗口的话，不是会转换成WM_QIUT消息而结束消息循环吗？

user: user-0
content: 引用 5 楼 Intel0011 的回复:关闭窗口后一般的处理是结束消息循环、进程退出，难道你没有结束循环，还是创建了多个窗口，将你的完整代码贴出来看看 还有这等怪事  #include "stdio.h" #include "windows.h" LRESULT MyProc( HWND h, UINT msg, WPARAM wParam, LPARAM lParam) { 	return DefWindowProc( h, msg, wParam, lParam); } int main( void ) { 	WNDCLASS MyClass; 	MyClass.style 			=0;			 	MyClass.lpfnWndProc	=MyProc;	 	MyClass.cbClsExtra		=0;		 	MyClass.cbWndExtra	=0;	 	MyClass.hInstance		=NULL;		 	MyClass.hIcon			=NULL;			 	MyClass.hCursor		=NULL;		 	MyClass.hbrBackground	=NULL;	 	MyClass.lpszMenuName	=NULL;	 	MyClass.lpszClassName	="MyClass";	 	RegisterClass( &MyClass ); 	 	MSG msg; 	HWND h = CreateWindow( "MyClass", "新窗口", WS_OVERLAPPEDWINDOW,  							0, 0, 200, 200, NULL, NULL, NULL, NULL); 	ShowWindow(h, SW_SHOW);				 	UpdateWindow(h);					 	while( GetMessage(&msg, h, 0, 0) ) 	{ 		printf("收到消息%d\n", msg.message); 		DispatchMessage ( &msg ); 	} 	return 0; }

user: user-0
content: 引用 3 楼 user-2 的回复:If the function retrieves a message other than WM_QUIT, the return value is nonzero.  If the function retrieves the WM_QUIT message, the return value is zero.   If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle or lpMsg is an invalid pointer. To get extended error information, call GetLastError.  Warning   Because the return value can be nonzero, zero, or -1, avoid code like this:  while (GetMessage( lpMsg, hWnd, 0, 0)) ... The possibility of a -1 return value means that such code can lead to fatal application errors. Instead, use code like this:  Hide Example  BOOL bRet;  while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0) {      if (bRet == -1)     {         // handle the error and possibly exit     }     else     {         TranslateMessage(&msg);          DispatchMessage(&msg);      } } 无语，您能好好看看问题吗？我输出的是获取的消息值？为啥你老是谈GetMessage的返回值？

user: user-2
content: If the function retrieves a message other than WM_QUIT, the return value is nonzero.  If the function retrieves the WM_QUIT message, the return value is zero.   If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle or lpMsg is an invalid pointer. To get extended error information, call GetLastError.  Warning   Because the return value can be nonzero, zero, or -1, avoid code like this:  while (GetMessage( lpMsg, hWnd, 0, 0)) ... The possibility of a -1 return value means that such code can lead to fatal application errors. Instead, use code like this:  Hide Example  BOOL bRet;  while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0) {      if (bRet == -1)     {         // handle the error and possibly exit     }     else     {         TranslateMessage(&msg);          DispatchMessage(&msg);      } }

user: user-0
content: 引用 1 楼 user-2 的回复:GetMessage 有这样的说明 If the function retrieves the WM_QUIT message, the return value is zero. 你误会了，我还分不清返回值和消息？ 你看看代码：  	while( GetMessage(&msg, h, 0, 0) ) 	{ 		printf("收到消息%d\n", msg.message); 		DispatchMessage ( &msg ); 	}  当关闭窗口后，会不断收到消息0，返回值0的话早跳出循环了

user: user-2
content: GetMessage 有这样的说明 If the function retrieves the WM_QUIT message, the return value is zero.