BoxPlanner - 简单的布局算法
用于在行或列中布局控件的布局算法

引言
许多 Windows 应用程序在布局父窗口中的控件时,指定绝对位置和绝对大小。这种策略有一些缺点:创建的窗口无法调整大小,更改比较困难,创建美观的窗口耗时较长。
另一种非常常见的做法,尤其是在跨平台框架(wxWidgets、QT、Java 等)中,是使用布局算法。布局算法根据其策略确定控件的大小和位置。虽然每个控件可以提供关于其大小、位置和对齐方式的偏好,但布局算法可以忽略这些偏好,如果它们与布局策略冲突的话。
使用代码
什么是 Planner?
Planner 实现了一个布局算法。可以使用 Add
方法将控件与其大小、位置和对齐方式的偏好一起添加到 Planner 中,而 SetControl
方法设置其父控件。使用 Layout
方法来布局控件。
class Planner {
public:
virtual void Layout() = 0;
virtual void SetControl(const Control& item) = 0;
virtual void AddControl(const Control& item,int factor,int style) = 0;
...
};
什么是 BoxPlanner?
BoxPlanner
允许按行或按列布局控件。BoxPlanner
具有一个主方向:水平(psHorizontal
- 按行布局控件)和垂直(psVertical
- 按列布局控件)。主方向可以在构造期间或使用 SetDirection
方法指定。另一个方向将是次方向。
当控件添加到 planner
时,它可以指定其因子和样式。
- 因子是提示
planner
如何在主方向上调整控件大小。如果因子为 0,则将使用其所需的主方向大小。否则,其主方向大小将是因子单位(因子单位 - 主方向中的可用空间除以所有控件因子的总和)。 - 在次方向上,控件可以指定它想要所有可用空间(
psGrowAll
),或者想要使用其次方向所需的尺寸并与窗口对齐 -psAlignLeft
、psAlignCenter
、psAlignRight
用于水平方向,或者psAlignTop
、psAlignMiddle
、psAlignBottom
。
BoxPlanner 演示?
在窗口创建过程中,我们创建控件并将它们添加到 BoxPlanner
实例中:
LRESULT OnCreate ( LPCREATESTRUCT lpcs ) {
button1.Create(m_hWnd,CRect(0,0,100,50),_T("button 1"),WS_CHILD | WS_VISIBLE);
button2.Create(m_hWnd,CRect(0,0,100,40),_T("button 2"),WS_CHILD | WS_VISIBLE);
button3.Create(m_hWnd,CRect(0,0,100,40),_T("button 3"),WS_CHILD | WS_VISIBLE);
button4.Create(m_hWnd,CRect(0,0,100,40),_T("button 4"),WS_CHILD | WS_VISIBLE);
button5.Create(m_hWnd,CRect(0,0,100,50),_T("button 5"),WS_CHILD | WS_VISIBLE);
planner.AddControl(Control(button1.m_hWnd),2,Planner::psAlignLeft );
planner.AddControl(Control(button2.m_hWnd),2,Planner::psAlignRight );
planner.AddControl(Control(button3.m_hWnd),5,Planner::psGrowAll );
planner.AddControl(Spacer(10,10),2,Planner::psGrowAll );
planner.AddControl(Control(button4.m_hWnd),2,Planner::psGrowAll );
planner.AddControl(Spacer(10,10),0,Planner::psGrowAll );
planner.AddControl(Control(button5.m_hWnd),2,Planner::psGrowAll );
planner.SetControl(Control(m_hWnd));
SetMsgHandled(false);
return 0;
}
现在,在大小调整事件发生时,我们调用 Layout
方法:
void OnSize(UINT nType, CSize size) {
planner.Layout();
}
历史
- 2009 年 3 月 19 日:初始发布