gpt4 book ai didi

c++ - 如何关闭动态创建的 CDockablePane 窗口?

转载 作者:搜寻专家 更新时间:2023-10-30 23:50:43 25 4
gpt4 key购买 nike

在我的 MFC(功能包)应用程序中,可以动态创建停靠 Pane 以显示图表/表格等。
但是,我不想让用户打开同一个东西两次。

我创建了这样一个 Pane :

// Create CMyDockablePane pPane
pPane->Create(...);
pPane->EnableDocking(CBRS_ALIGN_ANY);
// Create CRect rcPane
pPane->FloatPane(rcPane);

这似乎工作正常。

这就是我尝试检查 Pane 是否已存在的方式。 Pane 由其类型(类)和参数标识。

BOOL CanOpenPane(const type_info & paneType, const CMyParameter & parameter) const
{
CMainFrame* pFrm = GetMainFrame();
CDockingManager* pDockMan = pFrm->GetDockingManager();


// Check if there already is a pane of the same type which also has the same parameter.
bool canOpen = true;
CObList panes;
pDockMan->GetPaneList(panes);
POSITION pos = panes.GetHeadPosition();
while (pos)
{
CMyDockablePane* pPane = dynamic_cast<CMyDockablePane*>(panes.GetNext(pos));
if (NULL == pPane) { continue; }

if (paneType == typeid(*pPane) &&
pPane->GetParameter() == parameter)
{
canOpen = false;
break;
}
}


return canOpen;
}

问题是当我关闭一个 Pane 时,它无法被识别。 CDockingManager 对象仍然在 GetPanes() 调用中返回 Pane 。

我如何告诉经理不要返回已关闭的 Pane ?

当 Pane 关闭时,如何从 Pane 列表中删除该 Pane ?


更新

我深入研究后发现,当单击标题栏中的“x”按钮时,CWnd 对象实际上并未关闭,而只是关闭了它们的容器。
所以真正的问题似乎是真正关闭 Pane 。
我还更改了问题以更好地反射(reflect)问题。

最佳答案

如我的更新所述,停靠管理器给我关闭 Pane 的问题是这些 Pane 实际上并未关闭。只有他们的容器是封闭的; Pane 本身只是隐藏起来的。

因此,为了真正关闭 Pane ,我在 CMDIFrameWndEx 派生的主框架类中覆盖了以下方法:

BOOL CMainFrame::OnCloseMiniFrame(CPaneFrameWnd* pWnd)
{
if(0 == pWnd->GetPaneCount()) { return TRUE; } // No panes.. allow closing

// Close all child panes of the miniframe that is about to be closed.
//
// Panes are placed inside a mini frame when they have the "floating" status.
// Since I didn't find a way to iterate over the panes of a mini frame
// (CMultiPaneFrameWnd can have several panes), we iterate over all panes
// and close those whose parent frame is pWnd.

CDockingManager* pDockMan = GetDockingManager();
if(NULL != pDockMan)
{
CObList allPanes;
pDockMan->GetPaneList(allPanes, TRUE, NULL, TRUE);

for(POSITION pos = allPanes.GetHeadPosition(); pos != NULL;)
{
CDockablePane* pPane = dynamic_cast<CDockablePane*>(allPanes.GetNext(pos));
if (NULL == pPane) { continue; }

if(pWnd == pPane->GetParentMiniFrame())
{
pPane->PostMessage(WM_CLOSE); // Note: Post instead of Send
}
}

}

return TRUE; // Allow closing
}

第二个:

BOOL CMainFrame::OnCloseDockingPane(CDockablePane* pWnd)
{
CObList paneList;

// We can get CDockablePanes and CTabbedPanes here.
// The tabbed panes contain dockable panes.
CTabbedPane* pTabbed = dynamic_cast<CTabbedPane*>(pWnd);
CDockablePane* pDockable = dynamic_cast<CDockablePane*>(pWnd);
if(NULL != pTabbed)
{
pTabbed->GetPaneList(paneList);
}
else if(NULL != pDockable)
{
paneList.InsertAfter(paneList.GetHeadPosition(), pDockable);
}

// Whatever it was, we now have a list of dockable panes, which we will close.
for(POSITION pos = paneList.GetHeadPosition(); NULL != pos;)
{
CDockablePane* pPane = dynamic_cast<CDockablePane*>(paneList.GetNext(pos));
ASSERT(NULL != pPane);


// Let the window disappear and then recalculate the layout.
// Not doing this causes problems with panes grouped together in a tabbed pane.
pPane->ShowWindow(SW_HIDE);
RecalcLayout();

// Really close the window so the docking manager also doesn't know of it anymore.
pPane->Reset();
pPane->PostMessage(WM_CLOSE); // Note: Post instead of Send
}


return TRUE; // Allow closing
}

关于c++ - 如何关闭动态创建的 CDockablePane 窗口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1333801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com