WINAPI メッセージループ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
苺ぷりん

WINAPI メッセージループ

#1

投稿記事 by 苺ぷりん » 10年前

こんばんわ 苺ぷりんです。
基本的なことなのですが、WINAPIのメッセージループでわからないことがありまして、よろしくお願いします。
[1.1]PeekMessageを用いたメッセージループを作りたい(関数版)

[1.2]

コード:

bool CheckMessage(){
	MSG msg;
	ZeroMemory(&msg, sizeof(MSG));
	while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
		if (msg.message == WM_QUIT){
			gHwnd = NULL;
			return false;
		}
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return true;
}

コード:

bool CheckMessage(){
	MSG msg;
	ZeroMemory(&msg, sizeof(MSG));
	while (GetMessage(&msg, NULL, 0, 0)) {
		if (msg.message == WM_QUIT){
			gHwnd = NULL;
			return false;
		}
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return true;	
}
メッセージを取得してWM_QUITの場合falseを返してループを抜ける
下記みたいな使い方を想定した関数を作っております

コード:

while(ChcekMessage()==true){
}
[1.3]PeekMessageを使うループとそうでないループ
どちらもエラーなく動くのですが
PeekMessageを使った場合、タスクマネージャでCPU使用率を確認したら17%に跳ね上がっておりました。
使わない場合は使用率0%です。
ウィンドウを表示しているだけなのですが、この差はなんでしょうか?
ゲーム関連のループはPeekMessageを使ったほうがいいと書籍等にかいてあったのですが、
コードが間違ってたりしますか?変なことやってたり・・・
ご指摘よろしくおねがいします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: WINAPI メッセージループ

#2

投稿記事 by みけCAT » 10年前

苺ぷりん さんが書きました:PeekMessageを使った場合、タスクマネージャでCPU使用率を確認したら17%に跳ね上がっておりました。
使わない場合は使用率0%です。
ウィンドウを表示しているだけなのですが、この差はなんでしょうか?
ループ中にSleepなどで(ビジーループでない)ウェイトを作っていますか?
GetMessageはメッセージが来るまでブロックするのに対し、PeekMessageはメッセージが来ていなくてもすぐに処理を返すため、他にウェイトを入れなければ高負荷になります。
苺ぷりん さんが書きました:ゲーム関連のループはPeekMessageを使ったほうがいいと書籍等にかいてあったのですが
確かにフレームレートの管理などが必要なゲームでは、勝手に処理が遅延しないPeekMessageの方が適しています。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

苺ぷりん

Re: WINAPI メッセージループ

#3

投稿記事 by 苺ぷりん » 10年前

みけCATさん 回答ありがとうございます。

ループ中にSleep等などまったく使っていませんでした。
PeekMessageを使うと、ループの数が多くってしまうため重くなってしますんですね。

ビジーループ(ビジーウェイト?)とは「キーボードからの入力を待ったり」とかなんとか検索したら
でてきました。ピンときませんでしたが、「ゲームプログラミングの館」の「特定のFPSで動作させる方法」
みたいな感じでSleep等を使ってループ数を決めてあげればいいんですね。

一度挑戦してみたいと思います。ありがとうございました。

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: WINAPI メッセージループ

#4

投稿記事 by usao » 10年前

オフトピック
PeekMessageを使ったループ書くときは
PeekMessage( PM_REMOVE ) で良い気がするのだけれど,
検索すると,例えば
http://eternalwindows.jp/graphics/bitmap/bitmap18.html
の一番下みたく,
PeekMessage( PM_NOREMOVE )でメッセージの有無だけを確認 → GetMessage()でメッセージを取り出す
という2度手間っぽい書き方を結構見かけるのが気になる.これって何か利点があるのだろうか?

閉鎖

“C言語何でも質問掲示板” へ戻る