トリッキーコードネット トップへ戻る   C/C++, Java, Perl, PHP, JavaScript, アルゴリズム, ショートコーディング, IOCCCコードの解説, 等々

サイト情報

トリッキーなコード

7行プログラミング

物凄いコード集

アルゴリズム

データ構造

C/C++な話題

コードサンプル

ツール/環境構築

開発ノウハウ 等

ネタ/ジョーク集

おススメ書籍/サイト

サイトTOP >> コードサンプル >> GetMessage()関数のエラー処理について

GetMessage関数のエラー処理について (Win32API)

さて、以下のコードは、VC++2005で作成される、Win32アプリケーションのテンプレートの一部です。
MSG msg;
HACCEL hAccelTable;

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(「リソースビューのAcceleratorID」));

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

return (int) msg.wParam;
GetMessage()にて、メッセージキューからメッセージを読込みTranslateAccelerator()にて、ショートカットキーの処理を行い、 TranslateMessage()にて、キーボードイベントの変換(*1)を行い、 DispatchMessage()にて、ウィンドウプロシージャへメッセージを送出 *1:WM_CHAR, WM_SYSCHARのポスト という、ありきたりなコードなワケですが、実はこのコード、バグを含んでいます。 工エエェェ(´д`)ェェエエ工 何処にバグがあるのかというと、「GetMessage()の戻り値を、whileループの継続条件にしてしまっているところ」です。 MSDNのGetMessage関数の項目には、 -------------------------------------------------------------------------------- [戻り値] WM_QUIT 以外のメッセージを取得した場合、0 以外の値が返ります。 WM_QUIT メッセージを取得した場合、0 が返ります。 エラーが発生した場合、-1 が返ります。 たとえば、hWnd パラメータで無効なウィンドウハンドルを指定した場合や、lpMsg で無効なポインタを指定した場合は、 エラーが発生します。 拡張エラー情報を取得するには、 関数を使います。 警告 GetMessage 関数は、0 以外の値、0、-1 のいずれかを返します。したがって、次のようなコードは避けてください。 while (GetMessage(lpMsg, hWnd, 0, 0)) ... このようなコードを作成すると、GetMessage 関数が失敗して -1(0xFFFFFFFF、つまり TRUE)が返った場合、 ループが持続し、致命的なアプリケーションエラーを発生させる可能性があります。 -------------------------------------------------------------------------------- とあります。 つまり、冒頭のコードを以下の様に修正すればOKというわけです^^;)
MSG msg;
HACCEL hAccelTable;

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(「リソースビューのAcceleratorID」));

BOOL bRet;

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

return (int) msg.wParam;
BOOL型はint型をtypedefしただけのもの(windef.h参照)なので、 GetMessage()の戻り値として、技術的には「0以外, 0, -1」を返すのはおかしくはないのですが、 それでもやはり、「こんな紛らわしい実装は避けるべきなのではないの~??ねぇねぇMicrosoftさん??」という気がします。 ついでにもう一つ愚痴っておくと、「VC++で生成するコードにバグが含まれてるって、一体なんのご冗談?!」( ゚д゚)ポカーン
         このエントリーをはてなブックマークに追加   


作業効率化・ライフハックのオススメ記事




コンピュータ・テクノロジーのオススメ記事





恋愛・人間関係のオススメ記事




※ 当サイトは、トップページからリンクで辿る事の出来るページに限り、リンクフリーです。
※ 当サイトの閲覧/利用によって生じた如何なる損害も、当サイト管理人は責任を負いません。
※ 当サイトの内容を転載される場合は、当サイトへのリンクをお願い致します。