Question

J'essaie de créer une zone sur un CDialog, où je peux mettre des CDockablePanes. Ceux-ci doivent être parfaitement ancrables à un contenu de dialogue fixe.

L'exemple de volets de dialogue Codejock est exactement ce que je veux, mais réalisé avec les classes du pack de fonctionnalités MFC: http://codejock.com/downloads/samples/dockingpane.asp

Pour le moment, j'ai une classe héritée de CFrameWndEx, qui est intégrée dans le CDialog. J'ai également un CDockablePane fonctionnel dedans. Je peux le détacher et le déplacer, mais quand je veux l'ancrer, le programme se bloque.

Ceci est dû au fait que la classe de volet ancrable essaie de générer un volet factice pour prévisualiser où le volet réel irait. Il appelle GetTopLevelFrame () qui renvoie NULL. Cela produit le crash de afxpane.cpp @CreateEx ().

Quelqu'un a-t-il de l'aide ou des idées pour moi? :(

Salutations,


Modifier:
D'accord, un peu de code:
J'ai écrit une petite classe héritée de CFrameWndEx (car son constructeur est protégé):

class CMyFrame: public CFrameWndEx  
{  
    public:  
    DECLARE_MESSAGE_MAP()  
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);  
    CDockablePane m_DockWnd; // Will use an own class inherited from CDockablePane later on
};

Maintenant, j'ai intégré cette classe dans mon CDialog et j'ai changé sa taille pour la taille des boîtes de dialogue:

BOOL CMyDlg::OnInitDialog()  
{      
    CRect wndRect;  
    GetWindowRect(wndRect);    
    m_pFrame = new CMyFrame();  
    m_pFrame->Create(NULL, NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, wndRect, this);  
    m_pFrame->MoveWindow(wndRect);

    CDialog::OnInitDialog();
    ...
}

Dans OnCreate () de la classe CMyFrame, j'ai configuré CDockablePane et je l'ai ancré:

int CMyFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWndEx::OnCreate(lpCreateStruct) == -1)
        return -1;

    CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

    EnableDocking(CBRS_ALIGN_ANY);
    // DT_SMART creates dummy dockable panes for previewing the possible position of  
    // the currently floating pane, this leads to a crash at call to GetTopLevelFrame()
    CDockingManager::SetDockingMode(DT_SMART);
    EnableAutoHidePanes(CBRS_ALIGN_ANY);

    // m_DockWnd is a CDockablePane
    if (!m_DockWnd.Create(_T("Test"), this, CRect(0, 0, 200, 200), TRUE, IDC_DOCK_WND, 
        WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI))
    {
    TRACE0("Failed to create Properties window\n");
    return 1; // failed to create
    }

    m_DockWnd.EnableDocking(CBRS_ALIGN_ANY);
    DockPane(&m_DockWnd);

    return 0;
}
Était-ce utile?

La solution

D'accord, je l'ai enfin compris.

Au lieu de laisser le MFC créer le dummywnd, je l'ai créé moi-même.Ainsi, le MFC ignore la création et l'appel à GetTopLevelFrame ().

Maintenant, le problème était que la variable membre dummywnd était protégée et n'avait pas de méthode d'ensemble publique.J'ai donc hérité d'une classe et construit moi-même une méthode d'ensemble publique.

Autres conseils

Une autre méthode simple consiste à définir votre mode d'ancrage sur DT_IMMEDIATE si vous êtes dans un Dlg implémentant des cadres d'ancrage.Appel CDockingManager :: SetDockingMode (DT_IMMEDIATE);

dans OnCreate de votre objet CFrameWndEx (ou à un endroit approprié).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top