起こるはずのイベントが起こらない – プログラミング – Home

起こるはずのイベントが起こらない
 
通知
すべてクリア

起こるはずのイベントが起こらない


ほえほえむー
 ほえほえむー
(@ほえほえむー)
ゲスト
結合: 17年前
投稿: 5
Topic starter  

お世話になります。

Windows XP Pro SP3 / Visual Studio 2008 SP1
C++/CLI / Windowsフォームアプリケーションでアプリケーションを作成しています。

フォーム1(Form1 : System::Windows::Froms::Form)に
テキストボックス1(textBox1 : System::Windows::Forms::TextBox)と
ボタン1(button1 : System::Windows::Forms::Button)を配置しています。

テキストボックス1のLeaveイベントハンドラと
ボタン1のClickイベントハンドラを追加し、下のようにしています。

private:
System::Void textBox1_Leave(System::Object^ sender, System::EventArgs^ e) {
MessageBox::Show(Leaveイベントが発生しました。);
}

private:
System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
textBox1->Text = button1をクリックしました。;
}

ビルド後、実行し、テキストボックス1にフォーカスを当てた状態で
ボタン1をクリックします。
メッセージボックスが表示されるのでOKボタンをクリックします。
その後、ボタン1のクリックイベントハンドラが実行されることを
期待していたのですがメッセージボックスを閉じた後、
何も実行されません(ボタン1にフォーカスは移りますが)。

テキストボックス1がフォーカスを失うのがボタン1をクリックしたタイミング
だけではないのでテキストボックス1のLeaveイベントハンドラ内で
ボタン1のClickイベントを設定するわけにもいかず、困っています。

メッセージボックスを閉じた後、ボタン1のクリックイベントハンドラを
実行させる、というか発生するはずだったイベントをちゃんと発生させる
にはどうしたらいいのでしょうか。


引用解決済
トピックタグ
nori
 nori
(@nori)
ゲスト
結合: 23年前
投稿: 9
 

フォーカス移動イベントで、さらにフォーカスが移るような挙動をさせてはいけませ
ん。


返信引用
maru
 maru
(@maru)
ゲスト
結合: 17年前
投稿: 358
 

LeaveイベントでMessageBoxを表示させなければどうなりますか?


返信引用
ほえほえむー
 ほえほえむー
(@ほえほえむー)
ゲスト
結合: 17年前
投稿: 5
Topic starter  

noriさま、maruさま回答ありがとうございます。

noriさま
> フォーカス移動イベントで、さらにフォーカスが移るような挙動をさせてはいけませ
> ん。

今、テキストボックスからフォーカスがはずれるタイミングでその内容をチェックし、
チェックの結果によってはメッセージボックスをYES/NO/CANCELボタン付きで表示し、
ユーザによってキャンセルがクリックされた場合はフォーカス移動をキャンセル、
それ以外なら継続(例えばボタン1のクリックイベントハンドラの内容を実行など)
という動作を実装したいのですが、Leaveイベント以外でこの動作をさせるには
どうすればいいのでしょうか。

maruさま、
> LeaveイベントでMessageBoxを表示させなければどうなりますか?

ボタン1のクリックイベントが実行され、テキストボックス1に
button1をクリックしました。
と表示されます。
Leaveイベントでメッセージを表示しなければならないのか、という意味でしたら、
上に書かせていただいた回答と同じになります。


返信引用
maru
 maru
(@maru)
ゲスト
結合: 17年前
投稿: 358
 

メッセージボックスでYes/Noを選択する必要性がわからないので有効な回答かどうか
わからないのですが、テキストボックスの内容をチェックしたいというのであれば、

フォーカスを失った時に内容をチェックして、入力値が異常な場合はその旨をメッセー
ジボックスで表示し、(必要ならば、テキストボックスの変更しなければならない文字
列を選択状態にする)正常ならなメッセージボックスを表示しない。
Yes/Noを選択するのは、ボタンクリックイベントで実行する。

というのはどうですか?

あなたの実装では正常な入力であっても、フォーカスが移動したときに毎回メッセー
ジボックスで確認を求められ、使いにくいアプリケーションになると思います。
私の案でも、フォーカス移動時には正常値が入力されている必要があるので、テキス
トボックスに正常値を入力するまで、ダイアログを終わることができないという問題
が発生します。通常、テキストボックスの内容の検査は必要になるまで実行しません。
(ダイアログボックス自体をキャンセルで終了する場合、検査する必要はない!)


返信引用
nori
 nori
(@nori)
ゲスト
結合: 23年前
投稿: 9
 

TextBox.Validatingを調べて見てください。


返信引用
gak
 gak
(@gak)
ゲスト
結合: 21年前
投稿: 132
 

とりあえず何が起きているかだけ解説。
> 起こるはずのイベントが起こらない
1、Button 上で WM_LBUTTONDOWN(この後、Button 上で WM_LBUTTONUP されれば
 ボタンクリック完了となる)
2、クリック完了を検知するため Button がマウス入力をキャプチャする
3、TextBox がフォーカスを消失するので WM_KILLFOCUS が通知される
4、TextBox::Leave() で MessageBox 表示
5、MessageBox 表示に伴い WM_CANCELMODE が投げられる
6、[5] に伴い Button がマウス入力をキャプチャしていた状態が解除
7、[6] に伴い Button のクリック関連処理が中止
8、MessageBox 終了
9、TextBox::Leave() 終了

システム側から見れば、プログラム側が [4] を行った時点でボタンのクリックイベント
の中止に(仕様に理解して)同意したとなる。
http://msdn.microsoft.com/en-us/library/ms632615(VS.85).aspx
> WM_CANCELMODE
> the system sends this message to the active window when a dialog box or
> message box is displayed.

フォーカス消失関連処理中に MessageBox を出すのは良い類の行動では無い様子。
http://msdn.microsoft.com/en-us/library/ms646282(VS.85).aspx
> WM_KILLFOCUS
> While processing this message, do not make any function calls that display
> or activate a window.


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました