none
win32编程的一个编程问题的GetMessage问题 RRS feed

  • 问题

  • #include <windows.h>
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
         static TCHAR szAppName[] = TEXT ("Typer") ;
         HWND         hwnd ;
         MSG          msg ;
         WNDCLASS     wndclass ;
         
         wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
         wndclass.lpfnWndProc   = WndProc ;
         wndclass.cbClsExtra    = 0 ;
         wndclass.cbWndExtra    = 0 ;
         wndclass.hInstance     = hInstance ;
         wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
         wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
         wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
         wndclass.lpszMenuName  = NULL ;
         wndclass.lpszClassName = szAppName ;
         
         if (!RegisterClass (&wndclass))
         {
              MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
                          szAppName, MB_ICONERROR) ;
              return 0 ;
         }
         
         hwnd = CreateWindow (szAppName, TEXT ("Typing Program"),
                              WS_OVERLAPPEDWINDOW,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              NULL, NULL, hInstance, NULL) ;
         
         ShowWindow (hwnd, iCmdShow) ;
         UpdateWindow (hwnd) ;
         
         while (GetMessage (&msg, NULL, 0, 0))
         {
              TranslateMessage (&msg) ;
              DispatchMessage (&msg) ;
         }
         return msg.wParam ;
    }
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    
         HDC            hdc ;
         PAINTSTRUCT    ps ;
         TEXTMETRIC     tm ;
         
         switch (message)
         {
    
         case WM_DESTROY:
              PostQuitMessage (0) ;
              return 0 ;
         }
         return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
    
    这是一个非常简单的win32的程序,我的问题是这句
         while (GetMessage (&msg, NULL, 0, 0))
         {
              TranslateMessage (&msg) ;
              DispatchMessage (&msg) ;
         }
    我将GetMessage (&msg, NULL, 0, 0)的第二个参数改为hwnd,发现一个很奇怪的现象,当关掉窗口的时候,程序并没有完全销毁关闭(在任务管理器内还可以看到)。为什么改为NULL 就可以了。
    MSDN上说hwnd指定了需要接受消息的窗口,我需要关闭的是【主窗口】,第二个参数改为hwnd按理来说也说得过去呀,为什么改了就不行了?小弟不才,求高手解答。
    2011年9月14日 15:10

答案

  • 注意,此函数的返回值可非零、零或-1,应避免如下代码出现:  while(GetMessage(IpMsg,hwnd,0,0))…

      -1返回值的可能性表示这样的代码会导致致命的应用程序错误。

    引自:http://baike.baidu.com/view/1013920.htm

     

    你看一下GetMessage的介绍应该就明白了

    • 已标记为答案 Rob Pan 2011年9月20日 9:14
    2011年9月15日 0:53
  • PostQuitMessage发出的WM_QUIT消息是专门特别处理的,它不联系着任何一个窗口,查看WM_QUIT消息的说明,MSDN文档里对它有一行特别说明的:

    The WM_QUIT message is not associated with a window and therefore will never be received through a window's window procedure. It is retrieved only by the GetMessage or PeekMessage functions.

    • 已标记为答案 Rob Pan 2011年9月20日 9:14
    2011年9月15日 3:20
  • 正确的msgloop方式:

    BOOL bRet;

    while( (bRet = GetMessage( &msg, NULL, 00 )) != 0)

        
    if (bRet == -1)
        {
            
    // handle the error and possibly exit
        }
        
    else
        {
            TranslateMessage(
    &msg); 
            DispatchMessage(
    &msg); 
        }
    }

     

    http://www.cnblogs.com/Greatest/archive/2009/08/25/1553623.html

    • 已标记为答案 Rob Pan 2011年9月20日 9:14
    2011年9月16日 8:28

全部回复

  • 注意,此函数的返回值可非零、零或-1,应避免如下代码出现:  while(GetMessage(IpMsg,hwnd,0,0))…

      -1返回值的可能性表示这样的代码会导致致命的应用程序错误。

    引自:http://baike.baidu.com/view/1013920.htm

     

    你看一下GetMessage的介绍应该就明白了

    • 已标记为答案 Rob Pan 2011年9月20日 9:14
    2011年9月15日 0:53
  • PostQuitMessage发出的WM_QUIT消息是专门特别处理的,它不联系着任何一个窗口,查看WM_QUIT消息的说明,MSDN文档里对它有一行特别说明的:

    The WM_QUIT message is not associated with a window and therefore will never be received through a window's window procedure. It is retrieved only by the GetMessage or PeekMessage functions.

    • 已标记为答案 Rob Pan 2011年9月20日 9:14
    2011年9月15日 3:20
  • 正确的msgloop方式:

    BOOL bRet;

    while( (bRet = GetMessage( &msg, NULL, 00 )) != 0)

        
    if (bRet == -1)
        {
            
    // handle the error and possibly exit
        }
        
    else
        {
            TranslateMessage(
    &msg); 
            DispatchMessage(
    &msg); 
        }
    }

     

    http://www.cnblogs.com/Greatest/archive/2009/08/25/1553623.html

    • 已标记为答案 Rob Pan 2011年9月20日 9:14
    2011年9月16日 8:28