ダイアログ: メモリ上にテンプレートを作成する例 (2)
ここでは、DLGTEMPLATE、DLGITEMTEMPLATE 構造体を使った例を示します。
作成例 2
HGLOBAL hgbl; LPDLGTEMPLATE lpdt; LPDLGITEMTEMPLATE lpdit; LPWORD lpw; LPBYTE lpb; LPWSTR lpwsz; int nChar; // 実際は、サイズはデータが収まりきるように // あらかじめ計算しておく必要があります。 // GMEM_ZEROINIT であらかじめデータを 0 に設定しておきます。 // (省略されているメンバは 0 になります) hgbl = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, 1024); if (!hgbl) ErrorAndExit(); // ダイアログボックスの初期値を設定します。 // ※ hgbl と lpdt のアドレスは同じになります (GMEM_FIXED のため)。 lpdt = (LPDLGTEMPLATE) GlobalLock(hgbl); lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION | DS_SETFONT; // フォント付き lpdt->cdit = 2; // コントロールの数 lpdt->x = 10; lpdt->y = 10; lpdt->cx = 100; lpdt->cy = 100; // 次のメンバの設定に移ります。 lpw = (LPWORD) (lpdt + 1); // <Menu ID> // *lpw++ = の文は、その位置に値を設定した後 ++ を行います。 // (つまり *lpw = 0; lpw++; と同じ) // 正式には lpw++ がインクリメントする前のアドレスを返し、 // そのアドレスに対して *XXX = 0 を行っています。 *lpw++ = 0; // <Window Class> *lpw++ = 0; // <Dialog Title> lpwsz = (LPWSTR) lpw; // MultiByteToWideChar 関数で ANSI 文字列を Unicode 文字列に変換します。 // 戻り値 (書き込んだ文字列の長さ) に NULL 文字が含まれているので + 1 しません。 nChar = MultiByteToWideChar(CP_ACP, 0, "ダイアログ テスト", -1, lpwsz, 50); // lpw = (LPWORD) lpwsz は必要ありません (アドレスが同じであるため)。 lpw += nChar; // WORD fontSize // ※ DS_SETFONT を指定しなかった場合、コントロールの設定に // 移るまでのデータ設定は行いません。 *lpw++ = 9; // WCHAR fontName[] lpwsz = (LPWSTR) lpw; nChar = MultiByteToWideChar(CP_ACP, 0, "MS P明朝", -1, lpwsz, 50); lpw += nChar; // コントロールの設定に移ります。 // 移る前に DWORD 境界に揃えます。 lpw = (LPWORD) (((DWORD_PTR) lpw + 3) & ~((DWORD_PTR) 3)); lpdit = (LPDLGITEMTEMPLATE) lpw; // OK ボタンを作ります。 lpdit->x = 10; lpdit->y = 70; lpdit->cx = 60; lpdit->cy = 14; lpdit->id = IDOK; // OK ボタンの ID lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; // 次のメンバの設定に移ります。 lpw = (LPWORD) (lpdit + 1); // <Window Class> // これでも構いません。 // lpwsz = (LPWSTR) lpw; // nChar = MultiByteToWideChar(CP_ACP, 0, "Button", -1, lpwsz, 50); // lpw += nChar; *lpw++ = 0xFFFF; // 数値指定に必要 *lpw++ = 0x0080; // ボタンのウィンドウクラスを指定します。 // <Control Text> lpwsz = (LPWSTR) lpw; nChar = MultiByteToWideChar(CP_ACP, 0, "OK", -1, lpwsz, 50); lpw += nChar; // WORD SizeOfCreationData // 特にデータは無いため、0 で終わります。 // ※ データがある場合、データのサイズ + sizeof(WORD) (= 2) を設定します。 *lpw++ = 0; // 次のコントロールの設定に移ります。 lpw = (LPWORD) (((DWORD_PTR) lpw + 3) & ~((DWORD_PTR) 3)); lpdit = (LPDLGITEMTEMPLATE) lpw; lpdit->x = 10; lpdit->y = 10; lpdit->cx = 40; lpdit->cy = 9; lpdit->id = IDC_STATIC; // スタティックコントロールによくある ID (IDC_STATIC = -1) lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT; lpw = (LPWORD) (lpdit + 1); // <Window Class> // これでも構いません。 // lpwsz = (LPWSTR) lpw; // nChar = MultiByteToWideChar(CP_ACP, 0, "Static", -1, lpwsz, 50); // lpw += nChar; *lpw++ = 0xFFFF; *lpw++ = 0x0082; // スタティックコントロールのウィンドウクラスを指定します。 // <Control Text> lpwsz = (LPWSTR) lpw; nChar = MultiByteToWideChar(CP_ACP, 0, "メッセージ", -1, lpwsz, 50); lpw += nChar; // WORD SizeOfCreationData // 特にデータは無いため、0 で終わります。 *lpw++ = 0; // データ設定は終了しました。ロックを解除します。 GlobalUnlock(hgbl); // DialogBoxIndirect を呼び出して作成します。GMEM_FIXED なので // LPDLGTEMPLATE の引数には hgbl をそのまま指定します。 // (hInst、hWndOwner、DialogProc は既に定義されているものとします。) DialogBoxIndirect(hInst, (LPDLGTEMPLATE) hgbl, hWndOwner, (DLGPROC) DialogProc); // メモリを解放します。 GlobalFree(hgbl);
最終更新日: 2005/04/17