1

WindowsMo​​bile5用のWTL8.0SDIアプリケーションがあります。以下のこの不自然な例では、ビューを作成し、破棄してから、再作成します。ただし、再作成されると、コントロールのHWNDが無効であるため、WM_INITDIALOGハンドラーでアサーションが失敗します。

CMyViewでWM_DESTROYを処理し、すべての子コントロールを手動で破棄することで、これを修正できることに注意してください。しかし、私はそうしなければならないとは思いませんでした。MSDNは言う

このメッセージは、最初に破棄されているウィンドウに送信され、次に破棄された子ウィンドウ(存在する場合)に送信されます。

誰かが何が起こっているのかについての考えを持っていますか?

編集: CMyViewでWM_NCDESTROYを処理する場合、すべての子コントロールハンドルは引き続き有効です!(some_control_.IsWindow()==TRUE)それはそれが想定されている方法ではありません...

ありがとう、PaulH

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
4

2 に答える 2

0

100%確信はありませんが、some_control_CEditコントロールが親ウィンドウに登録されていないようです。親ハンドルをパラメータとしてsome_control_.Create(...)を呼び出す必要があると思います。

CEdit :: Create()のドキュメントについては、msdnの記事を参照してください。

于 2009-12-09T14:50:09.503 に答える
0

同じウィンドウを作成、破棄、および再作成することはお勧めできません。ウィンドウを非表示にして、再度表示するときにコンテンツを再初期化することを検討する必要があります。

とにかく、あなたのコードは再作成時にアサートしません:

virtual void CMyView::OnFinalMessage(HWND)
{
    some_control_.m_hWnd = 0;
}
于 2010-03-06T01:36:15.410 に答える