CDockablePane的使用与注意

摘自网络,担心资源转移,特记录在此。

创建悬浮窗口的步骤:

1. 创建悬浮窗口类
每一个悬浮窗口都是一个CDockablePane的派生类的对象, 因此要为每一个悬浮窗口创建一个新类

1.1 添加类
通过菜单Project->Add Class...或者在类视图中工程名字处右键选择Add->Class...添加类
选择MFC Class, 点Add按钮进入下一步
Class name处写入新类的名字, 这里用CDock, 选择Base class为CDockablePane
按Finish按钮, 添加类完成.

1.2 添加消息处理函数
一般至少要处理两个消息, 一个是WM_CREATE, 一个是WM_SIZE, 具体步骤为:
(1) 头文件中添加函数声明(函数名及参数不可写错)
protected:
 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 afx_msg void OnSize(UINT nType, int cx, int cy);
(2) cpp文件中添加消息映射
BEGIN_MESSAGE_MAP(CDock, CDockablePane)
 ON_WM_CREATE()
 ON_WM_SIZE()
END_MESSAGE_MAP()
这里BEGIN_MESSAGE_MAP和END_MESSAGE_MAP宏都是自动生成的, 只需要添加中间两行代码即可
(3) 添加函数实现部分
int CDock::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CDockablePane::OnCreate(lpCreateStruct) == -1)
  return -1;
 // 在这儿创建控件
 return 0;
}
void CDock::OnSize(UINT nType, int cx, int cy)
{
 CDockablePane::OnSize(nType, cx, cy);
 // 这儿添加代码
}

1.3 添加控件
现在创建的CDock类中由于没有任何控件, 因此如果现在创建该类的对象并显示, 该区域中由于全是垃圾数据, 故可能该窗口显示时为花屏. 如果程序运行期间出现类似花屏的问题, 大概会有几种可能性: 1. 没有创建控件 2. 已创建控件, 但控件位置不对或未覆盖整个的dockablePane 3. 控件虽然占据整个区域, 但不能自动刷新
这里以添加一个listBox为例:
(1) 在类的头文件中添加控件对象, 代码为:
protected:
 CListBox _listBox;
(2) 在OnCreate()中添加创建控件窗口的代码:
这里必须要注意, 需要先调用基类的函数OnCreate()
int CDock1::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CDockablePane::OnCreate(lpCreateStruct) == -1)
  return -1;

 // 在这儿创建控件
 // nID为该控件的ID, 可以自行设置, 如果对ID不感兴趣, 也可以选择传递0让系统做处理
 if (!_listBox.Create(WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, nID))
 {
  TRACE0("创建listbox失败");
  return -1;
 }

 return 0;
}
(3) 在OnSize中设置各个控件的位置
这里要注意的是, 需要将控件布满整个窗口. 这里只有一个listBox, 故可以直接用listBox覆盖窗口.
同理, 必须要先调用基类函数CDockablePane::OnSize(nType, cx, cy)
void CDock::OnSize(UINT nType, int cx, int cy)
{
 CDockablePane::OnSize(nType, cx, cy);
 // 这儿添加代码
 if (GetSafeHwnd() == NULL)
 {
  return;
 }

 if (_listBox.GetSafeHwnd() != NULL)
 {
  CRect rectClient;
  GetClientRect(rectClient);
  _listBox.SetWindowPos(NULL, rectClient.left, rectClient.top, rectClient.Width(), rectClient.Height(), SWP_NOACTIVATE | SWP_NOZORDER);
 }

}

 

2. 在程序中添加悬浮窗口对象
上面一步只是给工程添加了一个悬浮窗口类, 但并没生成该类的实例. 这里创建该实例(在CMainFrame类中)

2.1 在主框架类声明中添加对象, 代码为:
protected:  
 CDock m_wndDock;

