基于对话框的应用程序与基于SDI和MDI的程序,在程序执行路径上有所不同。对话框的执行路径是:

1.刚开始都是差不多的:_tWinMain——>AfxWinMain——>theApp.InitInstance()

2.接下来有所不同:theApp.InitInstance()——>int nResponse = dlg.DoModal()(注意不是SDI和MDI中的ProcessShellCommand(),——>CreateDlgIndirect()

——>CreateDialogIndirect——>...——>CreateWindowEx().

 

一般的窗口的创建是使用Create函数,这个函数在创建窗口之前调用了PreCreateWindow函数,并且允许在创建创建之前在PreCreateWindow注册一个拥有自定义窗口样式的新的窗口类,来创建一个拥有自定义类名新的窗口。而模式对话框是通过CreateDialogIndirect来创建的,在这当中并没有调用PreCreateWindow函数,重载的PreCreateWindow函数根本就不被执行,因此在这个函数里修改对话框的窗口类是没有用的。
  CDialog是通过CDialog::DoModal()函数创建窗口的,下面是MFC中DoModal函数的代码:  

代码

 在这个函数里先是载入了对话框资源,然后通过LockResource函数,使DLGTEMPLATE类型指针指向相关的内存,然后把这个指针作为参数传递给了CreateDlgIndirect函数(调用了::CreateDialogIndirect)。DLGTEMPLATE的定义如下:

代码
1  typedef struct 
2   DWORD style; 
3   DWORD dwExtendedStyle; 
4   WORD cdit; 
5   short x; 
6   short y; 
7   short cx; 
8   short cy; 
9  }
 DLGTEMPLATE, *LPDLGTEMPLATE; 

我们看看CreateDlgIndirect函数的源码:

代码

函数CreateDialogIndirect在MSDN中的解释为:The CreateDialogIndirect macro creates a modeless dialog box from a dialog box template in memory,意思是他根据对话框模板在内存中创建一个无模的对话框。他是一个API函数,最终也是调用CreateWindowEx实现窗口(对话框)的创建。
  这个结构体保存着创建对话框需要的样式、位置等信息,在DoModal函数里它是通过对话框资源得到的,那对话框资源里一定有它需要的东西。

下面是从rc文件中摘录的对话框的信息:

 

代码
 1  IDD_AAAA_DIALOG DIALOGEX 00320200
 2  STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 3  EXSTYLE WS_EX_APPWINDOW
 4  CAPTION "aaaa"
 5  FONT 9"宋体"
 6  BEGIN
 7   DEFPUSHBUTTON "确定",IDOK,260,10,50,14
 8   PUSHBUTTON "取消",IDCANCEL,260,23,50,14
 9   LTEXT "TODO: 在这里设置对话控制。",IDC_STATIC,50,90,200,8
10  END
11

  第一行是对话框的位置信息,第二行是对话框的样式,第三行是扩展样式,它们的内容就是在对话框编辑器修改属性时得到的内容。
  重载PreCreateWindow的目的不外乎是想在其中修改默认的窗口类的样式信息,然后达到修改窗口样式的目的。而对话框能在资源编辑器里修改它的所有应有的样式,而这些样式在DoModal函数里能被读出来,并传递给CreateDialoagIndirect函数,创建对话框。

posted on 2009-11-30 21:50  !-_-木糖-_-!  阅读(2411)  评论(0)    收藏  举报