对话框管理器第三章创建控件
和上一篇创建框架窗口相比,创建控件的工作要轻松很多,信不信由你。
在对话框模板中定义的每一个控件,其对应的子窗口将会被创建。控件的大小和位置在模板中是以DLU为单位来描述的,所以,理所当然的,我们需要将它们转换为以像素单位,代码如下:
intxXDLU2Pix(ItemTemplate。x);
intyYDLU2Pix(ItemTemplate。y);
intcxXDLU2Pix(ItemTemplate。cx);
intcyYDLU2Pix(ItemTemplate。cy);
控件类名和标题也来自于模板。还有一些可选的额外字节pExtra没有人使用,但由于历史原因保留在模板定义中。一旦收集了这些信息,就该制作甜甜圈了。
HWNDhwndChildCreateWindowEx(
ItemTemplate。dwExStyleWSEXNOPARENTNOTIFY,
pszClass,pwzCaption,ItemTemplate。dwStyle,
x,y,cx,cy,hdlg,ItemTemplate。dwId,
hinst,pExtra);
请注意,对于对话框控件,WSEXNOPARENTNOTIFY样式是默认启用的。
下一部分经常让人栽跟头。当我尝试创建我的对话框时,它失败了,我不知道为什么。这可能是因为无法创建对话框上的某个控件,通常是因为你忘记为该控件注册窗口类。(例如,您忘记调用InitCommonControlsEx函数或忘记LoadLibrary适当版本的RichEdit控件。)
if(!hwndChild){
DestroyWindow(hdlg);
returnNULL;
}
DSNOFAILCREATE样式禁止了上述失败检查。
但是,如果确实创建了控件,则需要对其进行初始化。
SetWindowContextHelpId(hwndChild,ItemTemplate。dwHelpID);
SetWindowFont(hwndChild,hf,FALSE);
对模板中的每个控件重复上面的步骤后,你现在拥有一个包含所有子控件的对话框。告诉对话过程它可以初始化它的子窗口,如果我们在构建框架时延迟了WSVISIBLE位,则显示(现在准备好的)对话框,并将对话框返回给我们的调用者,此时对话框已准备就绪了。
Thedefaultfocusisthefirstitemthatisavalidtabstop。
HWNDhwndDefaultFocusGetNextDlgTabItem(hdlg,NULL,FALSE);
if(SendMessage(hdlg,WMINITDIALOG,hwndDefaultFocus,lParam)){
SetDialogFocus(hwndDefaultFocus);
}
if(fWasVisible)ShowWindow(hdlg);
returnhdlg;
}
关于SetDialogFocus,我们之前讲过。
至此,你应该明白了对话框是如何创建了。
(实际上,现实情况要复杂得多,因为我跳过了所有应用程序兼容性技巧!例如,有一个程序依赖于细节的设置和WSBORDER样式的缺失来决定控件是组合框还是列表框。我猜GetClassName函数工作量太大了?)
我希望这可以帮助你更好地理解对话模板是如何工作的。总结
描述性语言,是程序开发者和操作系统之间的一种十分友好的沟通方式。
就好比COM时代的IDL(接口描述语言)。最后
RaymondChen的《TheOldNewThing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《Thedialogmanager,part3:Creatingthecontrols》