- 締切済み
ダイアログのボタン操作
ダイアログのボタンが押されている間、文字列が表示されるようなプログラムを作りたいのですが、通常のプッシュボタンですと、押したあと離した時にイベント(WM_COMMAND)が発生してしまいます。(通常、OKやキャンセルを押した場合、実際に話した時に機能が働く) ボタンが押されていることを認識する方法はあるのでしょうか? ラジオボタンやチェックボックスなら設定によってできるような話を聞いたのですがプロパティをどのように設定したらよいかわりません。 よろしくお願い致します。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- YukiHanabi
- ベストアンサー率46% (6/13)
SDKでは、チェックボックスやボタン等の処理を行うときは、 サブクラス化しそこで処理を実施しないと動作しまん。 HWND botan_hwnd ; HWND mouse_hwnd; WNDPROC Org_WNDPROC; POINT pt; int pt_int; BOOL CALLBACK DialogFunc(HWND hdwnd,...){ //ダイアログの処理 switch(message){ case WM_INITDIALOG: botan_hwnd =GetDlgItem(hdwnd,IDCANCEL); //指定した ID のHWNDを確定 Org_WNDPROC = (WNDPROC)GetWindowLong(botan_hwnd, GWL_WNDPROC); //GetWindowLongで元々のプロシージャのアドレス //(FARPROC)を取得する、 SetWindowLong(botan_hwnd,GWL_WNDPROC,(LONG)MySubProc1); //サブクラス化の実行 break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: EndDialog(hdwnd, 0); SetWindowLong(botan_hwnd , GWL_WNDPROC, (LONG)Org_WNDPROC); //必要がなくなったらサブクラス化の解除(復元)、 return 1; } break; //一部省略 //サブクラス化 、一般的なメッセージ処理と代々同じ LRESULT CALLBACK MySubProc1(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){ switch (msg) { WM_LBUTTONDOWN: pt.x = LOWORD(lp); pt.y = HIWORD(lp); mouse_hwnd = ChildWindowFromPoint( hWnd, pt ); if( mouse_hwnd == botan_hwnd ) { //指定のボタンを押してるときの処理をここに記述 } break; } return (CallWindowProc(Org_WNDPROC, hWnd, msg, wp, lp)); //処理しないメッセージを元のプロシージャ側で処理 }; 一部ソースを省略し読みにくくなりましたが、以上でボタンの細かい処理ができます。
- buihyaku
- ベストアンサー率29% (97/326)
#1です。 SDK直でダイアログを処理したことがないのでピントのずれた回答になっていたらごめんなさい。 ただ、基本的な考え方として、ダイアログのWndProcでLButtonDown/UPを拾うと、ダイアログ内でマウスを押された場合すべて拾ってしまうとおもいますので、ボタンに対するWndProcを定義してそこで処理すればよいのではないかとおもいます。 (GetDlgItem,SetWindowLong, CallWindowProc) ボタンにWndProcを定義するのがメンドウなら、メッセージに含まれる座標からボタンの領域に含まれるかどうかを判定するのでもよいかとおもいます。GetDlgItemでボタンのHWNDを取得、そのHWNDに対しGetWindowRectでボタンのスクリーン座標を取得して、ScreenToClientで親ダイアログに対するクライアント座標に変換しメッセージのlparamに含まれる座標でボタン上かどうかPtInRectで判定、という形でしょうか。 その場合、横取りしたメッセージをボタンウィンドウにも投げてやることを忘れないようにしないとボタンが押された状態にならないとおもわれます。 どのボタンが押されたかを区別する、というのはGetDlgItemで取得したボタンのHWNDにたいして上記処理をやるわけですから区別可能ですよね。
確認したいことがあるのですが、 MFCを使っていますか? SDKを使っていますか? CButtonというクラスはご存知ですか? MFCのクラスのボタンクラスの派生クラスは作れますか? >>WM_LBUTTONDOWN, WM_LBUTTONUPを拾うところまでできました。 とありますが、具体的に答えていただけますか? また、下の方No1の方法でできたが、 >>ダイアログ中のどのボタンが押されているかを特定する方法は無いですか? どうやって個別に識別することができるのかを知りたいのですか?
補足
SDKを使っています。 メインダイアログプロシジャのなかで、WM_LBUTTONDOWN, WM_LBUTTONUPを判定し、それぞれを拾ったことがわかるようにしています。(文字列が表示されるなど) クラスについては勉強中でまだ使ったことはありません。 >どうやって個別に識別することができるのかを知りたいのですか? その通りです。WM_COMMANDで拾ったときは、引き続いてプッシュボタンのIDを判定して識別できましたが、WM_LBUTTONDOWN, WM_LBUTTONUPでは同じようにできないので、他に個別に識別する方法が知りたいです。
- buihyaku
- ベストアンサー率29% (97/326)
ボタンの派生クラスを作成すればWM_LBUTTONDOWN, WM_LBUTTONUPを拾うことができます。 VC6ですとクラスウイザードでボタンのコントロールのメンバ変数を追加して、その定義を自分で作成した派生クラスに置き換えてしまいます。
補足
WM_LBUTTONDOWN, WM_LBUTTONUPを拾うところまでできました。ただ、ダイアログ中のボタンではなく、マウスのボタンを押したときに拾うようです。ダイアログ中のどのボタンが押されているかを特定する方法は無いですか?(WM_COMMANDはダイアログ中のボタンを押して離したことを拾うので使えませんでした)
お礼
ありがとうございます。 実は仕事で組み込みプログラム(C)をやっていまして、それからみるとSDKのほうが取っ付きが良かったので、SDKにしました。 MFCでもプログラムに挑戦してみようと思います。