Mesoscopic Programming

タコさんプログラミング専門

ヌメロン製作講座第3回:キーボードアクセラレータを追加する

こんにちわ。ではさっそくキーボードアクセラレータを追加しましょう。

main.h

~前略~
enum AccelID
{
    ACCEL_NULL = -1,
    ACCEL_FILE_NEW,
    ACCEL_FILE_OPEN,
    ACCEL_FILE_SAVE,
    ACCEL_APP_ABOUT,
    ACCEL_SWITCH_MODE,
    ACCEL_SWITCH_ANAL,
    ACCEL_SWITCH_SECRET,
    ACCEL_CLEAR_RECORD,
    MAX_ACCEL
};

class Application : public Window
{
public :

    static const SHORT  wndWidth    = 640;
    static const SHORT  wndHeight   = 480;
    static LPCTSTR      className;
    static ACCEL        accels[ MAX_ACCEL ];

    HACCEL  hAccel;

    BOOL    Init( HINSTANCE hInstance, int nCmdShow );
    VOID    Run();
    VOID    OnDestroy();
    VOID    OnCommand();
    VOID    OnFileNew();
    VOID    OnFileOpen();
    VOID    OnFileSave();
    VOID    OnAppExit();
    VOID    OnAppAbout();
    VOID    OnSwitchMode();
    VOID    OnSwitchAnal();
    VOID    OnSwitchSecret();
    VOID    OnClearRecord();
};
~後略~

main.cpp

~前略~
ACCEL   Application :: accels[ MAX_ACCEL ]  =
{
    { FVIRTKEY | FNOINVERT | FCONTROL,  'N',    ID_FILE_NEW },
    { FVIRTKEY | FNOINVERT | FCONTROL,  'O',    ID_FILE_OPEN },
    { FVIRTKEY | FNOINVERT | FCONTROL,  'S',    ID_FILE_SAVE },
    { FVIRTKEY | FNOINVERT,             VK_F1,  ID_APP_ABOUT },
    { FVIRTKEY | FNOINVERT,             VK_F2,  ID_SWITCH_MODE },
    { FVIRTKEY | FNOINVERT,             VK_F3,  ID_SWITCH_ANAL },
    { FVIRTKEY | FNOINVERT,             VK_F4,  ID_SWITCH_SECRET },
    { FVIRTKEY | FNOINVERT,             VK_F5,  ID_CLEAR_RECORD },
};

BOOL Application :: Init( HINSTANCE hInstance, int nCmdShow )
{
    WNDCLASSEX  wcx;
    HWND        hWnd;
    HMENU       hMenu;
    HMENU       hSubMenu;

    wcx.cbSize          = sizeof( WNDCLASSEX );
    wcx.style           = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wcx.lpfnWndProc     = Window :: WindowProc;
    wcx.cbClsExtra      = 0;
    wcx.cbWndExtra      = sizeof( HANDLE );
    wcx.hInstance       = hInstance;
    wcx.hIcon           = LoadIcon( NULL, IDI_APPLICATION );
    wcx.hCursor         = LoadCursor( NULL, IDC_ARROW );
    wcx.hbrBackground   = ( HBRUSH ) ( COLOR_MENU + 1 );
    wcx.lpszMenuName    = NULL;
    wcx.lpszClassName   = className;
    wcx.hIconSm         = LoadIcon( NULL, IDI_WINLOGO );

    RegisterClassEx( & wcx );

    hMenu       = CreateMenu();
    hSubMenu    = CreateMenu();

    AppendMenu( hSubMenu,   MF_STRING,      ID_FILE_NEW,            _T( "新規作成(&N)\tCtrl+N" ) );
    AppendMenu( hSubMenu,   MF_STRING,      ID_FILE_OPEN,           _T( "開く(&O)...\tCtrl+O" ) );
    AppendMenu( hSubMenu,   MF_STRING,      ID_FILE_SAVE,           _T( "保存(&S)...\tCtrl+S" ) );
    AppendMenu( hSubMenu,   MF_SEPARATOR,   0,                      NULL );
    AppendMenu( hSubMenu,   MF_STRING,      ID_APP_EXIT,            _T( "終了(&X)\tAlt+F4" ) );
    AppendMenu( hMenu,      MF_POPUP,       ( UINT_PTR ) hSubMenu,  _T( "ファイル(&F)" ) );

    hSubMenu    = CreateMenu();

    AppendMenu( hSubMenu,   MF_STRING,      ID_SWITCH_MODE,         _T( "開始(&P)\tF2" ) );
    AppendMenu( hSubMenu,   MF_STRING,      ID_SWITCH_ANAL,         _T( "分析(&A)\tF3" ) );
    AppendMenu( hSubMenu,   MF_STRING,      ID_SWITCH_SECRET,       _T( "公開(&O)\tF4" ) );
    AppendMenu( hSubMenu,   MF_SEPARATOR,   0,                      NULL );
    AppendMenu( hSubMenu,   MF_STRING,      ID_CLEAR_RECORD,        _T( "棋譜消去(&C)\tF5" ) );
    AppendMenu( hMenu,      MF_POPUP,       ( UINT_PTR ) hSubMenu,  _T( "ゲーム(&G)" ) );

    hSubMenu    = CreateMenu();

    AppendMenu( hSubMenu,   MF_STRING,      ID_APP_ABOUT,           _T( "アバウト(&A)...\tF1" ) );
    AppendMenu( hMenu,      MF_POPUP,       ( UINT_PTR ) hSubMenu,  _T( "ヘルプ(&H)" ) );

    hWnd        = CreateWindow( className, appName,
                                WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
                                CW_USEDEFAULT, CW_USEDEFAULT, wndWidth, wndHeight,
                                NULL, hMenu, hInstance, ( LPVOID ) this );

    hAccel      = CreateAcceleratorTable( accels, MAX_ACCEL );

    ShowWindow( hWnd, nCmdShow );
    UpdateWindow( hWnd );

    return TRUE;
}

VOID Application :: Run()
{
    MSG msg;

    while ( GetMessage( & msg, NULL, 0, 0 ) )
    {
        if ( TranslateAccelerator( hwnd, hAccel, & msg ) == 0 )
        {
            TranslateMessage( & msg );
            DispatchMessage( & msg );
        }
    }
}
~後略~

以上です。

次回はWM_PAINTメッセージに対応しますです。
でわまた、さよおなら。