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

CResizableSheet 和 CResizablePage

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (19投票s)

2000年7月28日

CPOL
viewsIcon

414845

downloadIcon

8716

使用 MFC 实现可调整大小的属性表或向导对话框的两个 CPropertySheet/CPropertyPage 派生类

CResizableSheet(Ex) 和 CResizablePage(Ex)

这四个类处理可调整大小的属性表、向导以及 Wizard 97 风格的对话框,并且现在完全基于我的 ResizableLib 类库(请参阅文章)。

用户将能够调整对话框的大小,并随之重新排列子窗口。您可以控制允许的最小和最大尺寸,以及对话框的最大尺寸和位置。默认情况下会显示尺寸调整手柄,但您可以将其关闭。同时还支持自动保存/恢复对话框的大小和位置,以及活动页面。

转换以前存在的属性表或向导应该非常简单。

在本文的其余部分,我将讨论非 Ex 类,但同样的概念也适用于 Wizard 97 对话框。

示例应用程序

这是属性表和向导模式下示例对话框在最小尺寸时的视图

Property sheet with smaller size and proportional resizing Wizard mode with help button and minimal size

请注意,最小宽度不是默认值。您可以在下一节中看到如何实现这一点。

这是 Visual C++ 附带的 Wizard97 示例项目可调整大小版本的屏幕截图。

A resizable Wizard 97 dialog

用法 - 分步指南

ResizableLib 添加到您的项目工作区,具体说明请参阅相关文章

创建一个属性表或向导对话框,并将其与 MFC 类进行关联,例如使用属性表组件,或者使用您已有的要使其可调整大小的对话框。您无需更改任何窗口样式即可实现对话框的调整大小。

在属性表关联的头文件中包含 'ResizableSheet.h'。

在您的 .cpp 和 .h 文件中搜索并替换所有 CPropertySheet 的出现项为 CResizableSheet,就好像您的属性表类是从 CResizableSheet 而不是 CPropertySheet 派生的。

在属性页关联的头文件中包含 'ResizablePage.h'。

在您的 .cpp 和 .h 文件中搜索并替换所有 CPropertyPage 的出现项为 CResizablePage,就好像您的属性页类是从 CResizablePage 而不是 CPropertyPage 派生的。

当然,这同样适用于向导对话框。

您的属性表头文件应如下所示

// MyPropertySheet.h : header file
//

#include "MyPropertyPages.h"

/////////////////////////////////////////////////////////////////////////////
// CMyPropertySheet

#include "ResizableSheet.h"

class CMyPropertySheet : public CResizableSheet
{
    DECLARE_DYNAMIC(CMyPropertySheet)

// Construction
public:
    CMyPropertySheet(CWnd* pWndParent = NULL);

// ( other stuff )
// ...
}

在您的 OnInitDialog 重写中,您可以更改属性表的初始设置,例如最小尺寸和自动保存/恢复,还可以选择性地设置活动页面。

BOOL CMyPropertySheet::OnInitDialog() 
{
    CResizableSheet::OnInitDialog();
    
    // set minimal size
    CRect rc;
    GetWindowRect(&rc);

    SetMinTrackSize(CSize(GetMinWidth(), rc.Height()));

    // enable save/restore, with active page
    EnableSaveRestore(_T("Properties"), TRUE, TRUE);

    return TRUE;
}

您的属性页头文件应如下所示

// MyPropertyPages.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CMyPropertyPage1 dialog

#include "ResizablePage.h"

class CMyPropertyPage1 : public CResizablePage
{
    DECLARE_DYNCREATE(CMyPropertyPage1)
// ...
}

// and so on for the other pages ...

在每个页面的 OnInitDialog 重写中,您只需要为控件设置布局。您可以通过水平/垂直百分比或使用预定义常量指定将控件的左上角和右下角附加到哪里。

