Visual c++中不使用对话框模板资源创建对话框应用

引言

通常情况下,利用vc为应用程序创建对话框需要使用对话框模板资源。通过vc++集成开发环境中的对话框编辑器以可视化的方式创建对话框资源,这种方法可以应用于大多数对话框编程的情况下。但涉及对话框的程序模块必然依赖于开发项目资源,不能作为多个开发项目共享的公用程序模块。比如,笔者开发的一系列应用程序,都需要一个用户输入注册信息的功能。通常情况下,可以将公用程序模块引入不同的开发项目,而实际程序文件只有唯一的备份。这样便于程序的维护,避免公用模块存在多个不一致拷贝的情况。但如果在公用程序模块中存在用户界面,则不能简单引入不同开发项目(因为不同项目都有各自的资源,其资源定义不免存在冲突)。另外如果开发过程中需要使用大量的对话框,这些对话框内容相似,但又略有不同,用对话框模板资源,也显得较为烦琐。本文介绍了在Visualc++中不使用常规的对话框资源模板的情况下,动态创建对话框的方法。

1、基本原理

如何不使用对话框模板资源,创建对话框应用,正是本文探讨的问题。如果仔细阅读MSDN中有关CDialog的内容会发现
CDialogCreateIndriect和
CDialogInitModalIndirect两个成员函数。正是这两个成员函数可以利用内存中的对话框资源创建对话框。
CDialogCreateIndriect用于创建无模式对话框,
CDialogInitModalIndirect可以创建模式对话框。

这两个成员函数都包含参数
LPCDLGTEMPLATElpDialogTemplate,它指向包含对话框和控件资源的内存位置。该段内存的具体内容包括两部分:

1.1对话框资源

最开始为DLGTEMPLATE结构,指出对话框窗口的位置、大小和风格,紧接其后的是指向菜单资源的数组(前两个字节为0x0000表示没有菜单),
接下来的UniCode字符串数组表示控件对应的注册类名(前两个字节为0x0000表示使用缺省的预定义类),然后是UniCode字符串数组表示的对话框标题,双字节的字体长度和字体名。

1.2对话框控件资源

紧跟对话框资源之后的是一个或多个对话框控件资源,每个控件资源最开始为DLGITEMTEMPLATE结构,指出控件窗口的位置、大小和风格,然后是控件对应的的注册类名,(如果前两个字节为0xFFFF表示使用预定义类),此时后两个字节指出具体类见表1,然后是控件标题(如果前两个字节为0xFFFF表示将使用ICON资源),接下来的数据用于创建控件时使用,由系统发送WM_CREATE消息时,被lParam参数引用,可以用0x0000表示省略该部分数据。

 

1

 

 

 

 

0x0080

Button

0x0081

Edit

0x0082

Static

0x0083

List box

0x0084

Scroll bar

0x0085

Combo box

 

 

 

 

 

 

 

表1

其中DLGTEMPLATE结构为

typedefstruct//dltt

DWORDstyle

DWORDdwExtendedStyle

WORD  cdit

shortx

shorty

shortcx

shortcy

DLGTEMPLATE

style和dwExtendedStyle为对话框的风格,cdit表示对话框包含的控件个数,x,y,cx,cy表示窗口的大小。DLGITEMTEMPLATE结构与此类似,仅多了一项标识id。

通过上面的描述,可以知道只须自行申请内存空间,按要求在内存中定义对话框和控件的资源,就可以不再依赖项目资源。实际编程中,因为在对话框类中定义和创建控件比较容易,因此往往可以仅定义内存对话框资源而省略控件资源部分,通过常规方法动态创建就可以了。

2、实现方法与步骤

下面结合一个进度显示对话框实例介绍具体实现的步骤:

首先从CDialog中派生一个类CMemoryDialog,作为所有无模板对话框的基类。选择菜单Insert->NewClass弹出New Class对话框,在Name项键入CMemoryDialog,BaseClass项选择
CDialog,按确定按钮。ClassWizard提示用户首先创建对话框模板资源,对此不与理会,继续创建。在创建成功的.
h文件中找到enum IDD = _UNKNOWN_RESOURCE_ID_ ,表示未知的资源ID将这行代码删除。

定义成员变量:

CStringm_StrTitle//对话框标题

DLGTEMPLATEm_dlgTempl//内存对话框模板

定义成员函数:

intDoModalMemoryDialog//用于创建模式对话框

voidCreateMemoryDialog//用于创建无模式对话框

其中DoModalMemoryDialog的代码清单如下:

intCMemoryDialogDoModalMemoryDialog

intr

       WCHAR szFontName = LARIAL     //字体名

       WCHAR pszBoxCaption //标题

      int nLenTitle=m_StrTitle.GetLength+1

       pszBoxCaption = new WCHARnLenTitle

//将标题转换为Unicode字符串

      MultiByteToWideCharCP_ACP0m_StrTitle-1 pszBoxCaptionnLenTitle

      TRY   

//分配保存资源的内存

intnBufferSize=
   sizeofDLGTEMPLATE+2 sizeofWORD/menu and class/ + nLenTitlesizeofWCHAR

      nBufferSize+=sizeofWORD+sizeofszFontName/fontinformation/ +

  nBufferSize=nBufferSize+2&2//adjustsize to make first control DWORD aligned

  HLOCALhLocal

      hLocal = LocalAllocLHND nBufferSize

              if hLocal == NULL

                    AfxThrowMemoryException

             BYTE pBuffer=BYTELocalLockhLocal

             if pBuffer == NULL

             

                     LocalFreehLocal

                     AfxThrowMemoryException

             

              BYTE pdest=pBuffer

              // 拷贝DLGTEMPLATE 结构

              memcpypdest &m_dlgTempl sizeofDLGTEMPLATE

              pdest+=sizeofDLGTEMPLATE

              WORDpdest=0//表示没有菜单

              WORDpdest+1=0//使用缺省类

              pdest+=2sizeofWORD

              //拷贝标题字符串

              memcpypdestpszBoxCaptionnLenTitlesizeofWCHAR

              pdest+=nLenTitlesizeofWCHAR

              WORDpdest=11//字体名的长度

              pdest+=sizeofWORD

              //拷贝字体名字符串

              memcpypdestszFontNamesizeofszFontName

              pdest+=sizeofszFontName

              delete  pszBoxCaption

              //创建模式对话框

             InitModalIndirectDLGTEMPLATEpBuffer

             r=DoModal

      LocalUnlockhLocal

              LocalFreehLocal

      

       CATCHCMemoryExceptione

      

              AfxMessageBox″Memory allocation failed″

      

         END_CATCH

     return r

  CreateMemoryDialog与此类似,只需将

  InitModalIndirectDLGTEMPLATEpBuffer

  r=DoModal   

  两行替换为

  CreateIndirectDLGTEMPLATEpBuffer

  ShowWindowSW_SHOW

  并且去掉返回值。

  然后从CMemoryDialog再次派生新类CCustomProgressDialog。在.h文件中加入成员CProgressCtrlm_ProCtrl,并覆盖基类的OnInitDialog成员函数。在OnInitDialog中动态创建CProgressCtrl对象。

  这样一个简单的进度显示对话框就建立好了,用户可以根据需要派生更多的对话框类,也可随时添加更多的控件对象。

  3、结论

  通过上述进度显示对话框的实现步骤,可以看到建立无模板资源对话框的实现方法。用户可以根据需要派生更多的对话框类,也可随时添加更多的控件对象。而且这些模块都与资源无关,可以同时被多个开发项目包含,维护起来十分方便。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值