记一些事,免得以后忘了。关于SetWindowLong

来源:互联网 发布:linux ssh ppk 编辑:程序博客网 时间:2024/05/16 00:43
LRESULT CALLBACK ZFrame::__WindowTresteeshipProc( HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam ){CWindowObject *pWndObject = reinterpret_cast<CWindowObject*>(hWnd);ATLASSERT( pWndObject != NULL );/*此处的delete pWndObject有非常大的问题需要解决,假如用户会在对话框的WM_NCPAINT中调用 DestroyWindow( this ),那么,ZFrame的处理流程致如下:首先,ZFrame处理消息的优先级高与MFC,所以WM_NCPAINT消息会先交由本函数处理,本函数将WM_NCPAINT消息分发到CUIPopupWindow::WindowProc函数中,而CUIPopupWindow::WindowProc函数为了覆盖MFC(调回Windows默认的DefWindowProc)绘制的UI,选择先调回父类(既CWindowObject类)的WindowProc函数,CWindowObject类的WindowProc函数直接使用CallOldWindowProc,调回被ZFrame子类化前的窗口过程(既MFC的AfxWndProcBase,大多数情况下,MFC选择直接调回到Windows的DefWindowProc)。此时,若MFC(用户)在处理WM_NCPAINT中调用DestroyWindow,窗口将继续产生WM_DESTROY -> WM_NCDESTROY这些消息仍然会被ZFrame(本函数)处理,但对WM_NCDESTROY消息的处理是销毁包装窗口的CWindowObject类对象。那么,如上所述,ZFrame在处理WM_NCPAINT过程中(开始处理后,处理完成前)窗口被销毁,导致对象也被销毁。以下是大致的还原的栈侦(从上到下,最上边的是调用者):OSRedrawWindow() ->__WindowTresteeshipProc( WM_NCPAINT ) ->CUIPopupWindow::WindowProc( WM_NCPAINT ) ->(注意此处:CUIPopupWindow处理WM_NCPAINT消息时选择先让父类处理,然后再自己处理,既先调用CWindowObject::WidnowProc( WM_NCPAINT ),实际的绘制工作在调用CWindowObject::WidnowProc( WM_NCPAINT )完后再进行。)CWindowObject::WidnowProc( WM_NCPAINT ) ->MFC::AfxWndProcBase( WM_NCPAINT ) ->用户调用DestroyWindow() -> (省略WM_DESTROY消息,直接WM_NCDESTROY)__WindowTresteeshipProc( WM_NCDESTROY ) ->....(注意这里:此处对MFC::AfxWndProcBase( WM_NCDESTROY )的调用完成后将销毁ZFrame对窗口的包装对象,既CUIPopupWindow类的实例对象)。MFC::AfxWndProcBase( WM_NCDESTROY ) ->逐步向上返回.....这一系列动作完成后开始逐步返回到最早的调用者(OSRedrawWindow)当返回到__WindowTresteeshipProc( WM_NCDESTROY )时ZFrame窗口包装器对象被销毁。返回到CUIPopupWindow::WindowProc( WM_NCPAINT )时,CUIPopupWindow::WindowProc( WM_NCPAINT )函数仍然在使用窗口包装器对象,错误发生……< .fuhao >< .2015年12月15日19时40分 >< 503267714@qq.com >< Copyright (C.) 2009-2015 北京顺福群聚科技有限公司, all rights reserved >*/// 托管过程决定是否调回原来的窗口过程LRESULT lResult = pWndObject->WindowProc( message, wParam, lParam );if( message == WM_NCDESTROY ){if( pWndObject->m_bAutoDelete ){// 销毁MSCTFIME UI类的窗口时会失败,所以可能导致对同一个// 托管对象delete 多次。应该还原窗口过程,先不写。if( pWndObject->FromHandlePermanent( pWndObject->GetSafeHwnd() ) ){delete pWndObject;}}}return lResult;}

0 0
原创粉丝点击