WM_RESETMEMBER message is registered window message to reset pane member to null. WM_CLOSE which will destroy window as well. Īnd for the same resone i return True to prevent close because we already close it via
#CODEJOCK DOCKING PANE FORCE DOCK CODE#
Will make your code assert, so you need to post message(WM_CLOSE) instead of sending it, this give CBasePane::OnLButtonDown handler a chance to finish executing while the pane hWnd still valid. OnClosePane is called in middle of CBasePane::OnLButtonDown handler, destroying window Return (LRESULT)TRUE //prevent close, we already close it RemovePaneFromDockManager(pane,TRUE,TRUE,TRUE,NULL) OnClosePane look like this : LRESULT CMainFrame::OnClosePane(WPARAM,LPARAM lp) Really close the window so the docking manager also doesn't know of it anymore.Īdd to yor CMainFram a msg entry like the following : ON_REGISTERED_MESSAGE(AFX_WM_ON_PRESS_CLOSE_BUTTON,OnClosePane) Not doing this causes problems with panes grouped together in a tabbed pane. Let the window disappear and then recalculate the layout. Whatever it was, we now have a list of dockable panes, which we will close.įor(POSITION pos = paneList.GetHeadPosition() NULL != pos )ĬDockablePane* pPane = dynamic_cast(paneList.GetNext(pos)) PaneList.InsertAfter(paneList.GetHeadPosition(), pDockable) The tabbed panes contain dockable panes.ĬTabbedPane* pTabbed = dynamic_cast(pWnd) ĬDockablePane* pDockable = dynamic_cast(pWnd) We can get CDockablePanes and CTabbedPanes here. PPane->PostMessage(WM_CLOSE) // Note: Post instead of SendĪnd the second: BOOL CMainFrame::OnCloseDockingPane(CDockablePane* pWnd) PDockMan->GetPaneList(allPanes, TRUE, NULL, TRUE) įor(POSITION pos = allPanes.GetHeadPosition() pos != NULL )ĬDockablePane* pPane = dynamic_cast(allPanes.GetNext(pos)) and close those whose parent frame is pWnd.ĬDockingManager* pDockMan = GetDockingManager() (CMultiPaneFrameWnd can have several panes), we iterate over all panes Since I didn't find a way to iterate over the panes of a mini frame Panes are placed inside a mini frame when they have the "floating" status. Close all child panes of the miniframe that is about to be closed. If(0 = pWnd->GetPaneCount()) // No panes. So to really close the panes I overrode the following methods in my CMDIFrameWndEx derived main frame class: BOOL CMainFrame::OnCloseMiniFrame(CPaneFrameWnd* pWnd) Only their containers were closed the panes themselves were just hidden. I also changed the question to better reflect the problem.Īs described in my update, the problem for the docking manager giving me closed panes, was that the panes were not actually closed. So the real problem seems to be to really close the panes. I dived a bit deeper and found, that the CWnd objects are not actually closed, when clicking the 'x' button in the caption bar, but only their containers. How can I remove the pane from a pane list, when it's closed? How can I tell the manager to not return panes that are closed? The CDockingManager object still returns the pane in the GetPanes() call. The problem with this is that when I close a pane, this is not recognized. Check if there already is a pane of the same type which also has the same parameter.ĬMyDockablePane* pPane = dynamic_cast(panes.GetNext(pos)) BOOL CanOpenPane(const type_info & paneType, const CMyParameter & parameter) constĬDockingManager* pDockMan = pFrm->GetDockingManager() A pane is identified by its type (class) and a parameter. This is how I tried to check if a pane already exists. I create a pane like this: // Create CMyDockablePane pPane However, I don't want to let the user open the same thing twice. In my MFC (Feature Pack) application one can dynamically create docking panes to display charts/tables etc.