不使用资源文件动态创建对话框的做法 2016-09-28 00:00:00 广州睿丰德信息科技有限公司 阅读 睿丰德科技 专注RFID识别技术和条码识别技术与管理软件的集成项目。质量追溯系统、MES系统、金蝶与条码系统对接、用友与条码系统对接 一般而言,在 Windows编程中创建对话框需要先定义一个对话框资源。我想能不能不用资源文件单纯通过代码创建对话框呢?晚上搜索了一些资料,研究了一下,基本实现了。 我写了一个KDialog,代码如下(代码中有一些注释,相信大家能基本看懂): 头文件的代码: [cpp] view plaincopy <span style="font-size:16px;">// kdialog.h #ifndef KDIALOG_H_INCLUDED #define KDIALOG_H_INCLUDED #define ID_HELP 150 #define ID_EDIT 180 #define ID_TEXT 200 class 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 </span> Cpp文件的代码: [cpp] view plaincopy <span style="font-size:16px;">#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; } </span> 外部调用的方法也很简单(把应用程序句柄和对话框的所有者窗口句柄传进来即可): [cpp] view plaincopy <span style="font-size:16px;"> KDialog dlg(m_hInst,m_hWnd); dlg.DoModal(); </span> 上面创建的是模式对话框,下面是创建非模式对话框的代码: [cpp] view plaincopy 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++RFID管理系统集成商 RFID中间件 条码系统中间层 物联网软件集成