Tips of VC++ > ダイアログ > ダイアログでアクセラレーターを使うには
前へ戻る次へ進む


ダイアログでアクセラレーターを使うには

モーダルダイアログボックスではアクセラレータキーを使うことができません。 なぜならメッセージループがないからです。 よってモードレスダイアログでソースを書いていきます。

HACCEL LoadAccelerators(
  HINSTANCE hInstance,  // モジュールのハンドル
  LPCTSTR lpTableName   // アクセラレータテーブルの名前
);

まず、アクセラレータテーブルをリソースから読みこみます。 これは簡単。あとは、メッセージループをちょっといじるだけです。

int TranslateAccelerator(
  HWND hWnd,         // 目的のウィンドウのハンドル
  HACCEL hAccTable,  // アクセラレータテーブルのハンドル
  LPMSG lpMsg        // メッセージ情報
);

このAPIはIsDialogMessageと 使い方は同じです。 WM_KEYDOWNメッセージまたはWM_SYSKEYDOWNメッセージを、 WM_COMMAND メッセージまたは WM_SYSCOMMAND メッセージへ変換し ( 指定されたアクセラレータテーブル内に、キーに対応するエントリが存在する場合)、 WM_COMMAND または WM_SYSCOMMAND メッセージを、 適切なウィンドウプロシージャへ直接送信します。 そのとき、この関数はTRUEを返すので、そのメッセージが変換された場合は、 TranslateMessage 関数を使って そのメッセージをもう一度処理するべきではありません。
最後に、ダイアログベースのソースにアクセラレータを追加したものを載せておきます。

const char szClassName[]="アプリケーション名";

LRESULT CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow )
{
    HWND hDlg=::CreateDialog(hAppModule,MAKEINTRESOURCE(IDD_DIALOG1),
        NULL,(DLGPROC)DlgProc);
    ::ShowWindow(hDlg,SW_SHOW);

  MSG msg;
  HACCEL hAccel=::LoadAccelerators(
        hAppModule,MAKEINTRESOURCE(IDR_ACCEL1));
    while ( ::GetMessage(&msg,NULL,0,0) )
    {
        if ( !::TranslateAccelerator(hDlg,hAccel,&msg) &&
             !::IsDialogMessage(hDlg,&msg) )
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
    }

    return 0;
}

LRESULT CALLBACK DlgProc(HWND in_hWnd,
                         UINT in_Message,
                         WPARAM in_wParam,
                         LPARAM in_lParam)
{
    switch ( in_Message )
    {
    case WM_COMMAND:
        switch ( LOWORD(in_wParam) )
        {
        case IDCANCEL:
            ::DestroyWindow(in_hWnd);
            break;
        }
        break;
    case WM_DESTROY:
        ::PostQuitMessage(0);
        break;
    }
    return 0;
}