BOOL CMyPropertyPage2::OnInitDialog() 
{
    CResizablePage::OnInitDialog();
    
    // preset layout
    AddAnchor(IDC_LIST1, TOP_LEFT, CSize(50,70));
    AddAnchor(IDC_PICTURE1, CSize(50,0), CSize(100,70));
    AddAnchor(IDC_GROUP1, CSize(0,70), BOTTOM_RIGHT);
    AddAnchor(IDC_CHECK1, CSize(0,85));
    AddAnchor(IDC_RADIO1, CSize(100,85));
    AddAnchor(IDC_COMBO1, CSize(100,70));
    AddAnchor(IDC_BUTTON1, BOTTOM_RIGHT);

    m_ctlEdit1.AddString(_T("Just a single item to test the "
        "listbox behavior with very long lines..."));
    m_ctlEdit1.SetHorizontalExtent(300);

    return TRUE;
}

您现在可以重新构建项目,并获得一个可调整大小的属性表或向导对话框,就像您想要的那样。

有关更多详细信息,请参阅下一节。

类参考

属性表类继承自 CResizableLayoutCResizableGripCResizableMinMaxCResizableState,以及 CPropertySheet 本身。

属性页类继承自 CResizableLayout,以及 CPropertyPage 本身。其他类则不需要。

CResizableSheet::CResizableSheet

CResizableSheet()
CResizableSheet(UINT nIDTemplate, CWnd* pParentWnd = NULL)
CResizableSheet(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL)

CResizablePage::CResizablePage

CResizablePage()
CResizablePage(UINT nIDTemplate, CWnd* pParentWnd = NULL)
CResizablePAge(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL)

第一种形式是默认构造函数。

第二种和第三种形式是重现 CPropertySheet/Page 派生类的构造方案所必需的。由于 CPropertySheet/Page 构造函数需要对话框资源模板,因此您必须调用 CResizableSheet/Page 构造函数的其中一种形式。这就是将一个类替换为另一个类能够工作的原因。

CResizableSheet::EnableSaveRestore

void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly, BOOL bWithPage = FALSE)

启用对话框打开/关闭操作上的自动保存/恢复。第一个参数与 CWinApp::WriteProfileString 中的相同。如果 bRectOnlyTRUE,则不保存/恢复最小化/最大化状态。最后一个参数是用于恢复活动页面的标志(活动页面始终被保存)。应在所有布局设置之后调用。

如果您想了解这些设置如何存储的详细信息,请查阅 MFC 文档中的 CWinApp::SetRegistryKeyCWinApp::m_pszProfileNameCWinApp::m_pszRegistryKey

CResizable???::???

已在各种基类中实现,请参阅ResizableLib文章。

设置/重置最大化尺寸和位置的成员函数似乎没什么用处,因为窗口标题栏中没有最大化按钮。我保留它们是因为我认为有可能通过调整窗口样式来启用标题栏按钮。

结论

我希望这些类能让一些程序员的生活稍微轻松一些。我还要感谢 Jerzy Kaczorowski 在将 CResizableDialog 代码移植到属性表过程中提供的独特支持。

ResizableLib 的集成现已完成。这需要部分重写,但我希望它能受益于库中进行的所有改进(以及 bug 修复)。

CVS 树现在位于Source Forge

更新

2000 年 7 月 28 日

首次公开发布。

2000 年 10 月 27 日

修复了堆叠标签的 bug。
需要刷新的控件现在可以正确显示。
CArray 替换了内部结构。

2001 年 3 月 13 日

修复了单选按钮和组合框的 bug(感谢 Matt Philmon)
更改了版权声明

2001 年 6 月 11 日

新的实现和与 ResizableLib 的集成

2001 年 7 月 15 日

更新到新的 ResizableLib 版本
与库的完全集成,现在使用新的回调锚点
增加了对 'Wizard 97' 风格对话框的支持

2001 年 10 月 28 日

版本 1.1 (CVS 标签: SF_1_1)
修复了在向导对话框中导航时按 CTRL+Tab 的 bug
为所有项目添加了静态构建配置
CResizableSheet 和 CResizablePage - CodeProject - 代码之家
© . All rights reserved.