2.2 创建dockablePane的窗口, 在主框架的OnCreate()函数中
(注: 这里我建议在OnCreate函数中自动生成代码EnableAutoHidePanes(CBRS_ALIGN_ANY)的后面添加)
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 ...
 EnableAutoHidePanes(CBRS_ALIGN_ANY);
 // 利用这里的CBRS_RIGHT来设置最初的窗口停靠的位置, 可以的取值是
 // CBRS_NOALIGN, CBRS_LEFT, CBRS_TOP, CBRS_RIGHT, CBRS_BOTTOM
 DWORD style = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI;
 if (!wndDock1.Create(
  // 该dock窗口的标题(如果可以有的话...)
  _T("Dock1"),
  // 该dock窗口的parent, 设置为this
  this,
  //  窗口的大小, 注意是"悬浮"的情况下的大小, 处于dock状态时大小与该值无关
  CRect(0, 0, 200, 200),
  // 该dock窗口是否有标题, 如果为FALSE, 则第一个字符串参数显示不出来
  TRUE,
  // 该dock窗口的ID值. 注意: 如果希望dock窗口的状态可以保存在注册表中(这样下次启动程序时仍保持该状态),  则该值必须的唯一的
  nID,
  // 
  style))
 {
  return FALSE;
 }
 ...

2.3去掉CDockablePane的Close按钮?

方法一:

在继承CDockablePane的类中重写CanBeClosed()方法: 

virtual BOOL CanBeClosed() const; ... BOOL COutputWnd::CanBeClosed() const { return FALSE;

}

方法二:

if (!m_wndView.Create(strFileView, this, CRect(0, 0, 250, 200), TRUE, ID_VIEW_VIEW,

  WS_CHILD | WS_VISIBLE | CBRS_LEFT | CBRS_HIDE_INPLACE | WS_CAPTION, AFX_CBRS_REGULAR_TABS, AFX_CBRS_RESIZE))在Create的时候 后面加上这样的参数设置AFX_CBRS_REGULAR_TABS, AFX_CBRS_RESIZE 就不会有那个关闭按钮了

2.4显示隐藏CDockablePane

m_wndFileView.ShowPane(TRUE,FALSE,TRUE);//显示

m_wndFileView.ShowPane(FALSE,FALSE,TRUE);//隐藏

2.5 给悬浮窗口添加icon, 暂时省略.

 

3. 设置窗口悬浮方式, 令窗口悬浮

3.1 设置窗口悬浮位置
这部分代码也应该在MainFrame类的OnCreate函数中, 而且紧跟创建悬浮窗口的后面.
设置悬浮位置只需要调用CDockablePane::EnableDocking即可
 m_wndDock.EnableDocking(CBRS_ALIGN_ANY);
其中, 参数可以是CBRS_ALIGN_TOP, CBRS_ALIGN_RIGHT, CBRS_ALIGN_BOTTOM, CBRS_ALIGN_ANY

3.2 令窗口悬浮
欲使一个CDockablePane对象悬浮, 只需要调用框架类的DockPane函数即可:
 DockPane(&m_wndDock);
但是若有另外一个悬浮窗口的对象需要和m_wndDock在一起显示, 构成一个组(就像VS的资源视力和类视图), 那么第二个悬浮窗口需要使用CDockablePane类的AttchToTabWnd函数, 代码如下:
 DockPane(&m_wndDock);
 CDockablePane *pTabbedBar = NULL;
 m_wndDock2.AttachToTabWnd(&m_wndDock, DM_SHOW, FALSE, &pTabbedBar);

 

 

CDockablePane 使用

这个是转载的

int m_nshowCurrent;

m_nshowCurrent=theApp.GetProfileInt(_T("Workspace//Pane-377"),_T("IsFloating"),0);  //在构造函数中

首先派生两个子类,源码就不用写出来了,占篇幅,在MainFrm里申明如:
CCurrentDockablePane         m_wndCurrentDockablePane;
CHistoryDockablePane        m_wndHistoryDockablePane;
CDockablePane* m_pTabbedBar;

然后在OnCreate()里面:
CString strHistoryDockablePane;
CString strCurrentView;
strCurrentView.LoadString(IDS_Current_VIEW);
strHistoryDockablePane.LoadString(IDS_History_VIEW);

