不使用资源文件动态创建对话框的做法

一般而言,在 Windows编程中创建对话框需要先定义一个对话框资源。我想能不能不用资源文件单纯通过代码创建对话框呢?晚上搜索了一些资料,研究了一下,基本实现了。

 

我写了一个KDialog,代码如下(代码中有一些注释,相信大家能基本看懂):

头文件的代码:

[cpp] view plaincopy

  1. <span style="font-size:16px;">// kdialog.h  
  2. #ifndef KDIALOG_H_INCLUDED  
  3. #define KDIALOG_H_INCLUDED  
  4.   
  5. #define ID_HELP   150  
  6. #define ID_EDIT   180  
  7. #define ID_TEXT   200  
  8.   
  9. class KDialog  
  10. {  
  11. public:  
  12.   
  13.     KDialog(HINSTANCE hinst, HWND hwndOwner);  
  14.   
  15.     ~KDialog();  
  16.   
  17.     virtual INT_PTR DoModal();  
  18.   
  19. protected:  
  20.   
  21.     // API中注册的消息处理函数,不能是成员函数,因为成员函数有this指针  
  22.     static BOOL CALLBACK DialogProc(HWND hWnd,  
  23.                                        UINT uMsg, WPARAM wParam, LPARAM lParam);  
  24.   
  25. private:  
  26.   
  27.     HWND  m_hOwnerWnd;  
  28.   
  29.     HINSTANCE m_hInst;  
  30.   
  31. };  
  32.   
  33.   
  34.   
  35. #endif // KDIALOG_H_INCLUDED  
  36. </span>  

     

Cpp文件的代码:

    

