用于调整窗口大小的助手类

Image 1 介绍 在MFC中,调整或重新定位控件可能是相当麻烦的。如果您熟悉。net平台,那么通过使用控件类的锚和停靠属性,以及在设计时支持向容器控件添加子控件,事情会简化得多。我试着模仿。net的一些特性,但是用c++的方式。 背景 为此,还有其他在线解决方案(也可以在CodeProject.com上)。我认为我的解决方案在设计、简单和丰富的特性上脱颖而出。 这个解决方案允许你做以下事情: 锚对话框控件创建面板包含其他面板或UI控件限制对话框控件的大小或面板通过使用最小大小和最大大小属性对话框大小的限制,使用最小大小和最大大小属性创建水平或垂直分离容器冷冻分离容器,这样用户不能使用鼠标调整面板设置面板的分裂容器被固定,当对话框尺寸,固定面板将保持不变集对话框控件的父或面板(与Win32 SetParent API)显示调整控制对话框的右下角用视觉风格(如果应用程序支持它)显示调整控制分配器的分裂集装箱码头在其母面板对话框控件创建流布局面板 让我们来看看。net是如何调整子控件的大小的: 它允许子控件被锚定到左、上、右、下边缘,或者这四个选项的任意组合。停靠——它允许子控件停靠在左、上、右和下边缘。Visual Studio设计器支持——如果您将一个框架控件放置在一个Windows窗体上,然后将一个按钮控件拖动到该框架的顶部,该按钮将成为框架的实际子控件和Windows窗体的孙子控件。但在MFC的资源编辑器中,如果您将框架放在对话框模板上,然后在框架控件的顶部拖动一个按钮,该按钮实际上是对话框模板的直接子元素,而不是框架。这意味着如果你移动框架,按钮将不会移动。SplitContainer——自从这个控件发明以来,创建拆分器窗口从来没有这么简单过。它有两个面板,可以容纳其他控件。表示水平或垂直地动态布局其内容的面板。 在。net中,所有控件都是窗体的子控件或子控件;这就创建了控件的层次结构。当父节点被调整大小或重新定位时,它的所有子节点将根据其锚定或停靠属性设置调整大小或重新定位。 在我的解决方案中,我创建了一个矩形的层次结构(CRect)。我已经实现了锚、面板、SplitContainer、Dock和FlowLayout概念。 这个解决方案中有几个类,但是CWndResizer是开发人员将使用的唯一类。 通常,你会在Visual Studio资源编辑器中设计你的对话框模板,然后在对话框类实现中,你会有一个这样的成员变量: 隐藏,复制Code

private:
    CWndResizer m_resizer;

本文附带的示例使用CDialog类演示该类的许多特性。但是这个类可以与任何从CWnd派生的类一起使用(CDialog, CPropertyPage, CPropertySheet, CFrmWnd, CFormView,等等)。 在这个类做任何事情之前,你必须像这样调用钩子方法: 隐藏,复制Code

BOOL CExample1Dlg::OnInitDialog()
{
  CDialog::OnInitDialog();
  BOOL bOk = m_resizer.Hook(this);
  ASSERT(bOk == TRUE);
}

在本文中,我将把这个窗口(传递给Hook方法)称为“挂钩窗口”。 通过调用这个方法,它在WndProc链中放置了一个窗口过程钩子。 当您调用钩子方法时,它将钩子窗口的客户区存储在一个名为CPanel的结构中。面板主要是用钩窗的客户端坐标表示的矩形区域。一个面板可以有零个或多个面板作为子面板。在创建面板期间,您将为面板分配一个惟一的名称。该名称用于引用面板或查找面板。挂钩窗口的客户区域是层次结构的根,它被命名为_root。 每个面板都有锚、MinSize和MaxSize属性(以及其他一些属性)。但不能直接设置或获取面板的属性;相反,您将使用member metCWndResizer类的hods。 其思想是,当CPanel被调整大小或重新定位时,它的所有子元素也会相对地调整大小和重新定位。 现在,让我们看一些代码片段。 下面的代码将把对话框的OK和Cancel按钮锚定到右下角: 隐藏,复制Code

