
確認したいのですが、
MSG msg;
while(TRUE)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
{
return (int) msg.wParam;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
}
}
このPeekMessageというものですがキューに溜めているということでいいのでしょうか。
後、
MSG msg;
while(TRUE)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(!GetMessage(&msg,NULL,0,0))
{
return (int) msg.wParam;
}
if(msg.message==WM_QUIT)
{
return (int) msg.wParam;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
}
}
のif(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(!GetMessage(&msg,NULL,0,0))
{
return (int) msg.wParam;
}
はキューから出してGetMessageは待機してるということでいいのでしょか?
if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
{
if(!GetMessage(&msg,NULL,0,0))
{
return (int) msg.wParam;
}
これはキューの中は出さないで、GetMessageでPeekMessageからのキューを出しているということでいいのでしょか?
No.3ベストアンサー
- 回答日時:
「キューからメッセージを取り出して消える」ってのが分かってないのでしょうか。
もしくは、PeekMessageやGetMessageが、引数のmsgを書き換えるというのが分からないのでしょうか。
基本的に、せっかくGetなりPeekなりでメッセージを取得しても、
TranslateMessage & DispatchMessageにそのデータを渡さなければ意味がありません。
[A]の前の時点でキューに、
メッセージ1
メッセージ2
メッセージ3
と格納されていたとして、PeekMessageでREMOVE成功した[B]の時点では、
メッセージ2
メッセージ3
になります。メッセージ1の情報はmsgに取り出された状態で、キューからはREMOVEされます。
そして、GetMessageに成功した[C]の時点では
メッセージ3
になります。メッセージ2の情報はmsgに取り出された状態で、キューからはREMOVEされます。
そして、同時にその前まで[A]でmsgに格納していたメッセージ1の情報は、
GetMessageによって上書きされて失われます。既にキューにもありません。
メッセージ1は一度もTranslateMessage&DispatchMessageに渡されませんでした。
[C]に渡すのはあくまでGetMessageの引数であるmsg(=メッセージ2)であって、
メッセージ1ではありません。メッセージ1はTranslateもDispatchもされずに終わりました。
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))// <- ここでmsgにメッセージ1を取得(キューから削除) [A]
{
if(!GetMessage(&msg,NULL,0,0))// <- ここで、メッセージ1が格納されたmsgにメッセージ2を上書き [B]
{
return (int) msg.wParam;
}
if(msg.message==WM_QUIT)
{
return (int) msg.wParam;
}
TranslateMessage(&msg);// <- ここで渡しているmsgはメッセージ2 [C]
DispatchMessage(&msg);
}
ゆえに、PeekMessageで取得したmsg(=メッセージ1)はTranslateMessage&DispatchMessageに渡ることがありません。
わかりやすい回答ありがとうございます。メッセージ1が通ることがなく1つ飛ばしてしまうからバグが発生すると言ってもいいのでしょうか。わかりました。何回も説明ありがとうございました。
No.2
- 回答日時:
メッセージキューの話で言えば、
・GetMessage:成功すれば取り出したメッセージがキューから消えます。
・PeekMessage(REMOVE):成功すれば取り出したメッセージがキューから消えます。
・PeekMessage(NOREMOVE):メッセージはキューから消えません。
そして、キューからメッセージが消えた場合、そのメッセージは引数のmsgに入ってます。
(NOREMOVEでない限り、同じものを二回取り出すことはできません)
> PeekMessageによってキューから取り出して
> またGetMessageが待機してキューからまた取り直して
> 前のpeekMessageによって取り出されたキューは消されてしまういうことでよろしいのでしょうか?
REMOVEを指定している以上、取り出したメッセージは勿論キューから消えますので、
GetMessageが取り出すのはその次のメッセージになります。
そして、PeekMessageの引数msgに取り出した最初のメッセージは、
何も処理されないまま、GetMessageの引数として上書きされています。
> msgにGetMessageで渡された値が次のPeekMessageでバグってしまうと言うことでしょうか?
いいえ。
> なぜバグってしまうのでしょうか?
Windowsのルールでは、基本的に、受け取ったメッセージは
TranslateMessage(&msg);
DispatchMessage(&msg);
に渡してあげる必要があります。
PeekMessage(NOREMOVE)であれば、キューからメッセージを捨てないので、
もう一度GetMessageすればそのメッセージが取得でき、Translate&Dispatchが可能ですが、
提示のPeekMessage(REMOVE)の例では、PeekMessageでmsg構造体に格納したデータを、
次のGetMessageで上書きしており、そのmsgはTranslate&Dispatchされません。
したがって、Windows OSから通知されるメッセージが予期せず歯抜けし、おかしな挙動をする可能性があります。(←バグ)
回答ありがとうございます。GetMessageで上書きとかいてありますが、
上書きしたらしたで、なぜTranslate&Dispatchされないのでしょうか?GetMessageメッセージでmsgを取得しているのに・・・勉強不足ですみません。
No.1
- 回答日時:
MSDNを読んでください。
> このPeekMessageというものですがキューに溜めているということでいいのでしょうか。
いいえ。PeekMessageにキューに溜める機能はありません。
PM_REMOVEを指定してますので、キューから取り出してます。
(GetMessageとはブロッキングの有無などが違います)
> はキューから出してGetMessageは待機してるということでいいのでしょか?
PeekMessageでキュー内からmsgを取り出した場合(PeekMessageが0以外を返す)に、
GetMessageで待機して次のキューを取り出しmsgを上書きしていますので、
最初のPeekMessageで取り出したmsgは処理せずに捨ててます。
(つまり、バグってます)
> これはキューの中は出さないで、GetMessageでPeekMessageからのキューを出しているということでいいのでしょか?
PeekMessageでキューの中身があれば(この時点ではキューの中身を取り出さず)、GetMessageでその中身を取得しています。
PeekMessage自体は予めキューにメッセージがあるか確認しているだけで、
PeekMessageがキューにメッセージを溜めているわけではありません。
GetMessageもPeekMessageもキューの中身を取り出すためのAPIで、
キューに溜める機能はありません。(通常はシステムが溜めます。自分で溜めるには例えばPostMessage等を使います)
GetMessageはキューの中身がなければキューイングされるまで待ちます。
PeekMessageはキューの中身がなければ無かったといって処理を返します。
また、PeekMessageは、その際にキューの中身を消すか否かを選択できます。
(つまり、削除せずに中身があるか確認することもできますし、削除してしまうこともできます)
わかりやすい説明ありがとうございます。まとめると
> はキューから出してGetMessageは待機してるということでいいのでしょか?
は、PeekMessageによってキューから取り出してまたGetMessageが待機してキューからまた取り直して前のpeekMessageによって取り出された
キューは消されてしまういうことでよろしいのでしょうか?そして
msgにGetMessageで渡された値が次のPeekMessageでバグってしまうと言うことでしょうか?なぜバグってしまうのでしょうか?どうかご教授よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript javascriptで入力フォームが空欄の時にアラートによるエラーを出すコードを書いています。 2 2023/06/13 17:58
- JavaScript セレクトを全て選択されていないと、文字によるエラーメッセージを表示させるコードを調べています 2 2023/06/22 15:48
- JavaScript 入力フォームの javascript で メールアドレスの正規チェックをを行い、ボタンをクリックして 2 2022/04/27 16:06
- HTML・CSS ボタンをクリックした時に、入力フォームのすぐ下部に、「入力欄が空白です」というテキストメッセージが表 1 2022/04/27 16:25
- FX・外国為替取引 mql4のコンパイルエラー箇所の修正お願いします。 1 2023/03/15 16:14
- Excel(エクセル) エクセルVBA Msgboxでの変数の活用 4 2023/07/23 08:33
- PHP php ログイン 1 2022/11/01 00:24
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- JavaScript Javascriptが機能せず原因が分からないので教えて頂きたいです 3 2023/06/04 14:50
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エディットボックスの背景の色...
-
エラー Run-Time Check Failur...
-
C#のswitch文を簡略化したいの...
-
オーバーレイみたいな処理がしたい
-
Win32APIでウィンドウを中央に...
-
ポップアップメニュー
-
WinAPIでの画像高速切り替え表...
-
C言語win32api、エディットボッ...
-
ウィンドウハンドルがメッセー...
-
Win32のファイルダイアログのサ...
-
Enterキーを押されたら次の処理...
-
数字以外が入力されたらエラー...
-
「Aに対するBの割合」と「Aに対...
-
10個出力で改行したいのですが...
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
Aの値からBの値を除するとは??
-
ラグランジュの補間法のCプログ...
-
エクセルで可視セルにのみ値貼...
-
DWORDの実際の型は何でしょうか
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エディットボックスの背景の色...
-
ダイアログプログラムでEnterキ...
-
エラー Run-Time Check Failur...
-
プログラミングでエラーが出ま...
-
ボタンの色(WINAPI)
-
Win32APIでウィンドウを中央に...
-
C言語win32api、エディットボッ...
-
C#のswitch文を簡略化したいの...
-
ウィンドウ非表示に時に表示し...
-
不明なエラー
-
COMPORTマルチスレッドで例外発生
-
WM_CREATE について
-
コンソールアプリケーションの...
-
別関数に渡す変数のポインタが...
-
作成プログラムを常にアクティ...
-
DialogBox
-
【Windowsアプリ】ファイルのド...
-
オーバーレイみたいな処理がしたい
-
ボタンのアイコン表示
-
ウィンドウのサイズ変更について
おすすめ情報