類似 Spybot/Outlook 左側導航:多個面板疊放,每個面板含 **標題列 (Rubric)** 與 **內容區 (Content)**。點擊標題列切換顯示對應內容區,同一時間僅一個內容區可見。
#include
struct PANE { CWnd* pRubric; CWnd* pContent; BOOL bOpen; };
class CStackedWndCtrl : public CStatic {
CArray m_arrPanes;
public:
int AddPane(CWnd* pRubric, CWnd* pContent);
void RearrangeStack();
~CStackedWndCtrl();
};
int CStackedWndCtrl::AddPane(CWnd* pRubric, CWnd* pContent) {
// 隱藏目前展開的面板
for (int i=0; ibOpen) m_arrPanes[i]->bOpen = FALSE;
PANE* p = new PANE; p->pRubric = pRubric; p->pContent = pContent; p->bOpen = TRUE;
int idx = m_arrPanes.Add(p);
RearrangeStack();
return idx;
}
void CStackedWndCtrl::RearrangeStack() {
CRect rcClient; GetClientRect(&rcClient);
int y = 0;
for (int i=0; ipRubric->MoveWindow(rcRubric);
y += 24;
if (p->bOpen) {
CRect rcContent(0, y, rcClient.Width(), rcClient.bottom);
p->pContent->MoveWindow(rcContent);
p->pContent->ShowWindow(SW_SHOW);
y = rcClient.bottom; // 內容區佔滿剩餘空間
} else {
p->pContent->ShowWindow(SW_HIDE);
}
}
}
// Rubric 視窗 (如 CStatic 衍生類) 處理 WM_LBUTTONDOWN
void CRubricWnd::OnLButtonDown(UINT nFlags, CPoint point) {
GetParent()->SendMessage(WM_USER_SWITCH_PANE, (WPARAM)this);
}
// Stacked 控制項處理
ON_MESSAGE(WM_USER_SWITCH_PANE, OnSwitchPane)
LRESULT CStackedWndCtrl::OnSwitchPane(WPARAM wp, LPARAM) {
CWnd* pClicked = (CWnd*)wp;
for (int i=0; ibOpen = (m_arrPanes[i]->pRubric == pClicked);
}
RearrangeStack();
return 0;
}
CStackedWndCtrl::~CStackedWndCtrl() {
for (int i=0; ipRubric->DestroyWindow(); delete m_arrPanes[i]->pRubric;
m_arrPanes[i]->pContent->DestroyWindow(); delete m_arrPanes[i]->pContent;
delete m_arrPanes[i];
}
m_arrPanes.RemoveAll();
}
// 對話框初始化
m_stacked.AddPane(new CRubricWnd(_T("好友")), new CFriendListCtrl);
m_stacked.AddPane(new CRubricWnd(_T("群組")), new CGroupTreeCtrl);
m_stacked.AddPane(new CRubricWnd(_T("最近")), new CRecentListCtrl);