J'ai une application SDI WTL 8.0 pour Windows Mobile 5. Dans cet exemple inventé ci-dessous, je crée une vue, la détruis, puis la recréer. Mais, lorsqu'il est recréé, les assertions du gestionnaire WM_INITDIALOG échouent car le HWND du contrôle n'est pas valide.par défaut WM_DESTROY ne nettoie pas correctement les fenêtres enfants
Je remarque que je peux résoudre ce problème en gérant WM_DESTROY dans CMyView et en détruisant manuellement chaque contrôle enfant. Mais, je ne pensais pas que je devrais le faire. MSDN even says:
Ce message est envoyé d'abord à la fenêtre étant détruite, puis aux fenêtres de l'enfant (le cas échéant) comme ils sont détruits.
Quelqu'un a-t-il une idée de ce qui se passe? Editer: Si je gère WM_NCDESTROY dans CMyView, toutes les poignées de contrôle enfants sont toujours valides! (some_control_.IsWindow()==TRUE
) Ce n'est pas la façon dont il est censé être ...
Merci, 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
Merci pour votre aide. Qu'est-ce qui fait que "ce n'est pas une bonne pratique"? – PaulH
Fondamentalement parce que créer et détruire une fenêtre est une opération exigeante du système. Pratiquement parce que ATL :: CWindowImpl ne le gère pas correctement, donc nous avons du travail supplémentaire :-) –