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

CResizableDialog

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (51投票s)

2000年5月25日

CPOL
viewsIcon

861718

downloadIcon

15177

一个派生自CDialog的类,用于在MFC中实现可调整大小的对话框

CResizableDialog - 是什么 & 为什么?

我编写了自己的类来实现可调整大小的对话框,这主要是作为MFC和Windows编程的一个练习。后来,我发现其他人也写过类似的类,但我没有找到一个我真正喜欢的,而且像我的小项目那样简单的。

在您继续阅读之前,我必须警告您,我不是“大师”。肯定有些地方可以做得更好,但我认为这个类至少易于使用。

用户将能够调整对话框的大小,并相应地重新排列子窗口,您可以控制允许的最小和最大尺寸,以及对话框的最大化尺寸和位置。大小抓手默认显示,但您可以将其关闭。还支持自动保存/恢复对话框的大小和位置。

转换一个已存在的对话框应该非常简单,创建新的可调整大小的对话框也是如此。

现在已实现 ResizableLib (请参阅文章)。

示例应用程序

这是示例对话框的视图

Default min size is the one in the dialog template (and grip is visible)

Support for colored or bitmap background with a triangular size grip

这是一个组合视图,您可以看到最大化位置不是默认值

A desktop snapshot with the dialog maximized and normal size overimpressed

您可以在下一节中看到如何做到这一点。 

用法 - 分步指南

ResizableLib 添加到您项目的工作空间中,如相关文章中所述。

创建一个对话框资源,并将其与 CDialog 派生类关联,例如使用类向导,或者使用您已有的想要使其可调整大小的对话框。

您不再需要更改窗口样式即可实现对话框的调整大小。

在关联的头文件中包含 'ResizableDialog.h'。

在您的 .cpp.h 文件中,搜索并用 CResizableDialog 替换所有 CDialog 的出现,就像您的对话框类是从 CResizableDialog 而不是 CDialog 派生的一样。我认为没有办法让类向导为您做到这一点。如果我错了,请告诉我。

您的头文件应该如下所示

// MyDialog.h : header file
//
// ( Class Wizard stuff )
/////////////////////////////////////////////////////////////////////////////
// CMyDialog dialog

#include "ResizableDialog.h"
class CMyDialog : public CResizableDialog
{
// Construction
public:
    CMyDialog(CWnd* pParent = NULL);    // standard constructor

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

在您的 OnInitDialog 重载函数中,为每个希望在用户调整对话框大小时更改大小和/或位置的控件添加一个锚点。

BOOL CMyDialog::OnInitDialog()
{
    CResizableDialog::OnInitDialog();

    // Set the icon for this dialog. The framework does this
    // automatically when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);     // Set big icon
    SetIcon(m_hIcon, FALSE);    // Set small icon

    // preset layout
    AddAnchor(IDOK, BOTTOM_RIGHT);
    AddAnchor(IDCANCEL, BOTTOM_RIGHT);
    
    AddAnchor(IDC_SPIN1, TOP_RIGHT);

    AddAnchor(IDC_LABEL1, TOP_LEFT);
    AddAnchor(IDC_EDIT1, TOP_LEFT, BOTTOM_RIGHT);

    AddAnchor(IDC_RADIO1, BOTTOM_LEFT);
    AddAnchor(IDC_RADIO2, BOTTOM_LEFT);
    AddAnchor(IDC_GROUP1, BOTTOM_LEFT, BOTTOM_RIGHT);
    
    // other initializations
    // ...

在这里,您还可以设置对话框的最大尺寸(默认是工作区区域),最小尺寸(默认是在资源编辑器中设置的尺寸),以及对话框最大化时占据的矩形。

// get desktop size
CRect rc;
GetDesktopWindow()->GetClientRect(&rc);

// set max tracking size to half a screen
SetMaxTrackSize(CSize(rc.Width(), rc.Height()/2));

// maximized position and size on top of the screen
rc.bottom = 100;
SetMaximizedRect(rc);

在完成所有这些设置后,您可能希望对话框的大小和位置自动保存和恢复,以及其最大化或最小化状态。只需在应用程序的配置文件中提供一个节和条目名称,以便保存对话框的状态。

// save/restore
// (for dialog based app, default is a .INI file with
// the application's name in the Windows directory)
EnableSaveRestore(_T("DemoDlg"));

您现在可以重新构建您的项目,您将得到一个如您所愿的可调整大小的对话框。

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

类参考

此类继承自 CResizableGripCResizableLayoutCResizableMinMaxCResizableState,以及显然的 CDialog

CResizableDialog::CResizableDialog

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

第一个是默认构造函数。

第二种和第三种形式对于重现 CDialog 派生类的构造方案是必需的。由于 CDialog 构造函数需要对话框资源模板,您必须调用 CResizableDialog 构造函数的这些形式之一。这就是为什么用一个类替换另一个类会起作用的原因。

CResizableDialog::EnableSaveRestore

void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE)

在对话框打开/关闭操作时启用自动保存/恢复。参数与 CWinApp::WriteProfileString 相同。如果 bRectOnlyTRUE,则不保存/恢复最小化/最大化状态。应在所有布局设置之后调用。

如果您想了解有关您的应用程序如何存储这些信息的详细信息,请参阅MFC文档中的 CWinApp::SetRegistryKeyCWinApp::m_pszProfileNameCWinApp::m_pszRegistryKey

CResizable???::???

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

结论

我想让这个类与类向导更加“集成”,但我甚至不知道是否可能。我希望这个类能对其他只想用最少努力实现可调整大小对话框的程序员有所帮助。

我实现了一种比例调整大小的方式。然而,当前可用的锚点类型不允许高度复杂的实现,但在许多应用中应该足够了。如果您需要更多的灵活性,或者您的对话框非常大并且控件很多,您可以在本节的CodeProject中搜索其他解决方案(请参阅文章顶部)。

CVS树现在托管在Source Forge上。

更新

2000年5月25日

  • 首次公开发布

2000年5月31日

  • 已删除一些不必要的代码
  • 减少了 ButtonStaticListBox 控件的闪烁
  • 添加了保存/恢复支持
  • 修复了一个只在无模式对话框中出现的严重bug

2000年6月9日

  • 现在可以在警告级别4下干净地编译
  • 修复了内存泄漏(我完全忘了释放内存)
  • 新的锚定类型,允许更复杂的布局(与之前的代码兼容)
  • 修复了隐藏大小抓手时以及对话框最大化时的bug
  • 更好地处理需要重绘的控件
  • 演示项目已更新以展示新功能

2000年7月11日

  • 修复了保存/恢复函数中的一个小bug。(标准最大化对话框未正确恢复)

2000年10月27日

  • 更改了布局实现(从 CPtrListCArray
  • 修复了需要刷新的控件的bug

2000年11月23日

  • 修复了多次调用 DoModal() 的bug
  • 从zip文件中移除了文档(如果需要,您只需保存此页面即可)

2001年3月13日

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

2001年6月11日

  • ResizableLib 的新实现和集成
  • 自动调整大小样式(感谢John Simmons)
  • 添加了抗闪烁支持

2001年7月15日

  • 更新至新的 ResizableLib 版本
  • 演示项目显示了新的抓手实现

2001年10月28日

  • 版本 1.1 (CVS 标签: SF_1_1)
  • 为所有项目添加了静态构建配置
© . All rights reserved.