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

               

作者:朱金灿

来源:http://blog.csdn.net/clever101

 

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

 

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

头文件的代码:

// kdialog.h#ifndef KDIALOG_H_INCLUDED#define KDIALOG_H_INCLUDED#define ID_HELP   150#define ID_EDIT   180#define ID_TEXT   200class KDialog{public:    KDialog(HINSTANCE hinst, HWND hwndOwner);    ~KDialog();    virtual INT_PTR DoModal();protected:    // API中注册的消息处理函数,不能是成员函数,因为成员函数有this指针    static BOOL CALLBACK DialogProc(HWND hWnd,                                       UINT uMsg, WPARAM wParam, LPARAM lParam);private:    HWND  m_hOwnerWnd;    HINSTANCE m_hInst;};#endif // KDIALOG_H_INCLUDED

     

Cpp文件的代码:

    

#include "kdialog.h"#include "resource.h"BOOL CALLBACK DialogProc (HWND, UINT, WPARAM, LPARAM) ;LPWORD lpwAlign ( LPWORD lpIn){    ULONG ul;    ul = (ULONG) lpIn;    ul +=3;    ul >>=2;    ul <<=2;    return (LPWORD) ul;}KDialog::KDialog(HINSTANCE hinst, HWND hwndOwner){    m_hInst = hinst;    m_hOwnerWnd = hwndOwner;}KDialog::~KDialog(){}char nEditTwo[128]= "从这儿输入字符串." ;BOOL CALLBACK KDialog::DialogProc(HWND hDlg,                                     UINT uMsg, WPARAM wParam, LPARAM lParam){       switch (uMsg)  {          case WM_INITDIALOG :      SetDlgItemText ( hDlg, ID_EDIT, nEditTwo );               return TRUE ;          case WM_COMMAND :               switch (LOWORD (wParam))               {     case ID_EDIT :       GetDlgItemText (hDlg, ID_EDIT, nEditTwo, 127);       return TRUE;     case ID_HELP :       MessageBox( NULL, nEditTwo, "输入数据", MB_OK | MB_SYSTEMMODAL | MB_NOFOCUS);       return TRUE;              case IDOK :                         EndDialog (hDlg, 0) ;                return TRUE ;      }              break ;            case WM_CLOSE:                  EndDialog (hDlg, 0) ;                  return TRUE ;        default:          break;     }     return FALSE ;}INT_PTR KDialog::DoModal(){    HGLOBAL hgbl;    LPDLGTEMPLATE lpdt;    LPDLGITEMTEMPLATE lpdit;    LPWORD lpw;    LPWSTR lpwsz;    LRESULT ret;    int nchar;    hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);    if (!hgbl)        return -1;    lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);    // Define a dialog box.    lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU                  | DS_MODALFRAME | WS_CAPTION;    lpdt->cdit = 3// number of controls    lpdt->x  = 10;    lpdt->y  = 10;    lpdt->cx = 100;    lpdt->cy = 70;    lpw = (LPWORD) (lpdt + 1);    *lpw++ = 0;   // no menu    *lpw++ = 0;   // predefined dialog box class (by default)    lpwsz = (LPWSTR) lpw;    nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "内存对话框", -1,                                    lpwsz, 50);    lpw   += nchar;    //-----------------------    // Define an OK button.    //-----------------------    lpw = lpwAlign (lpw);    lpdit = (LPDLGITEMTEMPLATE) lpw;    lpdit->x  = 10;    lpdit->y  = 50;    lpdit->cx = 80;    lpdit->cy = 15;    lpdit->id = IDOK;  // OK button identifier    lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;    lpw = (LPWORD) (lpdit + 1);    *lpw++ = 0xFFFF;    *lpw++ = 0x0080;    // button class    lpwsz = (LPWSTR) lpw;    nchar = 1+MultiByteToWideChar (CP_ACP, 0, "退出", -1, lpwsz, 50);    lpw   += nchar;    *lpw++ = 0;              // no creation data    //-----------------------    // Define a Help button.    //-----------------------    lpw = lpwAlign (lpw);    lpdit = (LPDLGITEMTEMPLATE) lpw;    lpdit->x  = 10;    lpdit->y  = 30;    lpdit->cx = 80;    lpdit->cy = 15;    lpdit->id = ID_HELP;    // Help button identifier    lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;    lpw = (LPWORD) (lpdit + 1);    *lpw++ = 0xFFFF;    *lpw++ = 0x0080;                 // button class atom    lpwsz = (LPWSTR) lpw;    nchar = 1+MultiByteToWideChar (CP_ACP, 0, "显示输入", -1, lpwsz, 50);    lpw   += nchar;    *lpw++ = 0;                      // no creation data    //-----------------------    // Define a EDIT.    //-----------------------    lpw = lpwAlign (lpw);    lpdit = (LPDLGITEMTEMPLATE) lpw;    lpdit->x  = 10;    lpdit->y  = 10;    lpdit->cx = 80;    lpdit->cy = 12;    lpdit->id = ID_EDIT;    // Help button identifier    lpdit->style = ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;    lpw = (LPWORD) (lpdit + 1);    *lpw++ = 0xFFFF;    *lpw++ = 0x0081;                 // edit class atom    *lpw++ = 0;                      // no creation data    GlobalUnlock(hgbl);    ret = DialogBoxIndirect(m_hInst,                            (LPDLGTEMPLATE) hgbl,                            m_hOwnerWnd,                            (DLGPROC) DialogProc);    GlobalFree(hgbl);    return ret;}

   

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

    
             KDialog dlg(m_hInst,m_hWnd);              dlg.DoModal();


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

