我有一个用于 Windows Mobile 5 的 WTL 8.0 SDI 应用程序。在下面这个人为的示例中,我创建一个视图,销毁它,然后重新创建它。但是,当它在 WM_INITDIALOG 处理程序中重新创建断言时,因为控件的 HWND 无效而失败。
我注意到我可以通过在 CMyView 中处理 WM_DESTROY 并手动销毁每个子控件来解决此问题。但是,我认为我不应该这样做。MSDN 甚至说:
此消息首先发送到正在销毁的窗口,然后在子窗口(如果有)被销毁时发送到它们。
有人知道发生了什么吗?
编辑:如果我在 CMyView 中处理WM_NCDESTROY,所有子控件句柄仍然有效!( some_control_.IsWindow()==TRUE
) 这不是它应该的样子......
谢谢,保罗
class CMyView : public CDialogImpl< CMyView >,
public CWinDataExchange< CMyView >
{
// <snip> Message Map and other standard WTL macros </snip>
LRESULT OnInitDialog( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ )
{
DoDataExchange( FALSE );
// assertion fails within the SetWindowText() call
// atlwin.h line 876
// ATLASSERT(::IsWindow(m_hWnd));
some_control_.SetWindowText( _T( "Foo" ) );
return 0;
};
private:
CEdit some_control_;
}; // class CMyView
class CMainFrame : public CFrameWindowImpl< CMainFrame >,
public CUpdateUI< CMainFrame >,
public CMessageFilter,
public CIdleHandler
{
public:
// <snip> Message Map and other standard WTL macros </snip>
BOOL CMainFrame::PreTranslateMessage( MSG* pMsg )
{
if( CFrameWindowImpl< CMainFrame >::PreTranslateMessage( pMsg ) )
return TRUE;
return my_view_.PreTranslateMessage( pMsg );
};
LRESULT OnCreate( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ )
{
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT( pLoop != NULL );
pLoop->AddMessageFilter( this );
pLoop->AddIdleHandler( this );
m_hWndClient = my_view_.Create( m_hWnd );
my_view_.DestroyWindow();
m_hWndClient = my_view_.Create( m_hWnd );
};
private:
CMyView my_view_;
}; // class CMainFrame