不使用資源文件動態創建對話框的做法 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中間件 條碼系統中間層 物聯網軟件集成