设为首页 加入收藏

TOP

MFC程序员的WTL指南之分隔窗口(七)
2012-11-04 15:05:14 来源: 作者: 【 】 浏览:1990
Tags:MFC 程序员 WTL 指南 分隔 窗口
  数据成员

  其他的一些特性可以通过直接访问CSplitterWindow的公有成员来设定,只要GetSystemSettings()被调用了,这些公有成员也会相应的被重置。

  ·m_cxySplitBar:控制分隔条的宽度(垂直分隔条)和高度(水平分隔条)。默认值是通过调用GetSystemMetrics(SM_CXSIZEFRAME)(垂直分隔条)或GetSystemMetrics(SM_CYSIZEFRAME)(水平分隔条)得到的。

  ·m_cxyMin:控制每个窗格的最小宽度(垂直分隔)和最小高度(水平分隔),分隔窗口不允许拖动比这更小的宽度或高度。如果分隔窗口有WS_EX_CLIENTEDGE扩展属性,则这个变量的默认值是0,否则其默认值是2*GetSystemMetrics(SM_CXEDGE)(垂直分隔)或2*GetSystemMetrics(SM_CYEDGE)(水平分隔)。

  ·m_cxyBarEdge:控制画在分隔条两侧的3D边界的宽度(垂直分隔)或高度(水平分隔),其默认值刚好和m_cxyMin相反。

  ·m_bFullDrag:如果是true,当分隔条被拖动时窗格大小跟着调整,如果是false,拖动时只显示一个分隔条的影子,直到拖动停止才调整窗格的大小。默认值是调用SystemParametersInfo(SPI_GETDRAGFULLWINDOWS)函数的返回值。

  开始一个例子工程

  既然我们已经对分隔窗口有了基本的了解,我们就来看看如何创建一个包含分隔窗口的框架窗口。使用WTL向导开始一个新工程,在第一页选择SDI Application并单击Next,在第二页,如下图所示取消工具条并选择不使用视图窗口:


  我们不使用分隔窗口是因为分隔窗口和它的窗格将作为“视图窗口”,在CMainFrame类中添加一个CSplitterWindow类型的数据成员:

class CMainFrame : public ...
{
 //...
 protected:
  CSplitterWindow m_wndVertSplit;
};

接着在OnCreate()中创建分隔窗口并将其设为视图窗口:

LRESULT CMainFrame::OnCreate ( LPCREATESTRUCT lpcs )
{
 //...
 // Create the splitter window
 const DWORD dwSplitStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,dwSplitExStyle = WS_EX_CLIENTEDGE;

 m_wndVertSplit.Create ( *this, rcDefault, NULL,dwSplitStyle, dwSplitExStyle );

 // Set the splitter as the client area window, and resize
 // the splitter to match the frame size.
 m_hWndClient = m_wndVertSplit;
 UpdateLayout();

 // Position the splitter bar.
 m_wndVertSplit.SetSplitterPos ( 200 );

 return 0;
}

  需要注意的是在设置分隔窗口的位置之前要先设置m_hWndClient并调用CFrameWindowImpl::UpdateLayout()函数,UpdateLayout()将分隔窗口设置为初始时的大小。如果跳过这一步,分隔窗口的大小将不确定,可能小于200个象素点的宽度,最终导致SetSplitterPos()出现意想不到的结果。还有一种不调用UpdateLayout()函数的方,就是先得到框架窗口的客户区坐标,然后使用这个客户区坐标替换rcDefault坐标创建分隔窗口。使用这种方式创建的分隔窗口一开始就在正确的初始位置上,随后对位置调整的函数(例如 SetSplitterPos())都可以正常工作。

  现在运行我们的程序就可以看到分隔条,即使没有创建任何窗格窗口它仍具有基本的行为。你可以拖动分隔条,用鼠标双击分隔条使其移到窗口的中间位置。


  为了演示分隔窗口的不同使用方法,我将使用一个CListViewCtrl派生类和一个简单的CRichEditCtrl,下面是从CClipSpyListCtrl类摘录的代码,我们在左边的窗格使用这个类:

typedef CWinTraitsOR<LVS_REPORT | LVS_SINGLESEL | LVS_NOSORTHEADER>
CListTraits;

class CClipSpyListCtrl :
public CWindowImpl<CClipSpyListCtrl, CListViewCtrl, CListTraits>,
public CCustomDraw<CClipSpyListCtrl>
{
 public:
  DECLARE_WND_SUPERCLASS(NULL, WC_LISTVIEW)

  BEGIN_MSG_MAP(CClipSpyListCtrl)
   MSG_WM_CHANGECBCHAIN(OnChangeCBChain)
   MSG_WM_DRAWCLIPBOARD(OnDrawClipboard)
   MSG_WM_DESTROY(OnDestroy)
   CHAIN_MSG_MAP_ALT(CCustomDraw<CClipSpyListCtrl>, 1)
   DEFAULT_REFLECTION_HANDLER()
  END_MSG_MAP()
  //...
};

  如果你看过前面的几篇文章就会很容易读懂这个类的代码。它响应WM_CHANGECBCHAIN消息,这样就可以知道是否启动和关闭了其它剪贴板查看程序,它还响应WM_DRAWCLIPBOARD消息,这样就可以知道剪贴板的内容是否改变。

  由于分隔窗口窗格内的子窗口在程序运行其间一直存在,我们也可以将它们设为CMainFrame类的成员:

class CMainFrame : public ...
{
 //...
 protected:
  CSplitterWindow m_wndVertSplit;
  CClipSpyListCtrl m_wndFormatList;
  CRichEditCtrl m_wndDataViewer;

};

首页 上一页 4 5 6 7 8 9 10 下一页 尾页 7/11/11
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇VC程序中实现控件的动态生成与响应 下一篇制作一个基于MFC对话框的OpenGL类

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: