WindowsフォームアプリケーションでのPeekMessage()の使い方

このQ&Aのポイント
  • Windowsフォームアプリケーションで、ループさせたいイベント内で別のイベントを行いたい場合にはPeekMessage()を使用します。
  • ただし、PeekMessage()の使い方に注意が必要です。
  • アプリケーション起動後、button1をクリックし、後にbutton2をクリックしようとすると代わりにbutton1がクリックされる現象が発生しています。
回答を見る
  • ベストアンサー

PeekMessage()について

Windowsフォームアプリケーションです。 ループさせたいイベント(button1)中に、button2のイベントを行いたいのでPeekMessage()を使って以下のようにしました。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { while(1){ PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); TranslateMessage(&msg); DispatchMessage(&msg); // ループさせたいイベント ・・・・・・・・・・・・・・・・・・・・ } } private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {    ・・・・・・・・・・・・・・・・・・・・ } アプリケーション起動後、button1をクリックし、後にbutton2をクリックしようとすると代わりにbutton1がクリックされてしまいます。 PeekMessage()の使い方が間違っているのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8516/19359)
回答No.1

ボタンも「ウィンドゥハンドルを持つ、ウィンドゥの1つ」だから PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); ってやると「現在のウィンドゥ」つまり「button1のウィンドゥ」に対してディスパッチとメッセージ送信するよ。 つまり「button2をクリックするとbutton1に通知される」よ。 >ループさせたいイベント(button1)中に、button2のイベントを行いたい こういう時は http://wikiwiki.jp/dxlibfunc/?%B4%D8%BF%F4%2FProcessMessage とかを使おう。 C++Builderの場合は http://www.geocities.co.jp/siliconvalley/6071/technic/26.html を使う。 VC++の場合は、ループの中で Sleep(0); ってやればオッケー。 ともかく、イベント処理の中で、PeekMessageやDispatchMessageをやるのはナンセンス。

miyaneya0
質問者

お礼

回答有り難うございます。 VS2010C++なのでSleep(0)を使いましたがうまくいきません。 改めてSleep(0)について質問しようと思います。

その他の回答 (1)

  • chie65535
  • ベストアンサー率43% (8516/19359)
回答No.2

当然だけど、ProcessMessage()や、Application->ProcessMessages()や、Slep(0)をループ内で呼ぶと、button1のイベント処理中に更にbutton1が押せてしまい、button1を押せば再帰的にイベントが呼ばれるので注意しよう。 再帰的に呼ばれては困る場合には、ループに入る前にbutton1を非アクティブにするか、イベント処理関数に飛んでこないように工夫しないといけない。当然、ループから抜けたら、元に戻すのを忘れずに。

miyaneya0
質問者

お礼

更なるご指示ありがとうございます。 参考にさせて頂きます。