BOOL KDialog::DoModeless(){        HGLOBAL hgbl;    LPDLGTEMPLATE lpdt;    LPDLGITEMTEMPLATE lpdit;    LPWORD lpw;    LPWSTR lpwsz;    LRESULT ret;    int nchar;    hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);    if (!hgbl)        return FALSE;    lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);    // Define a dialog box.    lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU                  | DS_MODALFRAME | WS_CAPTION;    lpdt->cdit = 3// number of controls    lpdt->x  = 10;    lpdt->y  = 10;    lpdt->cx = 100;    lpdt->cy = 70;    lpw = (LPWORD) (lpdt + 1);    *lpw++ = 0;   // no menu    *lpw++ = 0;   // predefined dialog box class (by default)    lpwsz = (LPWSTR) lpw;    nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "内存对话框", -1,                                    lpwsz, 50);    lpw   += nchar;    //-----------------------    // Define an OK button.    //-----------------------    lpw = lpwAlign (lpw);    lpdit = (LPDLGITEMTEMPLATE) lpw;    lpdit->x  = 10;    lpdit->y  = 50;    lpdit->cx = 80;    lpdit->cy = 15;    lpdit->id = IDOK;  // OK button identifier    lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;    lpw = (LPWORD) (lpdit + 1);    *lpw++ = 0xFFFF;    *lpw++ = 0x0080;    // button class    lpwsz = (LPWSTR) lpw;    nchar = 1+MultiByteToWideChar (CP_ACP, 0, "退出", -1, lpwsz, 50);    lpw   += nchar;    *lpw++ = 0;              // no creation data    //-----------------------    // Define a Help button.    //-----------------------    lpw = lpwAlign (lpw);    lpdit = (LPDLGITEMTEMPLATE) lpw;    lpdit->x  = 10;    lpdit->y  = 30;    lpdit->cx = 80;    lpdit->cy = 15;    lpdit->id = ID_HELP;    // Help button identifier    lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;    lpw = (LPWORD) (lpdit + 1);    *lpw++ = 0xFFFF;    *lpw++ = 0x0080;                 // button class atom    lpwsz = (LPWSTR) lpw;    nchar = 1+MultiByteToWideChar (CP_ACP, 0, "显示输入", -1, lpwsz, 50);    lpw   += nchar;    *lpw++ = 0;                      // no creation data    //-----------------------    // Define a EDIT.    //-----------------------    lpw = lpwAlign (lpw);    lpdit = (LPDLGITEMTEMPLATE) lpw;    lpdit->x  = 10;    lpdit->y  = 10;    lpdit->cx = 80;    lpdit->cy = 12;    lpdit->id = ID_EDIT;    // Help button identifier    lpdit->style = ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;    lpw = (LPWORD) (lpdit + 1);    *lpw++ = 0xFFFF;    *lpw++ = 0x0081;                 // edit class atom    *lpw++ = 0;                      // no creation data    GlobalUnlock(hgbl);    HWND hDlg = CreateDialogIndirect(m_hInst,                            (LPDLGTEMPLATE) hgbl,                            m_hOwnerWnd,                            (DLGPROC) DialogProc);    if(NULL==hDlg)       return FALSE;    ::ShowWindow(hDlg,SW_SHOW);    GlobalFree(hgbl);    return TRUE;}


效果图如下:


 

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



           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值