WTL CDialogResize 类的使用指南

在众多MFC实现可调整大小对话框的方案中,WTL提供了自己的解决方案,使得开发者只需要学习一种类和一种指定调整大小的方式。本文将概述WTL的调整大小支持,并提供一个示例程序来展示一些特性。

应该已经熟悉WTL以及如何安装它。如果需要帮助,WTL部分有相关文章。

使用 CDialogResize

和其他许多WTL特性一样,首先需要将CDialogResize添加到对话框类的继承列表中。如果使用WTL AppWizard创建一个基于对话框的应用程序,会在此处添加如下代码:

class CMainDlg : public CAxDialogImpl, public CDialogResize { //... };

CDialogResize在atlframe.h中声明,所以如果包含文件中还没有它,请添加该头文件。

接下来,在对话框的OnInitDialog处理程序中初始化CDialogResize代码:

LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { // 初始化CDialogResize代码 DlgResize_Init(); ... }

DlgResize_Init()有一些可选参数,稍后会介绍。

然后,在对话框的消息映射中添加一个条目,将调整大小的消息传递给CDialogResize:

BEGIN_MSG_MAP(CMainDlg) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) ... CHAIN_MSG_MAP(CDialogResize) END_MSG_MAP()

最后,在对话框类中添加一个新的映射,列出对话框中哪些控件将被调整大小:

class CMainDlg : public CAxDialogImpl, public CDialogResize { ... public: BEGIN_DLGRESIZE_MAP(CMainDlg) END_DLGRESIZE_MAP() ... };

将在“设置调整大小映射”部分描述如何填写这个映射。

初始化 CDialogResize

通过调用DlgResize_Init()来初始化CDialogResize。它的原型是:

void CDialogResize::DlgResize_Init( bool bAddGripper = true, bool bUseMinTrackSize = true, DWORD dwForceStyle = WS_THICKFRAME | WS_CLIPCHILDREN);

参数如下:

  • bAddGripper: 控制CDialogResize是否在对话框的右下角添加一个大小框。传递true来添加大小框,或者传递false不添加。
  • bUseMinTrackSize: 此参数控制CDialogResize是否限制对话框的最小大小。如果传递true,对话框不允许被调整到比其初始大小更小(如资源文件中存储的那样)。如果不想限制对话框的最小大小,传递false。
  • dwForceStyle: 指定要应用于对话框的窗口样式。默认值通常足够。

设置调整大小映射

对话框调整大小映射告诉CDialogResize哪些控件需要移动或调整大小。一个条目看起来像这样:

DLGRESIZE_CONTROL(ControlID, Flags)

ControlID是对话框控件的ID。可能的标志及其含义如下:

  • DLSZ_SIZE_X: 当对话框水平调整大小时,调整控件的宽度。
  • DLSZ_SIZE_Y: 当对话框垂直调整大小时,调整控件的高度。
  • DLSZ_MOVE_X: 当对话框水平调整大小时,水平移动控件。
  • DLSZ_MOVE_Y: 当对话框垂直调整大小时,垂直移动控件。
  • DLSZ_REPAINT: 在每次移动/调整大小后使控件无效,以便它每次都重新绘制。

注意不能在同一个维度上移动和调整大小一个控件。如果指定了DLSZ_MOVE_X和DLSZ_SIZE_X,大小标志将被忽略。

也可以将控件分组,使它们彼此成比例地移动和调整大小。稍后将讨论这个话题。

示例项目

本文附带的示例项目是一个简单的基于对话框的应用程序,它作为一个浏览器(使用WebBrowser ActiveX控件)来工作。下面列出了控件ID;稍后讨论移动和调整这些控件大小时,应该参考这个图表。

控件将根据以下规则移动和调整大小:

  • 位置编辑框将水平调整大小。
  • Go、Exit和About按钮将水平移动。
  • Back、Forward、Stop和Refresh按钮将作为一个组水平调整大小。
  • 浏览器控件将水平和垂直调整大小。

浏览器的OnInitDialog()函数像这样初始化CDialogResize:

LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // 初始化CDialogResize代码 DlgResize_Init(); ... }

这使用了DlgResize_Init()的默认参数,结果是一个大小框被添加。此外,对话框不能被调整到比其初始大小更小。这是对话框启动时的样子:

这是调整大小映射,它列出了控件的移动和调整大小行为。注意新的宏BEGIN_DLGRESIZE_GROUP()和END_DLGRESIZE_GROUP() - 它们将四个浏览器控件按钮放入一个调整大小组中。

BEGIN_DLGRESIZE_MAP(CMainDlg) // Location edit box DLGRESIZE_CONTROL(IDC_URL, DLSZ_SIZE_X) // Go, Exit, About buttons DLGRESIZE_CONTROL(IDC_GO, DLSZ_MOVE_X) DLGRESIZE_CONTROL(IDC_EXIT, DLSZ_MOVE_X) DLGRESIZE_CONTROL(ID_APP_ABOUT, DLSZ_MOVE_X) // IE control buttons BEGIN_DLGRESIZE_GROUP() DLGRESIZE_CONTROL(IDC_BACK, DLSZ_SIZE_X) DLGRESIZE_CONTROL(IDC_FORWARD, DLSZ_SIZE_X) DLGRESIZE_CONTROL(IDC_STOP, DLSZ_SIZE_X) DLGRESIZE_CONTROL(IDC_REFRESH, DLSZ_SIZE_X) END_DLGRESIZE_GROUP() // WebBrowser control DLGRESIZE_CONTROL(IDC_BROWSER, DLSZ_SIZE_X|DLSZ_SIZE_Y) END_DLGRESIZE_MAP()

这是调整大小后的对话框:

注意编辑框变宽了,浏览器控件变宽变高了。四个分组按钮的行为有点难以用语言表达,WTL代码由于注释很少,提供的指导有限。但基本思想是:想象一个包围所有四个按钮的边界矩形。那个矩形像任何其他控件一样调整大小,所有按钮按比例调整大小,以便它们保持在边界矩形内。如果按钮要被移动,而不是调整大小,它们会被定位,以便始终保持均匀间隔。注意,一个组中的所有控件应该有相同的DLSZ_*标志,以产生有意义的行为。

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow) { // ... CMainDlg dlgMain; int nRet = dlgMain.DoModal(); _Module.Term(); ::CoUninitialize(); return nRet; } int nRet; { CMainDlg dlgMain; nRet = dlgMain.DoModal(); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485