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

WM_DESTROY与WM_CLOSE

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

由于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 ” 的相关文章

WinCE串口驱动分析

WinCE串口驱动分析  …

TCPMP分析

 TCPMP是一个功能强大开放式的开源多媒体播放器,播放器主…

freopen (stdin stdout ) 详解+实例

在flac库中看到if(fin != stdin)这种用法,记下.…

在ios上使用Google analytics

在ios上使用Google analytics,今天简单地测试了一下,总结: Google analytics使用分为普通web(移动web),及app(包括移动app).ios app访问记录,需要几个库: (libGoogleAnalytics.a,CFNetwork,libsqlite3.…

深刻理解Linux进程间通信(IPC)

一个大型的应用系统,往往需要众多进程协作,进程(Linux进程概念见附1)间通信的重要性显而易见。本系列文章阐述了 Linux环境下的几种主要进程间通信手段,并针对每个通信手段关键技术环节给出详细实例。为达到阐明问题的目的,本文还对某些通信手段的内部实现机制进 行了分析。 序…

Android消息传递应用功能解析

Android手机操作系统中有一种叫做Intent的消息传递机制。这在实际编程中是一个核心技术,值得我们去深入的研究。在这里大家将会了解到有关Android消息传递的一些基础应用技巧,帮助大家理解。每一个Cursor、ContentResolver做为一个小的注册中心,相关观察者可以在这个中心注册,…

发表评论

访客

看不清,换一张

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