関連するQ&A

  • Sleep(0)について

    VS2010C++でWindowsフォームアプリケーションをつくろうとしています。 ループさせたいイベント(button1)中に、button2のイベントを行いたいのでSleep(0)を使って以下のようにしました。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { while(1){ Sleep(0); // ループさせたいイベント ・・・・・・・・・・・・・・・・・・・・ } } private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {    ・・・・・・・・・・・・・・・・・・・・ } アプリケーション起動後button1をクリックすると、Sleep(0)が無いときと同じようにボタンを受け付けなくなります。 Sleep(0)の使い方が間違っているのでしょうか。

  • イベントハンドラ関数について

    現在VC++/CLR 2005 でプログラミングをしています。 基本的な事柄かもしれませんが、質問させてください  以下の2つのボタンのイベントハンドラ関数があった場合 //ボタン1のイベントハンドラ関数 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) String^ str = textBox1->Text } //ボタン2のイベントハンドラ関数 private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { } ボタン2をクリックしたときの動作とボタン1の動作を同じにしたいと思っています。 その場合は private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) String^ str = textBox1->Text } //ボタン2のイベントハンドラ関数 private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { String^ str = textBox1->Text } のようにボタン2のイベントハンドラ関数をボタン1と同じように書けばいいのですが イベントハンドラ関数の処理が膨大になった場合を考えて省略する 書き方は無いのでしょうか?(以下の場合ですとエラーが起こってしまいます。) private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { button1_Click(); } 宜しくお願いします

  • C#での書き方

    vb.netでは別のイベントを呼び出すとき下記のような書き方ができたのですが、C#ではどう書くんでしょうか? (ボタン2を押したらボタン1の処理が走る) Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click MessageBox.Show("AAA") End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Button1_Click(sender, e) End Sub

  • VC#2008の動作について

    VC#2008について、下記の場合、button1をクリックし、 その次に、button2をクリックしても全く反応しません。 どのように改良すれば反応しますか? 処理が重く止まったと感じた時、メッセージを表示した後、 アプリケーションを終了したいと思っています。 どなたかご存知の方、教えていただけないでしょうか? 宜しくお願い致します。 namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1(){ InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(10000000); } private void button2_Click(object sender, EventArgs e) { MessageBox.Show("close"); System.Diagnostics.Process[] p = System.Diagnostics.Process.GetProcessesByName("myapp"); foreach (System.Diagnostics.Process k in p) { k.Kill(); } } } }

  • C++でメッセージボックスを表示したい

    C++でメッセージボックスを表示したい フォーム上にbutton1を設置しました。 クリックして、メッセージボックスを表示したいのですがどうすればいいのかわかりません。 vb.netで言う Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click MessageBox.Show("test") End Sub をC++で書くとどうなるんですか? button1をダブルクリックして private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { } }; を表示させたのですが、どこにMessageBoxを入れればいいのか教えてください。 よろしくお願いします。

  • 他のFormのクリックイベント

    教えてください! 他のFormのクリックイベントを実行できますか? Form2のButton2をクリックした時に、Form1の「Button1_Click」を実行させることができますか? 出来るとしたら、Form2の「Button2_Click」にはどのように記載したらいいのでしょうか? [Form1]より Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs)・・・ [Form2]より Private Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs)・・・ End Sub 宜しくお願いします。

  • コンボボックスの削除の仕方

    コンボボックスのリストの削除はどうしたらよいでしょうか。 private: System::Void comboBox1_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) { index = comboBox1->SelectedIndex; cout << "index=" << index << "\n"; } private: System::Void button2_Click_1(System::Object^ sender, System::EventArgs^ e) { //comboBoxからデータ削除 comboBox1->Items->RemoveAt(index); このようなコードを書いてみましたがうまくいいきません。

  • C#プログラムにて

    C#プログラムにて お世話になります。 C#初心者です。 プログラムコードを書き始めで、早速行き 詰っています。 ステップでコードの動きを確認したところ、 program.csのMainから下記のForm1.csに 移りForm1のデザイナが表示されるのですが、 button3を押してもForm3が表れません。 また、ステップの黄色いカーソルと言いますか ステップの位置情報も消えています。 何がどう悪いのか分からなく困っています。 どなたかご親切な方、ご教授頂きたく 宜しくお願い致します。     記 using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication3 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void button3_Click(object sender, EventArgs e) { Form3 cForm3 = new Form3(); cForm3.ShowDialog(); } private void button2_Click(object sender, EventArgs e) { DialogResult ans; ans = MessageBox.Show("最新のコード表を照会しますか?", "Microsoft Visual Studio", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ans == DialogResult.OK) Application.Exit(); } private void button12_Click(object sender, EventArgs e) { Form4 cForm4 = new Form4(); cForm4.ShowDialog(); } } }

  • C#でオブジェクトの有無を取得する

    オブジェクトが作られている時と作られていない時で処理をわけたいのですがうまくいきません。 この書き方の何がまずいのでしょうか? namespace オブジェクト検索 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Control c = Controls["form2"]; if (c != null) { ((TextBox)c).Text += "*"; } } private void button2_Click(object sender, EventArgs e) { Form2 form2 = new Form2(); form2.Show(); Application.DoEvents(); } } } ボタン2を押した時に新しいフォームが立ち上がり、そのフォームがあるときは*が出るようにしたいです。

  • VSのButtonについて

    VS2010でWindowsアプリを作成しようとButtonを配置しましたが、ボタンをクリックする度にメモリ使用量が8KB増えてしまいます。(タスクマネージャーによる確認) 何故でしょうか。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {      // 何もコードを書いていません。      // 他の場所にもコードは追加していません。 }

専門家に質問してみよう