[index] [詰め合わせ] [ダイアログボックス] [メニュー] [アクセラレータ] [String Table] [その他]
ダイアログボックス(dialog box)
ダイアログボックスのテンプレートには、文法にのっとってスクリプトを記述しダイアログボックス本体のデザインをします。さらに、同様な記述によりコントロールを配置していきます。
ボタンは、"押される" と、親ウィンドウのプロシージャ、つまり、ここでの場合は、ダイアログボックスのプロシージャに、WM_COMMAND が、ボタンのコントロールID といっしょになって、( wParam とか wp とか、つまりプロシージャ関数の第3引数、の下位16ビット(下位ワード)として含まれるかたちで) 送られます。
他のコントロールも、なにか"出来事"があると、(主に)WM_COMMAND が、ボタンと全く同じように、コントロールのID といっしょに、送られます。
説明する項目が多すぎるので、スケルトンコードのように骨格として使ってください。まるごと一つの .rc ファイルとすることが可能です。
#include <windows.h> // #include <commctrl.h> // #include "myprog.h" #define IDC_LIST1 101 #define IDC_EDIT1 102 #define IDC_REPLACE 104 #define IDC_STATIC1 105 #define IDC_STATIC2 106 #define IDC_STATIC3 107 MYDIALOG1 DIALOGEX DISCARDABLE -40, 20, 160, 100 STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_SIZEBOX | WS_MAXIMIZEBOX | DS_SETFONT EXSTYLE WS_EX_TOOLWINDOW // MENU MYMENU1 CAPTION "ダイアログボックス1のタイトル" FONT 14, "MS P明朝" BEGIN LISTBOX IDC_LIST1 ,35 ,0 ,125 ,45 ,LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT | WS_VSCROLL | WS_HSCROLL EDITTEXT IDC_EDIT1 ,115 ,53 ,40 ,12 ,ES_AUTOHSCROLL PUSHBUTTON "置換" ,IDC_REPLACE ,15 ,53 ,31 ,12 ,0L LTEXT "すべては \"CONTROL\" キーワードで行えます。各キーワードの文法は微妙に違うので、使い分けるのが面倒な場合には CONTROL キーワードのみでいいでしょう。" ,IDC_STATIC1 ,5 ,68 ,135 ,24 ,SS_SUNKEN CONTROL "ほらね。" ,IDC_STATIC2 ,"STATIC" ,SS_LEFT | SS_SUNKEN ,115 ,67 ,30 ,12 CONTROL IDI_ASTERISK ,IDC_STATIC3 ,"STATIC" ,SS_ICON ,8 ,7 ,21 ,21 END
DIALOGEX キーワードは、 DIALOG キーワードが拡張されたものですが、文法はかわりません。面倒なので DIALOGEX キーワードを使用してしまいましょう。
EXSTYLE WS_EX_TOOLWINDOW はウィンドウ"拡張"スタイルの指定です。必要なければこれごと省略できます。WS_EX_ のかたちの拡張スタイル (フラグ) で指定します。
"この色" と同じ色の部分は、リソーススクリプト内で一回だけ、先頭に必要です。
0L は 特に LONG型(32ビット) を指定しての、0 です。0 と記述しても構いません。
MYDIALOG1 は自分でつけて良いメニューの名前です。数値やマクロ定数であることも可能です。その場合ソースプログラムでの扱いが異なります( MAKEINTRESOURCE() マクロの使用)。
ダイアログボックスにメニューをつける場合も上例の MENU MYMENU1 のようにします。MYMENU1 メニューの定義(記述)はこの場所以前である必要はありません。
※ CONTROL IDI_ASTERISK
,IDC_STATIC3 ,"STATIC" ,SS_ICON ,8 ,7 ,21 ,21
はスタティックコントロールのおもしろい(特殊な) 例です。表示文字列であるはずの部分が IDI_ASTERISK となっていますが例外的に OK です。(びっくりマークの)アイコンが表示できます。このほかにはあまり例外といえるものが存在しないので、しつこくなりましたが載せてみました。IDI_ASTERISK のほかの種類に関しては、LoadIcon() 関数のほか、 LoadBitmap() 関数などの説明をあたってみてください。
[ ダイアログ本体のウィンドウスタイル ]
[ 座標と大きさ ]
縦は 8DLU 、横は 4DLU がそれぞれフォントの高さ、幅にあたることと同値です。DLU は フォントの大きさを基準とした単位です。だから 、(下で説明する)フォントやその大きさを変えると、 DLU の表す大きさも変化し、つまりダイアログボックスの大きさが全体的に縮小拡大することになります。
[ フォント ]
自分のコンピュータでどんなフォントが使えるかは、ChooseFont() 関数で "フォント選択ダイアログ" を出してみるとか、また EnumFontFamilies() 関数も利用できます。
[ コントロール ]
ほらね。",IDC_STATIC2 ,"STATIC" ,SS_LEFT | SS_SUNKEN ,115 ,7 ,30 ,6CONTROL "
CONTROL
の次から順に、"表示文字列" , コントロールID , "ウィンドウクラス名" , ウィンドウ(の)スタイル , 座標(x4) と続きます。この例はスタティックコントロールです。文字を表示するだけのコントロール。
"コントロールに(デフォルトで)表示される文字列" はコントロールによっては関係のない場合があります。そのときは単に、"" などとします。文法的なきまりなので省略はできません。コントロールID は下記。ウィンドウクラス名はウィンドウ(コントロール)の種類です。ウィンドウスタイルについてはそれぞれのコントロールの説明を参照します。複数のスタイルは ビットor 演算子 | で足していきます。座標の単位は DLU です。
※ 表示される文字を動的に変えるには SetWindowText() 関数や SetDlgItemText() 関数をつかってみよう。
[ 特別に構文が用意されたコントロール ]
[ コントロールID (番号) ]
別のダイアログボックスのコントロール同士でコントロールID が重複することは、アプリケーション上は問題ありません。特に一意の値を付けたい特別なコントロールを除いては、その点を利用してきれいに ID を付けていくのがいいです。そのほかの要点は
[MSDN] ダイアログボックス本体の、リソーススクリプトに関すること。注1
注1
CONTROLや DIALOG, DIALOGEX をあたってみてください。Controls 以下には、特別に構文のあるコントロールもあります。でもかなり分かりづらいです。※
lcc のヘルプ を持っていれば、各コントロールのウィンドウスタイルや、WS_ と DS_ は CreateWindow() 関数、WS_EX_ に関しては CreateWindowEx() のところに載っているので非常に便利です。bcc についてくる grep.exe を使って、ヘッダファイル winuser.h や commctrl.h にむかって、"grep WS_ winuser.h" などとやるのも有効な手段です。
[ 最後に。どうやって使うか ]
CreateDialog( GetModuleHandle(NULL) , "
MYDIALOG1" , NULL , (DLGPROC)MyDlgProc ) ;のようにします。
"MyDlgProc" はダイアログボックスのプロシージャの "関数アドレス" を指定しています。ということはつまり MyDlgProc() 関数 (ダイアログボックスプロシージャ) の記述が必要です。この関数のプロトタイプや仕様に関しては、標準的には、"DialogProc" という名前で統一されて説明されています。CreateDialog() の説明からでもたどれるでしょう。
[ フォントの変更 ]
フォントはどのコントロールにも、テンプレートで指定したフォントが共通して使われます。あるコントロールだけフォントを変更したい場合は、SelectObject() 関数 : 違います や WM_SETFONT メッセージか、または SetWindowFont() マクロ ( <windowsx.h> にあります。これが一番楽 ) を利用します。この処理を行うタイミングは結局 WM_INITDIALOG くらいしか考えられません。フォントの作成には CreateFontIndirect() 関数などを使います。作ったフォントは、そのコントロールの破棄時に DeleteObject() することを忘れずに。ウィンドウ表示中に選択したフォントを DeleteObject() すると、文字が乱れますョ(実験するのが一番よいかもしれません)。
LRESULT CALLBACK MyDlgProc( HWND, UINT, WPARAM, LPARAM ); // プロトタイプ宣言 LRESULT CALLBACK MyDlgProc( HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) // 関数の本体 { return FALSE ; }
[トップ] [level4:言葉] [index]