`
paulfzm
  • 浏览: 888393 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

窗口破坏过程与Windows消息循环

    博客分类:
  • vc++
阅读更多

从用户单击关闭按钮(标题栏最右边)或者用鼠标或鍵盘选择系统菜单的“关闭”选项,直到窗口消失,应用程序结束。这期间到底发生了什么呢?这曾经是我百思不得其解的问题,我想也会有很多人和我一样会碰到这个问题。所以我要把我的一些学习心得写出来,与大家共享:  
  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);  
  }  
   
  --------------------------------------------------------------------------------  
  窗口破坏过程与Windows消息循环的补充,增加了对WM_NCDESTROY的处理  
  /**  
  *         File   Name                 :         MessageTest.cpp  
  *         Version                 :         1.1  
  *         Project   Name         :         MessageTest  
  *         Project   Type         :         Win32  
  *         Author                 :       netcoder  
  *                 Addition                           :         此版本增加了对WM_NCDESTROY的处理,   感谢   lily311   的补充    
  */  
   
  #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("已收到WM_DESTROY,看不到窗口了吧!"),_T("注意了"),MB_OK);  
                          break;  
   
                  case   WM_NCDESTROY:  
                          MessageBox(NULL,_T("收到WM_NCDESTROY!"),_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);

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/azhang00000/archive/2009/03/05/3961231.aspx

 

LRESULT CMyDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
    switch(message)   
    {   
    case   WM_CLOSE:   
        MessageBox(_T("收到WM_CLOSE消息,即将调用   DestroyWindow(hwnd);"),_T("注意了"),MB_OK);   
        DestroyWindow();   
        break;   
    case   WM_DESTROY:   
        MessageBox(_T("已调用过DestroyWindow(hwnd),看不到窗口了吧;"),_T("注意了"),MB_OK);   
        MessageBox(_T("以下处理WM_DESTROY"),_T("注意了"),MB_OK);   
        PostQuitMessage(0);
        break;   
    case   WM_SYSCOMMAND:   
        if((LOWORD(wParam)&0xFFF0) == SC_CLOSE)   
        {    
            MessageBox(_T("你关闭了窗口,即将发送WM_CLOSE消息!"),_T("注意了"),MB_OK);   
            SendMessage(WM_CLOSE,0,0);   
        }    
        //不要添加   break,否则不能响应其它WM_SYSCOMMAND消息 
    }     
    return CDialog::WindowProc(message, wParam, lParam);
}

 

分享到:
评论

相关推荐

    消息黑客(自定义并发送Windows消息)

    首先,Windows消息是操作系统用来传递信息的结构体,通常包含一个消息标识符(如WM_PAINT或WM_KEYDOWN),一个与消息相关的窗口句柄,以及可能的额外参数。这些消息通过消息队列进行传递,由Windows的消息循环负责...

    易语言窗口子类化例程源码

    4. **消息队列与消息循环**:Windows应用程序通常有一个消息循环,用于从消息队列中取出并分发消息。子类化窗口后,自定义窗口过程会参与到这个消息处理流程中。 5. **安全性与兼容性**:在进行窗口子类化时,需要...

    根据窗口标题关闭窗口

    3. **消息机制**:在Windows操作系统中,窗口之间的通信是通过消息队列和消息循环进行的。要关闭一个窗口,我们可以向其发送`WM_CLOSE`消息,这会触发窗口的关闭过程。`PostMessage`函数可以在目标窗口的消息队列中...

    windowsnt 技术内幕

    调协系统管理告警(Administrative Alert) 向用户发送系统管理消息 远程关闭一台Windows NT计算机 使用Windows NT系统属性对话框 Windows NT诊断程序(Diagnostic)简介 使用Windows NT诊断程序打印一份报告 在Windows ...

    Windows程序运行原理.ppt

    在Windows环境下,程序的执行基于一种被称为“消息循环”的机制。用户与界面的任何交互,比如点击鼠标或敲击键盘,都会被操作系统转化成标准化的消息,存入应用程序的消息队列中。程序则通过不断检查并处理这个队列...

    网络安全程序设计.ppt

    Windows程序通过消息循环(GetMessage, TranslateMessage, DispatchMessage)不断响应外部事件,执行相应操作。消息队列中的MSG结构包含了关于消息的各种信息,如消息类型、窗口句柄等。 Windows SDK是软件开发的...

    windows程序内部运行原理

    - **消息循环**:Windows应用程序通常有一个消息循环,负责处理来自操作系统的消息,如键盘输入、鼠标点击等。 - **窗口句柄**:每个窗口都有一个唯一的标识符,即窗口句柄,用于区分和操作不同的窗口。 7. **...

    windows-hook-demo

    学习"windows-hook-demo"可以帮助开发者掌握Windows Hook技术,从而在开发工具、监控软件、游戏外挂等领域实现各种功能,如键盘鼠标模拟、窗口监控、消息拦截等。然而,需要注意的是,不恰当的Hook使用可能导致系统...

    Windows 系统错误代码简单分析

     1002 窗口无法用来发送消息。  1003 无法完成此项功能。  1004 标志无效。  1005 卷不包含已识别的文件系统。请确认所有需要的文件系统驱动程序都已经加载,而且卷没有任何损坏。  1006 某文件的卷已...

    Hook经典分析 关于QQ Hook的应用 钩子

    在Windows系统中,Hook可以通过注册窗口过程(SetWindowLong/GetWindowLong)或者安装消息队列Hook(SetWindowsHookEx)来实现。对于QQ这类应用,可能需要关注的Hook点包括: 1. **消息处理**:通过Hook消息循环,...

    windows 10 cmd 备份

    在Windows 10操作系统中,命令提示符(Command Prompt,简称CMD)是一个至关重要的工具,它允许用户通过文本命令来执行系统级操作。CMD在处理系统管理任务、自动化脚本编写以及诊断问题时非常有用。当遇到如"cmd被...

    开源(VB代码):标题栏添加自己的按钮.zip

    学习这个代码,开发者可以深入理解VB与Windows API的交互,以及如何在不破坏系统默认行为的情况下自定义标题栏。 总之,这个压缩包提供了一个宝贵的学习资源,帮助开发者掌握在VB中自定义标题栏按钮的技术,这对于...

    C#坦克大作战窗口游戏源码

    【C#坦克大作战窗口游戏源码】是一个用于学习...总之,【C#坦克大作战窗口游戏源码】是一个理想的自学资源,它将理论知识与实践结合,帮助开发者提升C#编程技能,理解游戏开发的基本架构,为进一步的项目开发奠定基础。

    vc++实现hook编程源代码

    1. **理解Windows消息机制**:Hook技术往往与Windows的消息循环紧密相关,因此需要理解消息队列、消息泵和窗口过程等概念。 2. **内存操作和指针**:Hook技术涉及到对内存的读写,包括修改函数指针和跳转指令,因此...

    开源(VB代码):撕裂窗口病毒(源码).zip

    3. **循环与分支**:病毒可能会使用循环来不断生成窗口,使用条件语句来判断何时执行特定行为。 4. **多线程**:为了实现同时打开多个窗口,病毒可能利用多线程技术。 5. **文件操作**:可能涉及读取、写入或修改...

    易语言模拟Win8卸载程序过程源码.7z

    在这个“易语言模拟Win8卸载程序过程源码.7z”压缩包中,包含的是用易语言编写的一段代码,用于模拟Windows 8系统的软件卸载流程。 在Windows 8系统中,软件的卸载通常通过控制面板或者设置中的“应用和功能”来...

    DesktopSpammer

    1. **消息循环**:Windows应用程序的核心是消息循环,程序通过处理来自操作系统的消息来响应用户的操作。DesktopSpammer可能通过不断生成并发送自定义消息到桌面,来实现快速弹出窗口的效果。 2. **Windows API**:...

    易语言源码易语言HOOK注册表源码.rar

    1. **消息循环与消息处理**:在Windows编程中,每个窗口都有一个消息队列,程序需要有一个循环来处理这些消息。在易语言中,可以通过`系统消息处理`命令来实现。 2. **设置HOOK函数**:易语言中,可以使用`系统....

    Win32 Multilingual IME Overview for IME Development

    - 通过消息循环向应用程序提供信息(不破坏消息顺序) - 对IME感知和非IME感知应用提供强大支持 2. IME用户界面 IME用户界面是用户与输入法交互的部分,包括候选词列表、状态栏显示等。开发者需要设计并实现这些...

    Windows miniHook hookapi demo

    这些事件可以包括键盘、鼠标输入,窗口创建、消息发送等。钩子分为全局钩子(Global Hooks)和本地钩子(Local Hooks)。全局钩子可以在系统范围内的所有线程中运行,而本地钩子只在安装它们的线程中运行。 **Mini...

Global site tag (gtag.js) - Google Analytics