VS2008提供CDockablePane实现悬浮窗效果,各小窗口可以根据需要调整布局。本文介绍CDockablePane的使用方法以及使用中遇到的一些问题及解决方案。
首先展示一下最终效果
按住鼠标拖动小窗口,效果如下,可以根据需要选择放置位置:
实现步骤:
1. 新建一个MFC应用程序,其他选择默认。
2. 新建MFC类CLeftDlg,选择基类为CDialog。点击完成系统会自动生成对话框资源IDD_LEFTDLG,在资源视图中打开该对话框,放入自己想要的内容,如文本框,按钮等。
3. 新建MFC类CleftPane,选择基类为CDockablePane。添加此类的WN_CREATE和WM_SIZE相应,和成员变量
CLeftDlg m_LeftDlg;
编辑OnCreate 和 OnSize函数:
int CLeftPane::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDockablePane::OnCreate(lpCreateStruct) == -1) return -1;
// TODO: 在此添加您专用的创建代码 CRect rectDummy; rectDummy.SetRectEmpty(); // 创建选项卡窗口: if (!m_LeftDlg.Create(IDD_LEFTDLG,this)) { TRACE0("未能创建输出选项卡窗口/n"); return -1; //未能创建 } m_LeftDlg.ShowWindow(SW_SHOW);
return 0; }
void CLeftPane::OnSize(UINT nType, int cx, int cy) { CDockablePane::OnSize(nType, cx, cy); m_LeftDlg.SetWindowPos (this, -1, -1, cx, cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); m_LeftDlg.ShowWindow(SW_SHOW); } |
4. 在Mainframe中添加变量CleftPane m_LeftPane; OnCreate中添加代码
if (!m_LeftPane.Create(_T("LeftPane"), this, CRect(0, 0, 100, 100), TRUE, IDD_TESTDLG, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI)) { TRACE0("未能创建输出窗口/n"); return FALSE; } m_LeftPane.SetControlBarStyle(m_LeftPane.GetControlBarStyle() | CBRS_LEFT | CBRS_SIZE_DYNAMIC); m_LeftPane.EnableDocking(CBRS_ALIGN_ANY); DockPane(&m_LeftPane); |
5. 重复步骤2-4,为CBottomPane添加对话框CBottomDlg,并在MainFrame中添加m_BottomFrame变量和OnCreate中的代码。
6. 此时,初步的页面布局已经没有问题,但是运行的结果会出现如下小窗口不能刷新现实区域,拖动时出现叠影。此时需要为CLeftPane和CBottomPane添加OnPaint函数,将背景填充为白色:
void CBottomPane::OnPaint() { CPaintDC dc(this); // device context for painting CRect rc; GetClientRect(rc); CBrush brush; brush.CreateSolidBrush(COLORREF(RGB(255, 255, 255))); dc.FillRect(&rc,&brush); brush.DeleteObject(); } |
7. 如果需要去掉CDockablePane右上角的close按钮,可以在创建pane的时候加入如下参数:
m_LeftPane.Create(_T("LeftPane"), this, CRect(0, 0, 100, 100), TRUE, IDD_TESTDLG,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI, AFX_CBRS_REGULAR_TABS, AFX_CBRS_RESIZE))
效果如下:
8. 在CDockablePane的内部按鼠标右键或出现系统菜单,要屏蔽此菜单,可以为CLeftPane和CBottomPane添加相应,运行,菜单不见鸟。
void CLeftPane::OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/)
9. 编译运行,最终效果如第一张图所示。