65.9K
CodeProject 正在变化。 阅读更多。
Home

BoxPlanner - 简单的布局算法

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.65/5 (6投票s)

2009年3月19日

CPOL

2分钟阅读

viewsIcon

30341

downloadIcon

742

用于在行或列中布局控件的布局算法

引言

许多 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),或者想要使用其次方向所需的尺寸并与窗口对齐 - psAlignLeftpsAlignCenterpsAlignRight 用于水平方向,或者 psAlignToppsAlignMiddlepsAlignBottom

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 日:初始发布
© . All rights reserved.