if (!m_wndHistoryDockablePane.Create(strHistoryDockablePane, this, CRect(0, 0, 200, 200),
   TRUE, ID_VIEW_HistoryDockablePane, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI))
{
     TRACE0("Failed to create Class View window/n");
      return FALSE; // failed to create
}

if (!m_wndCurrentDockablePane.Create(strCurrentView, this, CRect(0, 0, 200, 200),
   TRUE, ID_VIEW_CurrentView, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT| CBRS_FLOAT_MULTI))
{
    TRACE0("Failed to create File View window/n");
     return FALSE; // failed to create
}

再给她们添加图标:
HICON hHistoryDockablePaneIcon = (HICON) ::LoadImage(::AfxGetResourceHandle(),
          MAKEINTRESOURCE(bHiColorIcons ? IDI_history : IDI_history), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), 0);
m_wndHistoryDockablePane.SetIcon(hHistoryDockablePaneIcon, FALSE);
HICON hCurrentViewIcon = (HICON) ::LoadImage(::AfxGetResourceHandle(),
   MAKEINTRESOURCE(bHiColorIcons ? IDI_Currrently : IDI_Currrently), IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), 0);
m_wndCurrentDockablePane.SetIcon(hCurrentViewIcon, FALSE);

m_wndHistoryDockablePane.EnableDocking(CBRS_ALIGN_ANY);
m_wndCurrentDockablePane.EnableDocking(CBRS_ALIGN_ANY);

DockPane(&m_wndHistoryDockablePane);
DockPane(&m_wndCurrentDockablePane);
m_pTabbedBar = NULL;

m_wndCurrentDockablePane.AttachToTabWnd(&m_wndHistoryDockablePane, DM_SHOW, FALSE, &m_pTabbedBar);

相关显示代码就这样的了.后来老大说关闭需要修改工具栏里的显示状态,即去掉对勾.在工具栏里控制他们的显示和隐藏简单啊,就是用m_wndCurrentDockablePane.ShowPane(TRUE,FALSE,TRUE);可是关闭再去修改工具栏想了半天,以为要重载CDockablePane的Close()消息,又尝试了他的很多消息,都不对.跟踪进去才知道是调用MainFrm来关闭的.里面有pMainfrm.onCloseDockingPane(this);好了,我就重载这个方法.

BOOL CMainFrame::OnCloseDockingPane( CDockablePane* pWnd )
{
    CWnd * pfWnd = pWnd->GetFocus();
    if (*pfWnd == m_wndCurrentDockablePane)
    {
        m_nshowCurrent = 0;
    }
    else if(*pfWnd == m_wndHistoryDockablePane)
    {
       m_nshowHistory = 0;
    }
   return TRUE;
}
这样工具栏里面的信息就更新了.呵呵,高兴的太早了,才做了一半,当两个面板拆开,即处于浮动状态时关闭根本就不调用这里.又郁闷了半天,还是老大牛逼,说那种情况是OnCloseMiniFrame,于是有如下重载:

BOOL CMainFrame::OnCloseMiniFrame( CPaneFrameWnd* pWnd )
{
      CWnd *ptWnd = pWnd->GetWindow( GW_CHILD );
     if (*ptWnd ==m_wndCurrentDockablePane)
      {
            m_nshowCurrent = 0;
     }
      else if (*ptWnd == m_wndHistoryDockablePane)
    {
             m_nshowHistory = 0;
    }
   return TRUE;
}

 

//写注册表,在析构函数中