[cpp] view plaincopy

  1. <span style="font-size:16px;">#include "kdialog.h"  
  2.   
  3. #include "resource.h"  
  4.   
  5. BOOL CALLBACK DialogProc (HWND, UINT, WPARAM, LPARAM) ;  
  6.   
  7. LPWORD lpwAlign ( LPWORD lpIn)  
  8. {  
  9.     ULONG ul;  
  10.   
  11.     ul = (ULONG) lpIn;  
  12.     ul +=3;  
  13.     ul >>=2;  
  14.     ul <<=2;  
  15.     return (LPWORD) ul;  
  16. }  
  17.   
  18. KDialog::KDialog(HINSTANCE hinst, HWND hwndOwner)  
  19. {  
  20.     m_hInst = hinst;  
  21.     m_hOwnerWnd = hwndOwner;  
  22. }  
  23.   
  24. KDialog::~KDialog()  
  25. {  
  26.   
  27. }  
  28.   
  29. char nEditTwo[128]= "从这儿输入字符串." ;  
  30.   
  31. BOOL CALLBACK KDialog::DialogProc(HWND hDlg,  
  32.                                      UINT uMsg, WPARAM wParam, LPARAM lParam)  
  33. {  
  34.        switch (uMsg)  
  35.      {  
  36.           case WM_INITDIALOG :  
  37.                SetDlgItemText ( hDlg, ID_EDIT, nEditTwo );  
  38.                return TRUE ;  
  39.   
  40.           case WM_COMMAND :  
  41.                switch (LOWORD (wParam))  
  42.                {  
  43.                     case ID_EDIT :  
  44.                          GetDlgItemText (hDlg, ID_EDIT, nEditTwo, 127);  
  45.                          return TRUE;  
  46.                     case ID_HELP :  
  47.                          MessageBox( NULL, nEditTwo, "输入数据", MB_OK | MB_SYSTEMMODAL | MB_NOFOCUS);  
  48.                          return TRUE;  
  49.                     case IDOK :  
  50.                          EndDialog (hDlg, 0) ;  
  51.                          return TRUE ;  
  52.                }  
  53.               break ;  
  54.             case WM_CLOSE:  
  55.                   EndDialog (hDlg, 0) ;  
  56.                   return TRUE ;  
  57.         default:  
  58.           break;  
  59.      }  
  60.      return FALSE ;  
  61. }  
  62.   
  63. INT_PTR KDialog::DoModal()  
  64. {  
  65.     HGLOBAL hgbl;  
  66.     LPDLGTEMPLATE lpdt;  
  67.     LPDLGITEMTEMPLATE lpdit;  
  68.     LPWORD lpw;  
  69.     LPWSTR lpwsz;  
  70.     LRESULT ret;  
  71.     int nchar;  
  72.   
  73.     hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);  
  74.     if (!hgbl)  
  75.         return -1;  
  76.   
  77.     lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);  
  78.   
  79.     // Define a dialog box.  
  80.   
  81.     lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU  
  82.                   | DS_MODALFRAME | WS_CAPTION;  
  83.     lpdt->cdit = 3;  // number of controls  
  84.     lpdt->x  = 10;  
  85.     lpdt->y  = 10;  
  86.     lpdt->cx = 100;  
  87.     lpdt->cy = 70;  
  88.   
  89.     lpw = (LPWORD) (lpdt + 1);  
  90.     *lpw++ = 0;   // no menu  
  91.     *lpw++ = 0;   // predefined dialog box class (by default)  
  92.   
  93.     lpwsz = (LPWSTR) lpw;  
  94.     nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "内存对话框", -1,  
  95.                                     lpwsz, 50);  
  96.     lpw   += nchar;  
  97.   
  98.     //-----------------------  
  99.     // Define an OK button.  
  100.     //-----------------------  
  101.     lpw = lpwAlign (lpw);  
  102.   
  103.     lpdit = (LPDLGITEMTEMPLATE) lpw;  
  104.     lpdit->x  = 10;  
  105.     lpdit->y  = 50;  
  106.     lpdit->cx = 80;  
  107.     lpdit->cy = 15;  
  108.     lpdit->id = IDOK;  // OK button identifier  
  109.     lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;  
  110.   
  111.     lpw = (LPWORD) (lpdit + 1);  
  112.     *lpw++ = 0xFFFF;  
  113.     *lpw++ = 0x0080;    // button class  
  114.   
  115.     lpwsz = (LPWSTR) lpw;  
  116.     nchar = 1+MultiByteToWideChar (CP_ACP, 0, "退出", -1, lpwsz, 50);  
  117.     lpw   += nchar;  
  118.     *lpw++ = 0;              // no creation data  
  119.   
  120.   
  121.     //-----------------------  
  122.     // Define a Help button.  
  123.     //-----------------------  
  124.     lpw = lpwAlign (lpw);  
  125.   
  126.     lpdit = (LPDLGITEMTEMPLATE) lpw;  
  127.     lpdit->x  = 10;  
  128.     lpdit->y  = 30;  
  129.     lpdit->cx = 80;  
  130.     lpdit->cy = 15;  
  131.     lpdit->id = ID_HELP;    // Help button identifier  
  132.     lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;  
  133.   
  134.     lpw = (LPWORD) (lpdit + 1);  
  135.     *lpw++ = 0xFFFF;  
  136.     *lpw++ = 0x0080;                 // button class atom  
  137.   
  138.     lpwsz = (LPWSTR) lpw;  
  139.     nchar = 1+MultiByteToWideChar (CP_ACP, 0, "显示输入", -1, lpwsz, 50);  
  140.     lpw   += nchar;  
  141.     *lpw++ = 0;                      // no creation data  
  142.   
  143.   
  144.     //-----------------------  
  145.     // Define a EDIT.  
  146.     //-----------------------  
  147.     lpw = lpwAlign (lpw);  
  148.   
  149.     lpdit = (LPDLGITEMTEMPLATE) lpw;  
  150.     lpdit->x  = 10;  
  151.     lpdit->y  = 10;  
  152.     lpdit->cx = 80;  
  153.     lpdit->cy = 12;  
  154.     lpdit->id = ID_EDIT;    // Help button identifier  
  155.     lpdit->style = ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;  
  156.   
  157.     lpw = (LPWORD) (lpdit + 1);  
  158.     *lpw++ = 0xFFFF;  
  159.     *lpw++ = 0x0081;                 // edit class atom  
  160.     *lpw++ = 0;                      // no creation data  
  161.   
  162.     GlobalUnlock(hgbl);  
  163.   
  164.     ret = DialogBoxIndirect(m_hInst,  
  165.                             (LPDLGTEMPLATE) hgbl,  
  166.                             m_hOwnerWnd,  
  167.                             (DLGPROC) DialogProc);  
  168.   
  169.     GlobalFree(hgbl);  
  170.     return ret;  
  171. }  
  172. </span>  

   

    外部调用的方法也很简单(把应用程序句柄和对话框的所有者窗口句柄传进来即可):

    

[cpp] view plaincopy

  1. <span style="font-size:16px;">             KDialog dlg(m_hInst,m_hWnd);  
  2.               dlg.DoModal();  
  3. </span>  

上面创建的是模式对话框,下面是创建非模式对话框的代码:

