GetMessageにかかる負担について

解決


匿名希望  2005-05-30 21:23:26  No: 57615

簡易シューティングを作ってみようと思い、現在縦スクロールにて敵が上から下に移動しながら落ちてくるところまでを作成しました。

一応60FPSまでに抑えてあるのですが、画面になんらかの動作(マウス移動やキー押下)を起こし、GetMessageが送られるところで異常に処理落ちしまいます。

まだキーやマウスの判定は入れておらず、ESCで終了とWM_DESTROYくらいです。

一応抜粋:
LRESULT CALLBACK CGAME::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
      case WM_KEYDOWN:
        switch(wParam)
        {
          case VK_ESCAPE:
            SendMessage(hWnd, WM_DESTROY, 0, 0);
            break;
        }
        break;
      case WM_DESTROY:
        ShowCursor(TRUE);
        PostQuitMessage(0);
        break;
      default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}

また、GetMessageに行く前にはPeekMessageで判定するようにしています。
さらに抜粋:
if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)){    
  if (GetMessage(&Msg, NULL, 0, 0)){
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
  }
}

デバッグとしてGetMessageだけを仮にコメントとしてみたところ問題なくスムーズに動きます。
また、ウィンドウプロシージャ内を全てコメント化もしてみました。(本当はダメですが)
それでもやはり処理落ちしてしまいます。
GetMessageの後の処理がまったくない状態でも処理落ちしてしまうところからGetMessage自体に処理がかかっている気がします。
意味不明です(´・ω・`)

キーを押しっぱなしですとたしかにWM_KEYDOWNやWM_CHAR等のメッセージが
常に送られてくるとは思うのですが処理落ちするくらいの重さなのでしょうか?

環境はXP,VC6になります。


Ban  2005-05-30 22:51:36  No: 57616

ぱっと見、PeekMessage の引数が REMOVE なのはダメっぽい。

これだとメッセージが来ていたとしても、そのメッセージが削除対象に
なるわけで。そうすると、そのメッセージが処理されないまま
(Translate〜やDispatch を経る前に) GetMessage で次の
メッセージを待ってませんか?

# KEYDOWN は連続するとリピート回数でまとめられるはず。


Ban  2005-05-30 22:55:14  No: 57617

# 余談

>  if (GetMessage(&Msg, NULL, 0, 0)){

上の書き方では、GetMessage でエラーが発生しても(-1が返っても)抜けられません。

<MSDN>
WM_QUIT 以外のメッセージを取得した場合、0 以外の値が返ります。
WM_QUIT メッセージを取得した場合、0 が返ります。
エラーが発生した場合、-1 が返ります。
</MSDN>


匿名希望  2005-05-30 23:13:12  No: 57618

Banさん回答ありがとうございます。

ご指摘の通りPeekMessageをPM_NOREMOVEに変更したところ問題なく稼動しました。
的確な回答ありがとうございます。
助かりました。

さらに上記の文から質問してよろしいでしょうか?(ほんとはダメかもですが)

PeekMessageでメッセージを受け取りキューから削除できるということは
GetMessageの意味はあるのでしょうか?


Ban  2005-05-31 00:45:03  No: 57619

# Peek〜するときは、NOREMOVE がお約束なので。

> さらに上記の文から質問してよろしいでしょうか?(ほんとはダメかもですが)

私のわかる範囲ならどうぞ....(分らない場合でも他の識者に期待してどうぞ

> PeekMessageでメッセージを受け取りキューから削除できるということは
> GetMessageの意味はあるのでしょうか?

GetMessage は、メッセージが来るまでブロッキングします。
つまり、その間CPU時間を消費しません。
PeekMessage はポーリングなので、ウェイとなしでループをまわすと、
CPU100% になったり、他のプロセスに制御が回りにくくなったりします。
なので、適材適所で使い分けるために二個あるのでしょう。


匿名希望  2005-05-31 02:28:42  No: 57620

またまたありがとうございます。

やっと理解しました^^;

うまく使いわけていきたいと思います。


匿名希望  2005-05-31 02:29:10  No: 57621

解決とさせて頂きます。


Ban  2005-05-31 06:17:38  No: 57622

# まぁWaitMessage ってのも別途あるので、コレと Peek を組み合わせれば
# 上の問題もほぼ解決ですが。GetMessage は多分、メッセージループ用の
# 省略形なんじゃないかと思います。(WM_QUIT の扱いとか....)


匿名希望  2005-05-31 17:50:35  No: 57623

さらに詳しい詳細ありがとうございます。

関数の用途をよく調べてみようと思います。

助かりました<(_ _)>


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加