当前位置:首页 > 编程开发

WM_DESTROY与WM_CLOSE

webgou17年前 (2009-11-08)编程开发1617

由于wce中,要重写wtl的CFrameWindow,然后采用CWindowImpl去实现View,view里面加入了函数:
并加入CWindowImpl实现的CButton成员函数:
CMYButton m_btn1;
 void OnFinalMessage(HWND /*hWnd*/)
 {
  delete this;
 }
 
然后再在其实的地放用new的方式把View new出来,当窗口关闭时,并在_DEBUG模式下就出现问题,:
若用WM_DESTROY时,在CMYButton 虚构函数里会Assert出,因m_hWnd 不为空
若用WM_CLOSE时,则在CMYButton 虚构函数里不会Assert出
在msdn中在wce的描述:

WM_CLOSE

This message is sent as a signal that a window or an application should terminate.

WM_CLOSE wParam = 0;
  lParam = 0;

Return Values

An application should return zero if it processes this message.

Default Action
The DefWindowProc function calls the DestroyWindow function to destroy the window.

Remarks

An application can prompt the user for confirmation, prior to destroying a window, by processing the WM_CLOSE message and calling the DestroyWindow function only if the user confirms the choice.

WM_DESTROY

This message is sent when a window is being destroyed. It is sent to the window procedure of the window being destroyed after the window is removed from the screen.

This message is sent first to the window being destroyed and then to the child windows, if any, as they are destroyed. During the processing of the message, it can be assumed that all child windows still exist.

WM_DESTROY wParam = 0;   lParam = 0; 

Return Values

An application should return zero if it processes this message.

Remarks

In Windows CE, DefWindowProc does not automatically call PostQuitMessage in its handling of WM_DESTROY.

If the window being destroyed is part of the clipboard viewer chain (set by calling the SetClipboardViewer function), the window must remove itself from the chain by processing the ChangeClipboardChain function before returning from the WM_DESTROY message.

再对CWindowImplBaseT 中的WindowProc分析:

template <class TBase, class TWinTraits>
LRESULT CALLBACK CWindowImplBaseT< TBase, TWinTraits >::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 CWindowImplBaseT< TBase, TWinTraits >* pThis = (CWindowImplBaseT< TBase, TWinTraits >*)hWnd;
 // set a ptr to this message and save the old value
 _ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
 const _ATL_MSG* pOldMsg = pThis->m_pCurrentMsg;
 pThis->m_pCurrentMsg = &msg;
 // pass to the message map to process
 LRESULT lRes;
 BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
 // restore saved value for the current message
 ATLASSERT(pThis->m_pCurrentMsg == &msg);
 // do the default processing if message was not handled
 if(!bRet)
 {
  if(uMsg != WM_NCDESTROY)
   lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
  else
  {
   // unsubclass, if needed
   LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC);
   lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
   if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc)
    ::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
   // mark window as destryed
   pThis->m_dwState |= WINSTATE_DESTROYED;
  }
 }
 if((pThis->m_dwState & WINSTATE_DESTROYED) && pOldMsg== NULL)
 {
  // clear out window handle
// CMYbutton在虚构函数中报错,应该是没有处理到这里的消息,
//如果处理到了这里的消息m_hWnd会设置为NULL,
//所以可以认为WM_DESTROY 消息发出后,立即处理了view OnFinalMessage,并把
//view销毁了,而CMYbutton里的对像也随之销毁掉,并没来得及运行到这里
//WM_CLOSE,则并没有立即运行view OnFinalMessage,所以有时间CMYbutton消息运行到这个地方,并把m_hWnd销毁掉
  HWND hWndThis = pThis->m_hWnd;
  pThis->m_hWnd = NULL;
  pThis->m_dwState &= ~WINSTATE_DESTROYED;
  // clean up after window is destroyed
  pThis->m_pCurrentMsg = pOldMsg;
  pThis->OnFinalMessage(hWndThis);
 }else {
  pThis->m_pCurrentMsg = pOldMsg;
 }
 return lRes;
}
 
 
从网上找到WM_DESTORY,WM_CLOSE,主要讲的是MFC中有功能区别,如下:
WM_DESTROY,WM_CLOSE   功能有什么不同 
  下面程序执行时出错 
  void   CMainFrame::OnClose()   
  { 
        CMDIFrameWnd::OnClose(); 
        CDocument   *doc; 
        doc=this->GetActiveDocument(); 
  } 
  下面程序执行时不出错, 
  void   CMainFrame::OnDestroy()   
  { 
        CDocument   *doc; 
        doc=this->GetActiveDocument(); 
        CMDIFrameWnd::OnDestroy(); 
  }  
原因分析:
WM_CLOSE是在窗口关闭前发送的,你还可以决定是否真的关闭窗口 
  WM_DESTROY是在窗口关闭过程中发送的,窗口已被移出屏幕 
  你的程序的错误在于调用   CMDIFrameWnd::OnClose();   后窗体已经 
  被Destroy掉了,this指针指向的窗口对象已经不存在了,所以出错
也就是处理顺序是先处理WM_CLOSE(窗口未关闭),后处理WM_DESTROY(窗口已关闭) 
  CMDIFrameWnd::OnClose();后的部分不执行,如需要执行,可放到OnDestroy()中,即你的第二段
调用父类缺省处理   CMDIFrameWnd::OnClose()时,   系统又发出了 
  WM_DESTROY消息将窗口destroy了,所以OnDestroy中this指针还可以用, 
  等出了CMDIFrameWnd::OnClose()后this指针指向的窗口对象已经不存在了
同理:
  void   CMainFrame::OnClose()   
  { 
      CDocument   *doc; 
      doc=this->GetActiveDocument(); 
      CMDIFrameWnd::OnClose(); 
  }   
  将不出错 
  下面程序执行时出错, 
  void   CMainFrame::OnDestroy()   
  { 
      CMDIFrameWnd::OnDestroy(); 
      CDocument   *doc; 
      doc=this->GetActiveDocument(); 
  } 
  原因如下: 
  OnClose()中调用DestoryWindow(),而DestoryWindow()中发送   WM_DESTROY   和   WM_NCDESTROY;DestoryWindow()执行结束时,OnDestroy()、OnNcDestory()也都执行了,在 CMDIFrameWnd::OnClose()返回后,CMainFrame   的对象已被释放,this指针不可再用。

扫描二维码推送至手机访问。

版权声明:本文由知了博客发布,如需转载请注明出处。

本文链接:https://www.webgou.info/?id=81

标签: vc
分享给朋友:

“WM_DESTROY与WM_CLOSE ” 的相关文章

Unity中Shader LOD控制

 文章来自https://zhuanlan.zhihu.com/p/21316674 ...…

windows 网络编程

    Windows网络编程…

VC++动态链接库(DLL)编程深入浅出(一)

1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。 静态链接库与动态链接库都是共享代码的…

数字视频传输系统

最近车机牵涉到到车后视方面的知识,在这里补充一点次料:…

IE7 0DAY漏洞所用shellcode的分析

以下IE7 0DAY所用shellcode,其主要行为不外乎下载病毒到本机并运行,但是实现起来与一般短小的shellcode有所不同:1. 在进行实质性动作之前,shellcode进行了三个inline hook,hook的API函数分别为:kernel32!UnhandledExceptionFi…

WinCE5.0开发环境的建立

本文主要介绍WinCE5.0开发环境的建立过程及注意事项。        …

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。