[cpp] view plaincopy

  1. BOOL KDialog::DoModeless()  
  2. {  
  3.         HGLOBAL hgbl;  
  4.     LPDLGTEMPLATE lpdt;  
  5.     LPDLGITEMTEMPLATE lpdit;  
  6.     LPWORD lpw;  
  7.     LPWSTR lpwsz;  
  8.     LRESULT ret;  
  9.     int nchar;  
  10.   
  11.     hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);  
  12.     if (!hgbl)  
  13.         return FALSE;  
  14.   
  15.     lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);  
  16.   
  17.     // Define a dialog box.  
  18.   
  19.     lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU  
  20.                   | DS_MODALFRAME | WS_CAPTION;  
  21.     lpdt->cdit = 3;  // number of controls  
  22.     lpdt->x  = 10;  
  23.     lpdt->y  = 10;  
  24.     lpdt->cx = 100;  
  25.     lpdt->cy = 70;  
  26.   
  27.     lpw = (LPWORD) (lpdt + 1);  
  28.     *lpw++ = 0;   // no menu  
  29.     *lpw++ = 0;   // predefined dialog box class (by default)  
  30.   
  31.     lpwsz = (LPWSTR) lpw;  
  32.     nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "内存对话框", -1,  
  33.                                     lpwsz, 50);  
  34.     lpw   += nchar;  
  35.   
  36.     //-----------------------  
  37.     // Define an OK button.  
  38.     //-----------------------  
  39.     lpw = lpwAlign (lpw);  
  40.   
  41.     lpdit = (LPDLGITEMTEMPLATE) lpw;  
  42.     lpdit->x  = 10;  
  43.     lpdit->y  = 50;  
  44.     lpdit->cx = 80;  
  45.     lpdit->cy = 15;  
  46.     lpdit->id = IDOK;  // OK button identifier  
  47.     lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;  
  48.   
  49.     lpw = (LPWORD) (lpdit + 1);  
  50.     *lpw++ = 0xFFFF;  
  51.     *lpw++ = 0x0080;    // button class  
  52.   
  53.     lpwsz = (LPWSTR) lpw;  
  54.     nchar = 1+MultiByteToWideChar (CP_ACP, 0, "退出", -1, lpwsz, 50);  
  55.     lpw   += nchar;  
  56.     *lpw++ = 0;              // no creation data  
  57.   
  58.   
  59.     //-----------------------  
  60.     // Define a Help button.  
  61.     //-----------------------  
  62.     lpw = lpwAlign (lpw);  
  63.   
  64.     lpdit = (LPDLGITEMTEMPLATE) lpw;  
  65.     lpdit->x  = 10;  
  66.     lpdit->y  = 30;  
  67.     lpdit->cx = 80;  
  68.     lpdit->cy = 15;  
  69.     lpdit->id = ID_HELP;    // Help button identifier  
  70.     lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;  
  71.   
  72.     lpw = (LPWORD) (lpdit + 1);  
  73.     *lpw++ = 0xFFFF;  
  74.     *lpw++ = 0x0080;                 // button class atom  
  75.   
  76.     lpwsz = (LPWSTR) lpw;  
  77.     nchar = 1+MultiByteToWideChar (CP_ACP, 0, "显示输入", -1, lpwsz, 50);  
  78.     lpw   += nchar;  
  79.     *lpw++ = 0;                      // no creation data  
  80.   
  81.   
  82.     //-----------------------  
  83.     // Define a EDIT.  
  84.     //-----------------------  
  85.     lpw = lpwAlign (lpw);  
  86.   
  87.     lpdit = (LPDLGITEMTEMPLATE) lpw;  
  88.     lpdit->x  = 10;  
  89.     lpdit->y  = 10;  
  90.     lpdit->cx = 80;  
  91.     lpdit->cy = 12;  
  92.     lpdit->id = ID_EDIT;    // Help button identifier  
  93.     lpdit->style = ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;  
  94.   
  95.     lpw = (LPWORD) (lpdit + 1);  
  96.     *lpw++ = 0xFFFF;  
  97.     *lpw++ = 0x0081;                 // edit class atom  
  98.     *lpw++ = 0;                      // no creation data  
  99.   
  100.     GlobalUnlock(hgbl);  
  101.   
  102.     HWND hDlg = CreateDialogIndirect(m_hInst,  
  103.                             (LPDLGTEMPLATE) hgbl,  
  104.                             m_hOwnerWnd,  
  105.                             (DLGPROC) DialogProc);  
  106.     if(NULL==hDlg)  
  107.        return FALSE;  
  108.   
  109.     ::ShowWindow(hDlg,SW_SHOW);  
  110.   
  111.     GlobalFree(hgbl);  
  112.     return TRUE;  
  113. }  

效果图如下:

 

      具体的实现原理,大家请参考这篇文章:对话框模板,RegexTest,微软官网上也有相关的文章:UsingDialog Boxes。此外CodeProject上的一个例子:UsingDialog Templates to create an InputBox() in C++

时间: 2024-09-08 11:12:53

不使用资源文件动态创建对话框的做法的相关文章

Visual c++例子,可不使用常规的对话框资源模板的情况下,动态创建对话框的方法

