У меня есть приложение WTL 8.0 SDI для Windows Mobile 5. В этом надуманном примере ниже я создаю представление, уничтожаю его, а затем повторно создаю. Но при повторном создании утверждений в обработчике WM_INITDIALOG происходит сбой, поскольку HWND элемента управления недействителен.по умолчанию WM_DESTROY неправильно очищает дочерние окна
Я отмечаю, что могу исправить это, обработав WM_DESTROY в CMyView и уничтожив каждый дочерний элемент вручную. Но я не думал, что должен. MSDN even says:
Это сообщение посылается первым в окно уничтожается, а затем в дочерние окна (если таковые имеются), поскольку они уничтожены.
У кого-нибудь есть идея, что происходит?
Редактировать: Если я обрабатываю WM_NCDESTROY в CMyView, все дочерние элементы управления все еще действительны! (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
Спасибо за помощь. Что делает эту «неправдоподобную практику»? – PaulH
Принципиально, потому что создание и уничтожение окна - это система, требующая операции. Практически потому, что ATL :: CWindowImpl неправильно обрабатывает его, поэтому у нас есть дополнительная работа :-) –