MFC程序员WTL指南(8)分隔窗口
2008-01-19 20:26:47 来源:WEB开发网GetSystemSettings()读取系统设置并相应的设置数据成员。分隔窗口在OnCreate()函数中自动调用这个函数,你不需要自己调用这个函数。当然,你的主框架窗口应该响应WM_SETTINGCHANGE并将它传递给分隔窗口, CSplitterWindow在WM_SETTINGCHANGE消息的处理函数中调用GetSystemSettings()。传递true给bUpdate参数,分隔窗口会根据新的设置重画自己。
数据成员
其他的一些特性可以通过直接访问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())都可以正常工作。
更多精彩
赞助商链接