GetMessage の罠

VC.net(2003)、VC2005、VC2008 でプロジェクトを作成すると、以下のようなテンプレートのソースコードでプロジェクトが作成される。

// メイン メッセージ ループ:
while (GetMessage(&msg, NULL, 0, 0))
{
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

だけど、これは間違い。
http://msdn.microsoft.com/ja-jp/library/cc364699.aspx によると:

警告 GetMessage 関数は、0 以外の値、0、-1 のいずれかを返します。したがって、次のようなコードは避けてください。

while (GetMessage(lpMsg, hWnd, 0, 0)) ...

このようなコードを作成すると、GetMessage 関数が失敗して -1(0xFFFFFFFF、つまり TRUE)が返った場合、ループが持続し、致命的なアプリケーションエラーを発生させる可能性があります。

ということで、戻り値は BOOL なのに

  • 0
  • -1
  • それ以外

を返すという仕様になっている。

テンプレートを直せ、とか思わないでもない。

VC2010 はどうなってんだろう?

正解

正解はこんな感じ。

BOOL b;
while ((b = GetMessage(&msg, NULL, 0, 0)) != 0) {
    if (b == -1) {
        break;
    }
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}