BOOL CExample1Dlg::OnInitDialog()
{
  CDialog::OnInitDialog();
  BOOL bOk = m_resizer.Hook(this);
  ASSERT(bOk == TRUE);

  bOk = m_resizer.SetAnchor(IDOK, ANCHOR_RIGHT | ANCHOR_BOTTOM);
  ASSERT(bOk == TRUE);

  bOk = m_resizer.SetAnchor(IDCANCEL, ANCHOR_RIGHT | ANCHOR_BOTTOM);
  ASSERT(bOk == TRUE);
}

如果你想创建一个面板并将其锚定属性设置为anchor_horizontal,你可以这样做: 隐藏,复制Code

BOOL CExample1Dlg::OnInitDialog()
{
  CDialog::OnInitDialog();
  BOOL bOk = m_resizer.Hook(this);
  ASSERT(bOk == TRUE);
  CRect rc(40, 40, 240, 240);
  bOk = m_resizer.CreatePanel(_T("MyNewPanel"), &rc);

  bOk = m_resizer.SetAnchor(_T("MyNewPanel"), ANCHOR_HORIZONTALLY);
  ASSERT(bOk == TRUE);

  ASSERT(bOk == TRUE);
}

关于剪切(重要) 此解决方案不能剪切对话框控件的任何部分或面板的任何部分。通常,CPanel对象没有任何与之关联的窗口(HWND)。如果一个子面板比它的父面板大,子面板在父面板外面的区域将是可见的,因为父面板和子面板实际上都不是窗口。为了避免这个问题,我们应该通过调用SetMinimumSize方法为父面板设置一个合理的最小大小,以便父面板永远不会小于子面板的最小大小。您还应该考虑设置挂钩窗口的最小大小,以便它能够包含其客户区域内的所有面板。 使用的代码 在VS2008中创建的示例应用程序演示了这个类的许多特性。 CWndResizer类有以下成员: CreateFlowLayoutPanel CreatePanel CreateSplitContainer GetAnchor GetAutoHandlePaint GetDock GetFixedPanel GetFlowDirection GetFlowItemSpacingX GetFlowItemSpacingYgettissplitterfixed GetMaximumSize GetMinimumSize GetParent GetShowResizeGrip GetShowSplitterGrip Hook invokeonresize SetAnchor SetAutoHandlePaint SetDock SetFixedPanel SetFlowDirection SetFlowItemSpacingX SetFlowItemSpacingY SetIsSplitterFixed SetMaximumSizeSetMinimumSize SetShowResizeGrip SetShowSplitterGrip Unhook 具体内容如下: 方法BOOL CreateFlowLayoutPanel(LPCTSTR panelName, const CRect * prcPanel); BOOL CreateFlowLayoutPanel(LPCTSTR panelName, const CUIntArray * parrID, BOOL setAsChildren = FALSE); Description在挂钩窗口的客户区创建一个流布局面板。净类比)。此面板的唯一名称。稍后将使用此名称引用此面板。在挂钩窗口的客户端坐标中给出的矩形。删除对话框控件id数组。此方法使用此数组中指定的对话框控件的组合区域创建面板。如果这是真的,那么这个方法将为在parrID中指定的每个对话框控件创建面板,并使它们成为自己的子控件。返回值为真。错误的失败。 钩子方法没有被调用。 或者, panelName不是唯一的或者是空的。 或者, parrID包含一个无效的ID。 FlowLayout面板将其内容按水平或垂直流向排列。它的内容可以从一行包装到下一行,或者从一列包装到下一列。 您可以通过调用SetFlowDirection方法的值来指定流方向。 其他面板可以是FlowLayout面板的子面板。有了这个功能,您就可以在运行时构建适合对话框尺寸的复杂布局。 方法BOOL CreatePanel(LPCTSTR panelName, const CRect * prcPanel); BOOL CreatePanel(LPCTSTR panelName, const CUIntArray * parrID, BOOL setAsChildren = FALSE); BOOL CreatePanel(使用UINT panelID); Description在挂钩窗口的客户区创建一个面板。此面板的唯一名称。稍后将使用此名称引用此面板。在挂钩窗口的客户端坐标中给出的矩形。删除对话框控件id数组。此方法使用此数组中指定的对话框控件的组合区域创建面板。如果为真,那么该方法将为parrID中指定的每个对话框控件创建面板,并将它们作为自己的子控件。对话框控件的ID。返回值为真。错误的失败。 钩子方法没有被调用。 或者, panelName不是唯一的或者是空的。 或者, parrID包含一个无效的ID。 或者, panelID是无效的。 面板创建后,默认情况下会有以下初始设置: 父名:_T("_root") Anchor: ANCHOR_LEFT | ANCHOR_TOP Dock: DOCK_NONE MinimumSize: cx = 10, cy = 10 MaximumSize: cx = 100000, cy = 100000 关于BOOL CreatePanel(UINT panelID): 通常可以对ActiveX或OLE控件使用此重载方法。通过这个重载方法创建的面板将使用MoveWindow API重新调整大小/定位。对于其他面板,CWndResizer使用BeginDeferWindowPos、DeferWindowPos和EndDeferWindowPos来调整UI控件的大小/位置。 注意:当对话框控件第一次被引用时,CWndResizer会在内部为对话框控件创建面板。 关于BOOL CreatePanel(LPCTSTR panelName, const CUIntArray * parrID, BOOL setAsChildren = FALSE): 这种方法可以作为一些技术的捷径。假设您有一个非常简单的对话框,只有OK和Cancel按钮,并且您想在底部锚定这两个按钮-右下角的对话框,然后你可以做以下三种技术中的任何一种来实现这个: 技巧1: 隐藏,Codem_resizer副本。SetAnchor(IDOK, ANCHOR_RIGHT | ANCHOR_BOTTOM); m_resizer。SetAnchor(IDCANCEL, ANCHOR_RIGHT | ANCHOR_BOTTOM) 技巧2: 隐藏,复制CodeCRect rcArea;//两个按钮的组合区域 绘图用的矩形类rcBtn;//区域的单个按钮 GetDlgItem (IDOK)→GetWindowRect(及rcBtn); rcArea.UnionRect(及rcArea, rcBtn); GetDlgItem (IDCANCEL)→GetWindowRect(及rcBtn); rcArea.UnionRect(及rcArea, rcBtn); ScreenToClient(及rcArea); //创建面板 m_resizer.CreatePanel (_T(“My_OK_Cancel_Panel”),rcArea); //将按钮设置为新创建面板的子元素 m_resizer。SetParent (IDOK _T (My_OK_Cancel_Panel ")); m_resizer。SetParent (IDCANCEL _T (My_OK_Cancel_Panel ")); //设置新创建的面板的锚 m_resizer.SetAnchor (_T(“My_OK_Cancel_Panel”), ANCHOR_RIGHT | ANCHOR_BOTTOM); 技巧3: 隐藏,CodeCUIntArray arrID复印件; arrID.Add (IDOK); arrID.Add (IDCANCEL); m_resizer.CreatePanel (_T(“My_OK_Cancel_Panel”), , arrID,真正的); m_resizer.SetAnchor (_T(“My_OK_Cancel_Panel”), ANCHOR_RIGHT | ANCHOR_BOTTOM); 技术2和技术3产生了完全相同的面板层级。但是技巧3比技巧2短得多。 方法BOOL CreateSplitContainer(LPCTSTR splitContainerName, LPCTSTR panelNameA, LPCTSTR panelNameB); BOOL CreateSplitContainer(LPCTSTR splitContainerName, LPCTSTR panelNameA, UINT panelIDB); BOOL CreateSplitContainer(LPCTSTR splitContainerName, UINT panelIDA, UINT panelIDB); BOOL CreateSplitContainer(LPCTSTR splitContainerName, UINT panelIDA, LPCTSTR panelNameB); 描述创建一个分割容器(。净类比)。参数splitContainerName这个分割容器的唯一名称。稍后将使用此名称引用此面板。panelnama面板的名称,该面板是由之前调用CWndResizer::CreatePanel或CWndResizer::CreateSplitContainer创建的。 如果结果面板是水平拆分容器,则这指的是拆分容器的左侧面板。否则,它就是分割容器的顶部面板。 嵌套窗口的子控件(窗口)的ID。 如果结果面板是水平拆分容器,则这指的是拆分容器的左侧面板。否则,它就是分割容器的顶部面板。 之前调用CWndResizer::CreatePanel或CWndResizer::CreateSplitContainer创建的面板的名称。 如果结果面板是水平拆分容器,则这指的是拆分容器的右面板。否则,它是拆分容器的底部面板。 嵌套窗口的子控件(窗口)的ID。 如果结果面板是水平拆分容器,则这指的是拆分容器的右面板。否则,它是拆分容器的底部面板 返回值为真。错误的失败。 钩子方法没有被调用。 或者, splitContainerName, panelNameA, panelIDA, panelNameB或panelIDB不是唯一的或为空。 或者, 指定的面板(矩形)重叠。 或者, 一个或所有指定的面板已经用于创建分割容器。 CWndResizer决定了分割容器应该是水平的还是垂直的。 如果第一个矩形的右成员(第二个参数)小于第二个矩形的左成员(第三个参数),此方法将创建一个水平分割容器。否则,如果第一个矩形的底部成员(第二个参数)小于第二个矩形的顶部成员(第三个参数),此方法将创建一个垂直分割容器。 CSplitContainer的定义 CSplitContainer由两个csplitpanel和一个CSplitterPanel组成。CSplitterPanel包含CSplitterGripperPanel。 如果您将鼠标移动到CSplitContainer的两个面板(CSplitPanel)之间的空间(CSpitterPanel)上,鼠标指针将会改变。然后您可以按下鼠标左键并拖动来调整面板的大小。如果面板的父面板调整了大小,则拆分器面板的两个面板将按比例调整大小。 方法BOOL GetAnchor(LPCTSTR panelName, UINT &锚); UINT panelID, UINT &锚); Description获取指定面板的锚(。净类比)。参数panelName先前调用CWndResizer::CreatePanel创建的面板的名称。钩窗的子控件(窗口)的ID。锚接收锚值。返回值为真。锚包含一个有效值。错误的失败。锚值应该被忽略。 钩子方法没有被调用。 或者, panelName或panelID无效。 备注检索面板的锚定值。详情请参阅SetAnchor。BOOL GetAutoHandlePaint()方法; 描述获取CWndResizer是否应该自动处理油漆。返回值为真。锚包含一个有效值。错误的失败。锚值应该被忽略。 钩子方法没有被调用。 或者, panelName或panelID无效。 备注详情请参阅SetAutoHandlePaint。方法GetDock(LPCTSTR panelName, UINT &uDock); UINT panelID, UINT &uDock); Description获取指定面板的锚(。净类比)。参数panelName先前调用CWndResizer::CreatePanel创建的面板的名称。钩窗的子控件(窗口)的ID。uDock接收dock值。返回值为真。锚包含一个有效值。错误的失败。锚值应该被忽略。 钩子方法没有被调用。 或者, panelName或panelID无效。 备注检索面板的停靠值。详细信息请参见SetDock。方法BOOL GetFixedPanel(LPCTSTR splitContainer, short &面板);Description获取固定面板的名称(如果有的话)。净类比)。参数splitContainerName分割容器的名称,该分割容器是由之前调用CWndResizer创建的::CreateSplitContainer。面板接收固定面板的ID。如果它包含1,那么左侧面板(如果splitContainer是一个垂直分隔容器,则顶部面板)是固定的;如果它是2,则右侧面板(如果splitContainer是一个垂直分隔容器,则底部面板)是固定的。否则,splitContainer没有固定面板。返回值为真。面板包含一个有效值。错误的失败。面板值应该被忽略。 钩子方法没有被调用。 或者, splitContainerName无效。 备注检索一个分割容器的固定面板ID。有关详细信息,请参见SetSetFixedPanel。方法BOOL GetFlowDirection(LPCTSTR flowPanelName, short &方向);说明获取流面板的流方向(。净类比)。参数flowPanelName分割容器的名称,它是由之前调用CWndResizer创建的::CreateFlowLayoutPanel。方向接收流板的流向。返回值为真。方向包含一个有效值。错误的失败。方向值应该被忽略。 钩子方法没有被调用。 或者, flowPanelName无效。 详细信息请参见SetFlowDirection。方法BOOL GetFlowItemSpacingX(LPCTSTR flowPanelName, int &nSpace);说明获取流面板中x方向项之间的间距。参数flowPanelName分割容器的名称,它是由之前调用CWndResizer创建的::CreateFlowLayoutPanel。nSpace接收以像素为单位的空间。返回值为真。面板包含一个有效值。错误的失败。nSpace值应该被忽略。 钩子方法没有被调用。 或者, flowPanelName无效。 详情请参见SetFlowItemSpacingX。方法BOOL GetFlowItemSpacingY(LPCTSTR flowPanelName, int &nSpace);说明获取流面板中y方向项之间的间距。参数flowPanelName分割容器的名称,它是由之前调用CWndResizer创建的::CreateFlowLayoutPanel。nSpace接收以像素为单位的空间。返回值为真。面板包含一个有效值。错误的失败。nSpace值应该被忽略。 钩子方法没有被调用。 或者, flowPanelName无效。 详情请参见SetFlowItemSpacingY。方法BOOL GetIsSplitterFixed(LPCTSTR splitContainerName, BOOL &fixed);描述获取拆分容器的拆分器是否被设置为固定(。净类比)。参数splitContainerName分割容器的名称,该分割容器是由之前调用CWndResizer创建的::CreateSplitContainer。固定接收布尔值。如果这是真的,那么分割器是固定的;否则,拆分器可以由鼠标自由移动。返回值为真。固定包含一个有效的值。错误的失败。固定值应该被忽略。 钩子方法没有被调用。 或者, splitContainerName无效。 备注检索一个标志,该标志指示拆分容器的拆分器是否可以由鼠标自由移动。有关详细信息,请参见SetIsSplitterFixed。方法BOOL GetMaximumSize(LPCTSTR panelName, CSize &大小); (UINT panelID, CSize &大小); Description获取指定面板的最大大小(。净类比)。参数panelName先前调用CWndResizer::CreatePanel创建的面板的名称。钩窗的子控件(窗口)的ID。返回值为真。size包含有效值。错误的失败。大小值应该被忽略。 钩子方法没有被调用。 或者, panelName或panelID无效。 如果panelName或panelID引用的面板是水平分割容器的一部分,则CSize::cy成员应被忽略。如果panelName或panelID指的是panel是垂直分割容器的一部分,那么CSize::cx成员应该被忽略。方法BOOL GetMinimumSize(LPCTSTR panelName, CSize &大小); (UINT panelID, CSize &大小); Description获取指定面板的最小大小(。净类比)。参数panelName先前调用CWndResizer::CreatePanel创建的面板的名称。钩窗的子控件(窗口)的ID。返回值为真。size包含有效值。错误的失败。大小值应该被忽略。 钩子方法没有被调用。 或者, panelName或panelID无效。 如果panelName或panelID引用的面板是水平分割容器的一部分,则CSize::cy成员应被忽略。如果panelName或panelID引用的面板是一个垂直分离容器的一部分,那么CSize::cx成员应被忽略。方法BOOL GetParent(LPCTSTR panelName, CString &parentName); UINT panelID, CString &parentName); Description获取指定面板的父面板的名称。参数panelName先前调用CWndResizer::CreatePanel创建的面板的名称。钩窗的子控件(窗口)的ID。parentName接收父节点的名称。返回值为真。parentName包含一个有效值。错误的失败。大小值应该被忽略。 钩子方法没有被调用。 或者, panelName或panelID无效。 如果parentName是_root,则说明该面板是挂钩窗口的直接子窗口。BOOL GetShowResizeGrip()方法;如果在挂钩窗口的右下角绘制了一个调整大小的手柄,说明将显示一个标志指示。无参数。它将在对话框/窗口的右下角绘制一个调整大小的手柄。FALSE它不会在对话框/窗口的右下角绘制一个调整大小的手柄。这个方法永远不会失败。方法BOOL GetShowSplitterGrip(LPCTSTR splitContainerName, BOOL &bShow);描述获取拆分容器的拆分柄是否可见。参数splitContainerName分割容器的名称,该分割容器是由之前调用CWndResizer创建的::CreateSplitContainer。bShow接收一个布尔值。如果这是真的,那么splitter抓地力是可见的,否则splitter抓地力是隐藏的。返回值为真。错误的失败。bShow值应该被忽略。 钩子方法没有被调用。 或者, splitContainerName无效。 N/A方法BOOL Hook(CWnd * pWnd);描述在WndProc链中放置了一个钩子。参数pWnd一个指向要调整大小的CWnd及其子控件的指针。返回值为真。错误的失败。 pWnd无效。 或者, 此方法已经被调用过一次。 您必须在调用任何其他方法之前调用此方法。 pWnd指向的窗口称为“挂钩窗口”。 BOOL InvokeOnResized()方法;描述模拟挂钩窗口的大小调整。无参数。返回值为真。错误的失败。 钩子方法没有被调用。 这个方法发送一个WM_SIZE消息到挂钩窗口。 在创建了必要的面板和设置锚点之后,您可能希望调用它来初始应用设置。 方法BOOL SetAnchor(LPCTSTR panelName, UINT &锚); UINT panelID, UINT &锚); Description设置指定面板的锚(。净类比)。参数panelName先前调用CWndResizer::CreatePanel创建的面板的名称。钩窗的子控件(窗口)的ID。锚锚值。看到评论。返回值为真。锚包含有效值。错误的失败。 钩子方法没有被调用。 或者, panelName或panelID无效。 讲话锚可以下列一个或多个: 锚值描述ANCHOR_LEFT锚其母面板的左边缘。这是默认的面板。ANCHOR_TOP锚其母面板的顶部边缘。这是默认的面板。ANCHOR_RIGHT锚板的右边缘其母。ANCHOR_BOTTOM锚板的底部边缘。ANCHOR_CENTER_HORIZONTALLY父矩形内的面板水平居中。它有更高的优先级比ANCHOR_ALL。net没有类似的支持。ANCHOR_CENTER_VERTICALLY父矩形内的面板垂直居中。它有更高的优先级比ANCHOR_ALL。net没有类似的支持。如果使用ANCHOR_HORIZONTALLY ANCHOR_PRIORITY_RIGHT这仅仅是有用的。如果面板的宽度大于允许的最大宽度,默认情况下,面板的左边缘将锚定并右边缘将释放适应的最大大小。如果这是指定的,那么右边缘将锚定并左边缘将释放适应的最大大小。net没有类似的支持。如果使用ANCHOR_VERTICALLY ANCHOR_PRIORITY_BOTTOM这仅仅是有用的。如果面板的高度增长大于允许的最大高度,默认情况下,面板的上边缘固定和底部边缘会被释放到适应的最大大小。如果这是指定的,那么底部边缘将锚定并顶部边缘将释放适应的最大大小。net没有类似的支持。ANCHOR_VERTICALLY (ANCHOR_TOP | ANCHOR_BOTTOM) ANCHOR_HORIZONTALLY (ANCHOR_LEFT | ANCHOR_RIGHT) ANCHOR_ALL (ANCHOR_VERTICALLY | ANCHOR_HORIZONTALLY) 注意:一个面板永远长不到其允许的最小大小,超过允许的最大尺寸。 方法BOOL SetAutoHandlePaint (BOOL bHandle); 描述集涂料是否应该被CWndResizer自动处理。参数bHandle真实如果CWndResizer自动处理WM_PAINT消息。否则错误。返回值真总是返回TRUE假永远不会返回FALSE。她的讲话e就是一个例子: 隐藏,收缩,复制CodeBOOL CTestDlg: OnInitDialog () { CDialog: OnInitDialog (); BOOL bOk = FALSE; 博克= m_resizer.Hook(这个); 断言(博克); //关闭自动油漆手柄 m_resizer.SetAutoHandlePaint(假); m_resizer.SetShowResizeGrip(真正的); 博克= m_resizer.InvokeOnResized (); 断言(博克); 返回TRUE; } 空白CTestDlg: OnPaint () { CPaintDC直流(这个);//绘制的设备上下文 //你的自定义图 rect(10, 20, 60, 60); CBrush刷(RGB (0, 0, 0)); 直流。FillRect(矩形和刷); //调用CWndResizer::Draw方法,使它可以绘制 //任何从CVisualPanel派生的类 m_resizer.Draw(及直流);// <=调用绘制方法 } 方法SetDock(LPCTSTR panelName, UINT &uDock); UINT panelID, UINT &uDock); 描述设置指定面板的停靠(。净类比)。参数panelName先前调用CWndResizer::CreatePanel创建的面板的名称。钩窗的子控件(窗口)的ID。uDock码头的价值。看到评论。返回值为真。错误的失败。 钩子方法没有被调用。 或者, panelName或panelID无效。 uDock可以是下列之一: DOCK_NONE面板将不会被停靠。这是默认的面板。DOCK_LEFT面板将停靠在其父面板的左边缘。DOCK_TOP面板将停靠在其父面板的上边缘。DOCK_RIGHT面板将停靠在其父面板的右边缘。DOCK_BOTTOM面板将停靠在其父面板的下边缘。 方法BOOL SetFixedPanel(LPCTSTR splitContainerName, short panel);说明将拆分容器的一个面板设置为固定(。净类比)。参数splitContainerName:先前调用CWndResizer创建的面板的名称::CreateSplitContainer。固定面板的面板ID。如果它包含1,那么左侧面板(如果splitContainer是一个垂直分隔容器,则顶部面板)是固定的;如果它是2,则右侧面板(如果splitContainer是一个垂直分隔容器,则底部面板)是固定的。否则,splitContainer没有固定面板。返回值正确成功了。错误的失败。 钩子方法没有被调用。 当挂钩窗口调整大小时,固定面板保持不变,而其他面板调整大小。 注意:一个面板永远长不到其允许的最小大小,超过允许的最大尺寸。 方法BOOL SetFlowDirection(LPCTSTR flowPanelName, short direction);描述设置流面板的流向(。净类比)。参数flowPanelName分割容器的名称,它是由之前调用CWndResizer创建的::CreateFlowLayoutPanel。流板的流向。返回值为真。错误的失败。 钩子方法没有被调用。 或者, flowPanelName无效。 将方向设置为1表示从左到右的方向,其他任何值将表示从上到下的方向。方法BOOL SetFlowItemSpacingX(LPCTSTR flowPanelName, int nSpace);说明设置流面板中x方向项之间的间距。参数flowPanelName分割容器的名称,它是由之前调用CWndResizer创建的::CreateFlowLayoutPanel。nSpace,空间单位是像素。返回值为真。错误的失败。nSpace值应该被忽略。 钩子方法没有被调用。 或者, flowPanelName无效。 如果流的方向是从左到右,nSpace表示x方向上两个项目之间的空格,否则表示项目的两列之间的空格。方法BOOL SetFlowItemSpacingY(LPCTSTR flowPanelName, int &nSpace);说明获取流面板中y方向项之间的间距。参数flowPanelName分割容器的名称,它是由之前调用CWndResizer创建的::CreateFlowLayoutPanel。nSpace,空间单位是像素。返回值为真。错误的失败。nSpace值应该被忽略。 钩子方法没有被调用。 或者, flowPanelName无效。 如果流的方向是从左到右,nSpace表示y方向上两个项目之间的空格,否则表示两行项目之间的空格。方法BOOL SetIsSplitterFixed(LPCTSTR splitContainerName, BOOL fixed);描述设置拆分容器的拆分器是否被设置为固定(。净类比)。参数splitContainerName分割容器的名称,该分割容器是由之前调用CWndResizer创建的::CreateSplitContainer。固定一个布尔值。如果这是真的,那么拆分器是固定的,否则拆分器是自由移动的鼠标。返回值为真。错误的失败。 钩子方法没有被调用。 如果拆分器被设置为固定,用户不能使用鼠标移动拆分器。方法BOOL SetMaximumSize(LPCTSTR panelName, CSize &大小); (UINT panelID, CSize &大小); 描述设置指定面板的最大尺寸(。净类比)。参数panelName先前调用CWndResizer::CreatePanel创建的面板的名称。钩窗的子控件(窗口)的ID。面板的最小尺寸。返回值为真。错误的失败。 钩子方法没有被调用。 或者, size小于CWndResizer::GetMinimumSize。 如果panelName或panelID引用的面板是水平分割容器的一部分,则应忽略cy成员的大小。如果panelName或panelID指的是一个面板,该面板是一个垂直分离容器的一部分,那么cx成员的大小应该被忽略。方法SetMinimumSize(LPCTSTR panelName, CSize &大小); (UINT panelID, CSize &大小); 描述设置指定面板的最小尺寸(。净类比)。参数panelName先前调用CWndResizer::CreatePanel创建的面板的名称。钩窗的子控件(窗口)的ID。返回值为真。错误的失败。 钩子方法没有被调用。 或者, panelName或panelID无效。 如果panelName或panelID引用的面板是水平分割容器的一部分,则应忽略cy成员的大小。如果panelName或panelID指的是一个面板,该面板是一个垂直分离容器的一部分,那么cx成员的大小应该被忽略。方法BOOL SetParent (LPCTSTR panelName, LPCTSTR parentName); BOOL SetParent(使用UINT panelID LPCTSTR parentName); BOOL SetParent (LPCTSTR panelName,使用UINT parentID); BOOL SetParent(使用UINT panelID使用UINT parentID); 描述集的母公司的名称指定的面板。参数panelName名称的前面板是由一个叫CWndResizer:: CreatePanel。panelID子控件的ID hooked-window(窗口)。parentID母公司的名称。parentName母公司的名称。返回值真的成功了。parentName包含一个有效值。错误的失败。大小值应该被忽略。 CWndResizer::钩方法没有被调用。 或者, panelName、panelID parentName或parentName无效。 评论这个不应该被认为是Win32 SetParent API。 设置parentName _root表明,面板是立即hooked-window的孩子。 方法空白SetShowResizeGrip (BOOL显示= TRUE);描述设置一个标志指示如果调整控制将hooked-window的右下角。参数显示正确,如果调整控制应该吸引,否则错误的。返回值N /无返回值。评论这个方法从未失败。方法BOOL SetShowSplitterGrip (LPCTSTR splitContainerName BOOL bShow);描述设置一个标志指示是否显示或隐藏爪分离器的分离容器。参数splitContainerName分离容器的名称之前,是由一个叫CWndResizer:: CreateSplitContainer。bShow真实如果调整控制应该吸引,否则隐藏。返回值真的成功了。错误的失败。 CWndResizer::钩方法没有被调用。 或者, splitContainerName是无效的。 评论这个方法从未失败。BOOL解开()方法;参数N /一个没有参数。返回值真的成功了。错误的失败。 CWndResizer::钩方法没有被调用。 的话你不需要调用这个方法。 当挂钩窗口收到WM_DESTROY消息时,会自动调用这个方法。 的兴趣点 这个解不需要你计算任何数字。此解决方案封装了CWndResizer中的所有功能。 可以重新设计它,使它暴露其他对象(CPanel、CSplitContainer等)。我这样设计它的原因是我不想让用户知道太多的对象,并简化内存分配和释放。 另一件事是它依赖于MFC类(CWnd等);同样,您可以删除所有对MFC类的引用,并使用纯Win32 api。 历史 2011年1月13日:文章更新,包括新特性,对接和FlowLayoutPanel 2011年2月25日:CWndResizer:解开方法改变按成员2272507的评论2011年3月16日:更新演示和源代码2011年5月23日:更新演示和源代码1 2011年8月:演示和源代码2011年8月17日更新:更新演示和源代码,现在支持滚动CFormView 7 2011年12月:演示和源代码2013年1月25日更新:新的例子添加(11例)和一个bug修正2013年6月28日:2013年11月9日更新的源代码:用户报告错误9例子是固定在2014年10月20日:添加三个新方法:画(CPaintDC * pDC), GetAutoHandlePaint()和SetAutoHandlePaint (BOOL bHandle)。当你有了自定义的绘画时,这些会很有帮助。有关详细信息,请参阅上面的文档。2014年10月20日:修复报告的bug 本文转载于:http://www.diyabc.com/frontweb/news5209.html

posted @ 2020-08-09 13:31  Dincat  阅读(313)  评论(0编辑  收藏  举报