关于Windows:Win32:CreateDialog而不是对CreateWindow的多次调用-有何缺点?

Win32: CreateDialog instead of multiple calls to CreateWindow - any downsides?

我目前正在使用Win32程序,该程序需要一个包含许多子窗口控件(按钮,列表视图等)的主窗口。 我相信构建此类窗口的标准方法是先为主窗口调用CreateWindow,然后再为每个控件调用。

作为一个更简单的选择,我正在考虑使用资源编辑器的对话框设计器设计主窗口,然后使用CreateDialog一次性构建主窗口。

通过在对话框模板中使用CLASS语句,我应该能够使主窗口使用自定义窗口类(以及自定义窗口过程),从而避免该窗口具有任何类似于对话框的行为。 可在Charles Petzold的" Programming Windows"(编程Windows)中找到该技术的示例:第11章中的HEXCALC程序。

以这种方式创建我的主窗口是否有不利之处? 如果是这样,它们是什么? 如果没有,为什么很少使用这种方法?


您无法控制主窗口消息循环-对话框管理器会为您处理它。另一方面,对话框管理器处理键盘加速器,选项卡排序和许多其他效果。

您会惊讶于使用标准对话框可以执行的操作-Windows音量控制由大约四个不同的对话框实现-它具有框架对话框,而主机又托管一个托盘窗口,该托盘窗口又包含音量控制对话框,每个应用量一个。


我知道的CreateDialog的唯一缺点(与重复的CreateWindow相比,不谈论某些重量级框架,仅是Win32 vs Win32)是对话框资源使用对话框单元定位子窗口。因此,布局不仅取决于DPI,而且还取决于用户的主题设置(字体的选择和大小)。

如果您的任何控件都需要具有固定的像素大小,那么您将对对话框提供的定位不满意,并且需要在事件结束后浏览并移动所有子窗口。

所以可以,您可以使用CreateDialog作为创建具有指定类和样式的窗口的快捷方式。但是不,您不能在对话框编辑器中进行布局。

OTOH,您可以存储设计机器上使用的DLU <->像素转换,然后了解足够的信息来分析DIALOG资源内部格式以提取定位信息,然后转换为像素并以更自动化的方式校正定位。


即使窗口是使用CreateDialog创建的,您也将拥有对窗口的完全控制权。

通常,当您创建自己的窗口(属于您的类)时,所使用的窗口过程就是您向该类注册的过程。通过CreateDialog创建的OTOH窗口将具有对话框标准窗口过程(DefDlgProc),该过程将主要调用您提供的"对话框处理程序"。

如果要完全控制所有消息,则可以在创建新窗口后立即替换其窗口进程。只需使用GWLP_WNDPROC参数调用SetWindowLongPtr。尽管如此,您仍可以通过在过程中调用IsDialogMessage来自动处理某些特定于对话框的内容。


没有任何缺点。

为什么很少使用?因为:

  • 人们通常使用DialogBox代替,因为在更简单的情况下这更容易。

  • 对于更复杂的情况,人们使用诸如MFC或ATL之类的东西(或诸如GTk或Qt之类的某些外部库)之类的东西,而不必理会本机Win32图形。


使用Windows SDK没有缺点,而MFC之类的内部库则使用Windows SDK。

人们倾向于在Windows SDK上使用像MFC这样的库,因为库中有现成的东西。但是,Windows SDK调用比库调用快,因此在某些情况下,开发人员可以直接调用Windows SDK。

1
2
CButton btnOk ;
btnOK.Create(_T("Press Me"), WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(100,100,300,300), pParentWnd, 1);

与以下代码类似,

1
2
HWND hWnd = CreateWindow("BUTTON","Press Me",WS_CHILD|WS_POPUP|BS_DEFPUSHBUTTON,100,100,300,300,NULL,NULL,GetModuleHandle(NULL),NULL);
ShowWindow(hWnd,SW_SHOW);