theApp.WriteProfileInt(_T("Workspace//Pane-377"),_T("IsFloating"),m_nshowCurrent);

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MFC(Microsoft Foundation Classes)是微软公司提供的一个用于开发Windows桌面应用程序的框架。CDockablePane是MFC中的一个类,用于创建可停靠的面板。 CDockablePane类是CWnd类的派生类,它提供了创建和管理可停靠面板的功能。使用CDockablePane类,我们可以将面板放置在主窗口的工作区中,并且可以通过拖放的方式改变面板的位置和大小。CDockablePane类提供了一些常用的方法,用于设置面板的样式、标题和图标等。 要使用CDockablePane类,首先需要在MFC应用程序的主框架窗口中添加一个CDockablePane成员变量。然后,通过调用CDockablePane类的Create方法,可以在主框架窗口中创建一个可停靠的面板。可以通过调用CDockablePane类的各种方法,来设置面板的属性和样式。 在创建CDockablePane对象后,可以使用其AddPane方法向面板中添加子窗口。可以使用CDockablePane类的各种方法,来管理面板中的子窗口,如获取面板中子窗口的数量、显示或隐藏子窗口等。 CDockablePane类还提供了一些回调函数,可以通过重写这些函数,实现自定义的面板行为。例如,可以重写OnEraseWorkArea方法来绘制面板的背景,或者重写OnShowPopupMenu方法来自定义面板的右键菜单。 总之,CDockablePane是MFC中的一个非常有用的类,可以用于创建可停靠的面板,方便用户在应用程序中进行操作。使用CDockablePane,可以轻松实现面板的拖放、调整大小和隐藏显示等功能,提升了用户的交互体验。 ### 回答2: MFC(Microsoft Foundation Class)是微软公司开发的用于Windows操作系统的程序开发框架。CDockablePane是MFC中的一个类,用于创建可停靠的窗格。 CDockablePane通过继承CWnd类实现,可以在应用程序的主窗口中创建可停靠的子窗格。它可以被拖动、停靠和浮动,并且可以在主窗口的各个区域(如左侧、右侧、底部等)进行停靠。 要使用CDockablePane,首先需要在主窗口类中添加一个成员变量,该变量为CDockablePane类型。然后,在主窗口的OnCreate函数中调用Create函数来创建CDockablePane对象。可以通过SetWindowText函数设置窗格的标题。 接下来,可以通过调用EnableDocking函数来启用CDockablePane的停靠功能。可以使用DockPane函数将CDockablePane对象停靠到主窗口的指定区域。 CDockablePane还提供了一些其他的功能,如在窗格中添加控件、处理事件等。可以通过重写OnCreate、OnSize等函数来实现这些功能。 总之,CDockablePane是MFC中一个用于创建可停靠窗格的类,通过调用相应的函数和重写相关的函数可以实现窗格的创建、停靠、浮动等功能。它为用户提供了一个灵活的界面布局方式,可以方便地进行界面设计。 ### 回答3: MFC(Microsoft Foundation Classes)是微软提供的一套用于Windows应用程序开发的C++类库。CDockablePane是MFC中的一个类,用于实现可以停靠的窗格。 CDockablePane类继承自CBasePane,它可以被用户拖动或者停靠到不同的位置,如主窗口的顶端、左侧、右侧或者底部。CDockablePane类提供了一些方法和属性,用于控制窗格的行为和外观。 使用CDockablePane类创建一个停靠窗格的步骤如下: 1. 在MFC应用程序的主框架窗口类中,添加一个成员变量,类型为CDockablePane或者CDockablePane的派生类。 2. 在为主窗口类生成的OnInitDialog()函数里调用Create()方法,创建CDockablePane对象。 3. 设置窗格的显示位置、大小以及其他外观属性,例如调用SetWindowText()方法设置窗格的标题,调用EnableAutoHide()方法启用自动隐藏等。 4. 在主框架窗口的OnCreate()方法中调用DockControlBar()方法,将窗格添加到主窗口,并根据需要布置窗格的位置和大小。 5. 在需要显示或隐藏窗格的时候,调用ShowPane()方法。 CDockablePane类还提供了一些事件处理方法,例如OnPaneContextMenu()用于处理窗格的右键菜单事件,OnPaneResized()用于处理窗格大小改变事件等。开发人员可以重写这些事件处理方法,以实现自定义的行为。 总之,CDockablePane是MFC中用于创建可以停靠的窗格的类,通过使用CDockablePane类,开发人员可以方便地实现灵活的界面布局,并提供交互性和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值