现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

程序关闭过程的函数响应顺序详解

2012-09-05 10:32 工业·编程 ⁄ 共 4130字 ⁄ 字号 暂无评论

    用户单击关闭按钮(标题栏最右边)或者用鼠标或键盘选择系统菜单的“关闭”选项,直到窗口消失,应用程序结束。这期间到底发生了什么呢?这曾经是我百思不得其解的问题,我想也会有很多人和我一样会碰到这个问题。所以我要把我的一些学习心得写出来,与大家共享。

     1、首先会产生一个WM_SYSCOMMAND消息,如果程序员没有对此消息进行拦截,则由缺省的窗口函数DefWindowProc进行处理,如果表达式(LOWORD(wParam)&0xFFF0)==SC_CLOSE 成立,DefWindowProc发出一个WM_CLOSE消息。

    2、同样,如果程序员没有对WM_CLOSE消息进行拦截,则还是由DefWindowProc进行处理,这次,她只简单的调用DestroyWindow函数,DestroyWindow先把窗口破坏掉,使用户看不到窗口。但是窗口破坏后,应用程序并没有结束,于是DestroyWindow再接再励,送出了一个WM_DESTROY消息。

     3、这一次,WM_DESTROY被载获了,通常是会有这样的句子: case WM_DESTROY: PostQuitMessage(0); ... 这里PostQuitMessage函数很简单的发送一个WM_QUIT消息来响应WM_DESTROY 4、WM_QUIT消息非常特殊,她使GetMessage函数返回0,从而结束了消息循环, 应用程序从此结束。

下面我给出完整的证明程序,请大家一试

#include   <Windows.h>    
  #include   <TCHAR.h>    
  LRESULT   CALLBACK   WndProc(HWND,UINT,WPARAM,LPARAM);    
          int   WINAPI   WinMain(HINSTANCE   hInstance,    
                                        HINSTANCE   hPrevInst,    
                                        LPSTR           lpszCmdLine,    
                                        int                 nCmdShow)    
  {    
          HWND   hwnd;    
          MSG   Msg;    
          WNDCLASS   wndclass;    
          char   lpszClassName[]="窗口";    
          char   lpszTitle[]="窗口示例";    
          wndclass.style=CS_HREDRAW   |   CS_VREDRAW;    
          wndclass.lpfnWndProc   =WndProc;    
          wndclass.cbWndExtra=0;    
          wndclass.cbClsExtra   =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=lpszClassName;    
          if(!RegisterClass(&wndclass))    
          {    
                  MessageBeep(0);    
                  return   FALSE;    
          }    
          hwnd=CreateWindow(lpszClassName,    
                                      lpszTitle,    
                                      WS_OVERLAPPEDWINDOW,    
                                              CW_USEDEFAULT,    
                                      CW_USEDEFAULT,    
                                                      CW_USEDEFAULT,    
                                                      CW_USEDEFAULT,    
                              NULL,    
                              NULL,    
                              hInstance,    
                              NULL);    
          ShowWindow(hwnd,nCmdShow);    
          UpdateWindow(hwnd);    
          while(1)    
          {    
                  GetMessage(&Msg,NULL,0,0);    
                  if(Msg.message==WM_QUIT)    
                  {    
                          MessageBox(NULL,_T("收到WM_QUIT,即将跳出消息循环"),_T("注意了"),MB_OK);    
                          break;    
                  }    
                  TranslateMessage(&Msg);    
                  DispatchMessage(&Msg);    
          }    
                  MessageBox(NULL,_T("已经跳出消息循环,应用程序即将结束!"),_T("注意了"),MB_OK);    
          return   Msg.wParam;    
  }    
  LRESULT   CALLBACK   WndProc(    
                                                    HWND   hwnd,    
                                                    UINT   message,    
                                                    WPARAM   wParam,    
                                                    LPARAM   lParam)    
  {      
          switch(message)    
          {    
  case   WM_CLOSE:    
            MessageBox(NULL,_T("收到WM_CLOSE消息,即将调用   DestroyWindow(hwnd);"),_T("注意了"),MB_OK);    
            DestroyWindow(hwnd);    
            break;            
  case   WM_DESTROY:    
                  MessageBox(NULL,_T("已调用过DestroyWindow(hwnd),看不到窗口了吧;"),_T("注意了"),MB_OK);    
          MessageBox(NULL,_T("以下处理WM_DESTROY"),_T("注意了"),MB_OK);    
          PostQuitMessage(0);    
          break;    
  case   WM_SYSCOMMAND:    
          if((LOWORD(wParam)&0xFFF0)==SC_CLOSE)    
          {    
                        MessageBox(NULL,_T("你关闭了窗口,即将发送WM_CLOSE消息!"),_T("注意了"),MB_OK);    
                SendMessage(hwnd,WM_CLOSE,0,0);    
          }    
          //不要添加   break,否则不能响应其它WM_SYSCOMMAND消息    
  default:    
        return   DefWindowProc(hwnd,message,wParam,lParam);    
          }    
          return(0);    
  }  

给我留言

留言无头像?