まず、WM_INITDIALOGメッセージを捕まえたときの処理です。 ここでは、initDlgという自作の関数内でやっている処理に ついて解説します。
この関数の中身をそのまま、ダイアローグプロシージャに書いても同じこと ですが、長ったらしくなるので関数にまとめただけです。 SetWindowText関数については第15章ではSetDlgItemText 関数を使いました。どちらを使っても結果は同じです。 エジットボックスに表示する文字列ですね。int initDlg(HWND hDlgWnd) { int i; SetWindowText(GetDlgItem(hDlgWnd, IDC_EDIT1), (LPCTSTR)edit_str); SetScrollRange(GetDlgItem(hDlgWnd, IDC_SCROLL1), SB_CTL, ScrMin, ScrMax, TRUE); ShowScroll(hDlgWnd); for ( i = 0; i <= 4; i++ ) SendMessage(GetDlgItem(hDlgWnd, IDC_LIST1), LB_INSERTSTRING, (WPARAM)i, (LPARAM)liststr[i]); SendMessage(GetDlgItem(hDlgWnd, IDC_LIST1), LB_SETCURSEL, (WPARAM)ListNo, 0L); for ( i = 0; i <= 3; i++ ) SendMessage(GetDlgItem(hDlgWnd, IDC_COMBO1), CB_INSERTSTRING, (WPARAM)i, (LPARAM)combostr[i]); SendMessage(GetDlgItem(hDlgWnd, IDC_COMBO1), CB_SETCURSEL, (WPARAM)ComboNo, 0L); return 0; }
次のSetScrollRange関数はスクロールバーの範囲です。
スクロールバーフラグは範囲を指定するときはSB_CTLにします。 再描画フラグは位置の変更を反映して再描画するかどうかを 指定します。普通は再描画をするのでTRUEですね。void SetScrollRange(hwnd, fnBar, nMin, nMax, fRedraw) HWND hwnd; /* スクロール バーを持つウィンドウのハンドル */ int fnBar; /* スクロール バー フラグ */ int nMin; /* スクロール位置の最小値 */ int nMax; /* スクロール位置の最大値 */ BOOL fRedraw; /* 再描画フラグ */
次に自作関数のShowScrollを呼んでいます。(後で解説)
次におなじみのSendMessage関数を使ってリストボックスに 文字列を挿入しています。
という感じで使います。ここでは2番目の引数をLB_INSERTSTRINGにしていますが LB_ADDSTRINGを使ってSendMessage(LISTBOXのウィンドウハンドル, LB_INSERTSTRING, (WPARAM)何番目か, (LPARAM)文字列);
というようにも書けます。ただし気を付けることがあります。 このように書いた場合、リソースエジタで文字列の順番をソート するように指定(VC++4.Xの場合デフォルトではソートになっている) した場合、文字列の順番が勝手に変わってしまいます。(後でもう少し解説)SendMessage(hwndCtl, LB_ADDSTRING, 0L, (LPARAM)文字列);
次に初期状態でリストボックスのどの文字列が選択された状態にするかを指定します。
ここで、3番目の引数を見て下さい。これは現に表示されているリスト ボックスの上から何番目か(一番上が0)を指定します。 もし、LB_ADDSTRINGで文字列をリストボックスに加えて、なおかつ 文字列をソートする設定になっていると困ったことが起こります。 つまり、自分では2番目の文字列を指定したつもりが、ソートが起こり 2番目の文字列が意図したものと違うものになっている可能性があるからです。 言葉で説明するとわかりにくいのですが、実際に経験するとピンときます。SendMessage(hwndCtl, LB_SETCURSEL, (WPARAM)何番目か, 0L);
コンボボックスについても同じように初期設定を行います。
さて、次はOKボタンが押されて、ダイアログボックスに入力された 情報を収集する方法です。ここでは、getDlgという自作関数にまとめましたが ダイアログプローシージャに直接書いても同じです。
最初のGetWindowTextはint getDlg(HWND hDlgWnd) { GetWindowText(GetDlgItem(hDlgWnd, IDC_EDIT1), edit_str, sizeof(edit_str)); ScrPos = GetScrollPos(GetDlgItem(hDlgWnd, IDC_SCROLL1), SB_CTL); ListNo = (int)(DWORD)SendMessage(GetDlgItem(hDlgWnd, IDC_LIST1), LB_GETCURSEL, 0L, 0L); ComboNo = (int)(DWORD)SendMessage(GetDlgItem(hDlgWnd, IDC_COMBO1), CB_GETCURSEL, 0L, 0L); return 0; }
ということになっています。あれ? 以前にエジットボックスから文字列を 取得するにはGetDlgItemText関数を使わなかったかな・・int GetWindowText( HWND hWnd, // handle of window or control with text LPTSTR lpString, // address of buffer for text int nMaxCount // maximum number of characters to copy );
はい。その通りです。第15章では GetDlgItemText関数を使っています。このように、SDKのプログラムでは 同じことをするのに2種類以上の方法が用意されていることがよくあります。 この場合、
どちらで書いても同じ結果となります。GetWindowText(GetDlgItem(hDlgWnd, IDC_EDIT1), edit_str, sizeof(edit_str)); GetDlgItemText(hDlgWnd, IDC_EDIT1, edit_str, sizeof(edit_str));
つぎに、選択されたリストボックスやコンボボックスの
番号の取得ですがやはり、SendMessage関数を使います。
例を見れば解説なしでも意味は分かりますね。
次は、自作のShowScroll関数です。
この関数は、スクロールの位置をセットしてスタティクテキストに、 スクロールの位置を数値で表示させるものです。何時呼ばれているかというと スクロールバーがクリックされたときと、ダイアログボックスの初期化が 行われたときです。int ShowScroll(HWND hWnd) { if (ScrPos < ScrMin) ScrPos = ScrMin; if (ScrPos > ScrMax) ScrPos = ScrMax; SetScrollPos(GetDlgItem(hWnd, IDC_SCROLL1), SB_CTL, ScrPos, TRUE); ShowStatic(hWnd); return 0; }
この関数もあんまり説明はいらないですね。int SetScrollPos( HWND hWnd, // スクロールバーのウィンドウハンドル int nBar, // スクロールバーフラグ int nPos, // スクロールつまみの位置 BOOL bRedraw // 再描画するかどうか );
次に、自作のShowStatic関数です。
ここまで、読み進んでこられた方なら特に説明の必要はないですね。int ShowStatic(HWND hWnd) { char str[8]; wsprintf(str, "%3d", ScrPos); SetWindowText(GetDlgItem(hWnd, IDC_STATIC1), (LPCTSTR)str); return 0; }
次に、ウィンドウプロシージャでWM_PAINTメッセージを捕まえたときの ShowText関数(自作)です。
DrawText関連の解説はすでに、第5章で行っています。int ShowText(HWND hWnd) { HDC hdc; RECT rt; PAINTSTRUCT ps; char str[256]; char *str_org = "エジットボックス=%s\n" "リストボックス=%s\n" "コンボボックス=%s\n" "スクロールバー=%3d"; wsprintf(str, str_org, edit_str, liststr[ListNo], combostr[ComboNo], ScrPos); GetClientRect(hWnd, &rt); hdc = BeginPaint(hWnd, &ps); DrawText(hdc, str, -1, &rt, DT_WORDBREAK); EndPaint(hWnd, &ps); return 0; }
この自作関数の解説は第16章を見て下さい。int SetWinCenter(HWND hWnd) { HWND hDeskWnd; RECT deskrc, rc; int x, y; hDeskWnd = GetDesktopWindow(); GetWindowRect(hDeskWnd, (LPRECT)&deskrc); GetWindowRect(hWnd, (LPRECT)&rc); x = (deskrc.right - (rc.right-rc.left)) / 2; y = (deskrc.bottom - (rc.bottom-rc.top)) / 2; SetWindowPos(hWnd, HWND_TOP, x, y, (rc.right-rc.left), (rc.bottom-rc.top),SWP_SHOWWINDOW); return 0; }
では、実行してみましょう。
実行すると左のようなウィンドウが画面の中央に現れます。(実際はもっと 大きいウィンドウです)
メニューの「ダイアログボックス」を選ぶと・・・
左のようなダイアローグボックスが現れます。スクロールつまみをいじったり、
コンボボックスから適当な文字列を選択したりして下さい。
OKボタンを押すとダイアログボックスが終了して、今選択したり
入力した内容がクライアント領域に表示されます。
[SDK Index] [総合Index] [Previous Chapter] [Next Chapter]
Update Apr/16/1997 By Y.Kumei