详细说明:Visual c++例子,可不使用常规的对话框资源模板的情况下,动态创建对话框的方法.该方法可以在运行时在内存中直接建立对话框资源,使用起来更为灵活.适用于多个开发项目共享有界面的公用程序模块的情况,也适用于编写需要显示大量对话框或对话框风格随着用户输入不断变化的应用程序.   下载地址1:http://files.cnblogs.com/lidabo/CDynamicDialogWithoutTemplate.rar 下载地址2:http://www.pudn.com/downloa

mfc-MFC父窗口上动态创建对话框出错

问题描述 MFC父窗口上动态创建对话框出错 m_dlgFlash=new CMyPlayerDlg();m_dlgFlash->Create(IDD_MYPLAYER_DLGthis); 解决方案 if (!m_wndView.Create(NULL NULL /*AFX_WS_DEFAULT_VIEW*/WS_CHILD | WS_VISIBLE CRect(0 0 0 0) this AFX_IDW_PANE_FIRST NULL)){ TRACE0(""未能创建视图窗口n&

MFC不使用对话框资源模版创建对话框

在MFC程序中使用对话框时首先在资源模版里创建对话框资源,然后DoModal()或者CReate显示出模式对话框或者非模式对话框,这样创建出的对话框移植性差,从一个工程移动到另一个工程比较麻烦.     在MFC中还有另一种创建对话框的方法:1 在内存中建立对话框资源模版DLGTEMPLATE结构体.2 使用InitModalIndirect API函数即可创建模式对话框,非模式对话框使用CreateDialog API函数创建. 代码如下:   // 创建内存对话框资源模版类,H文件 #pra

C#创建和使用资源文件

创建 创建资源文件    资源文件顾名思义就是存放资源的文件.资源文件在程序设计中有着自身独特的优势,他独立于源程序,这样资源文件就可以被多个程序使用.同时在程序设计的时候,有时出于安全或者其他方面因素的考虑,把重要东西存放在资源文件中,也可以达到保密.安全的效果.那么Visual C#所使用的资源文件中到底存放哪些东西呢?在用Visual C#创建资源文件大致可以存放三种类型的数据资源,分别是字节数组.各种对象和字符串.本文将结合一个程序例子来具体说明用Visual C#是如何创建资源文件的.

EasyUI创建对话框的两种方式_jquery

对话框(Dialog)是一个特殊的窗口(window),可以包含在顶部的工具栏和在底部的按钮.默认情况下,对话框(Dialog)不能改变大小,但是用户可以设置 resizable 属性为 true,使其可以改变大小. 这种就是对话框了. EasyUI有两种创建方式: 第一种:通过已存在的DOM节点元素标签创建 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org

代码阅读总结之Fitch and Mather 7.0(资源文件Resource随笔)

在Fitch and Mather 7.0中利用了大量的资源文件 资源文件对创建和本地化提供全面的支持 资源可以包含多种形式的数据,包括字符串.图像和持久的对象 通过在资源文件中存储数据,无需重新编译即可更改数据. 为了将持久对象写入资源文件,这些对象必须是可序列化的. Fitch and Mather 7.0在命名空间FMStocks7.Common中创建了一个ResourcesCollection集会类 此类定义了一个构造器和2个索引器 构造器初始化一个私有的ResourceManager实

Visual C#资源文件编程--使用资源文件 &amp;lt;zt&amp;gt;-Windows开发-.NET

在<Visual C#资源文件编程--创建资源文件>中已经介绍了如何用Visual C#创建资源文件.本文将接着上篇文章的话题来探讨资源文件另外一个问题,在Visual C#如何使用资源文件.在上一篇文章中,我们已经成功的创建了一个名称为"My.resources"的资源文件.这个资源文件中包含有一个图标资源,在文件中的名称为"demo.ico",若干个图片资源和一个字符串资源,在文件中的名称为"MyStr".我们将以上一篇文章创建的

在.net中创建并使用资源文件(2)

我们继续资源文件使用的学习,将上次生成Skines.resx文件(在\bin\Debug目录下)Copy到要使用资源的Project的根目录下,然后在Visual Studio的Solution Explorer中点击一下上方的"Show All Files"按钮,就能在项目下见到Skins.resx. 在Skins.resx中点右键选择"Include In Project"见Skins.resx增加到项目中.这时候,我们已经将资源增加到了项目中,到底怎么使用它呢

在.net中创建并使用资源文件(1)

在.net中,可以创建资源文件(.resx)供程序使用,可以在资源文件中加入图片.字符串等自定义资源.以便在程序中使用这些文件.下边就我们就创建一个名为Skins.resx的资源文件,在里面装载一些程序UI需要的资源,以便绘制程序界面. 首先我们新建一个Windows程序(Windows Application),在Form1_Load中加入以下代码: ResXResourceWriter rw = new ResXResourceWriter("Skins.resx"); //ski