zoukankan      html  css  js  c++  java
  • 不使用资源文件动态创建对话框的做法

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

     

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

    头文件的代码:

    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文件的代码:

        

    1. <span style="font-size:16px;">#include "kdialog.h"  
    2.   
    3. #include "resource.h"  
    4.   
    5. BOOL CALLBACK DialogProc (HWNDUINTWPARAMLPARAM) ;  
    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>  

       

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

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


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

    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++


  • 相关阅读:
    test
    VS dll 引用依赖
    Git配置
    编码--文字输入的前因后果
    base64相关
    异或
    UNION / UNION ALL 区别
    数据库使用规范
    chrome插件开发学习(一)
    缓存穿透 缓存雪崩 缓存并发
  • 原文地址:https://www.cnblogs.com/lidabo/p/3435057.html
Copyright © 2011-2022 走看看