Programming Windows Maniacs - プログラミング ウィンドウズ マニアックス ■ ご利用に際して ■ 更新履歴 ■ お問い合わせ ■ このホームページについて  
ホーム >> シェル >> 特定のキーで何か動作をさせるには(ホットキー)

特定のキーで何か動作をさせるには(ホットキー)

  特定のキーが押された際に、アプリケーションが非アクティブでも非表示でもメッセージを取得することができる仕組みがあります。
  これは、ホットキーというものです。

  ショートカットファイルを右クリックし[プロパティ]を表示し、[ショートカット]タブの「ショートカットキー」という項目は、このホットキーを使用しています。
  ホットキーはプログラムで記載することが可能ですので、「特定のキーを押した際に、ある動作をさせる」のようなプログラムを作成することが可能です。

  ホットキーを登録するには、グローバルなATOM値を使用して、RegisterHotKey () APIによりホットキーを登録します。
  登録の際ホットキーは、ウィンドウと関連付けることができ、登録したキーが押された際、そのウィンドウに WM_HOTKEY メッセージが送付されます。

  登録を解除するときは、UnregisterHotKey () APIを使用します。

ホットキーを登録するは、以下の項目に注意してください。
(1) ATOM値が重ならないようにする。もし重なった場合は、重ならないものが生成されるまで、文字列を作成するのが普通です。ただし、10回ほど失敗した場合は登録をやめてエラーにしましょう。メモリがないと登録に失敗するので、永久ループの可能性が出てきます。
(2) 普段アプリケーションが使用するようなキーは登録しない(例えば、Ctrl + 'C'など)。

以下は Shift + Ctrl + Alt + H を押した際にメッセージが表示されるサンプルになります。

 

■■■ hotkey プロジェクト
■ main.cpp

#include <windows.h>
#include <tchar.h>

#include "resource.h"

ATOM g_atom = 0;

void Unregister ( HWND hWnd )
{
    if ( 0 != g_atom )
    {
        if ( !UnregisterHotKey ( hWnd, g_atom ) )
        {
            MessageBox ( hWnd,
                _TEXT ( "Ctrl + Alt + Shift + H をホットキーとして登録解除できません" ),
                _TEXT ( "エラー" ),
                MB_OK | MB_ICONSTOP );
        }
        else
        {
            MessageBox ( hWnd,
                _TEXT ( "Ctrl + Alt + Shift + H キーが登録解除されました" ),
                _TEXT ( "確認" ),
                MB_OK );
            EnableWindow ( GetDlgItem ( hWnd, IDC_REGISTER_BUTTON ), TRUE );        
            EnableWindow ( GetDlgItem ( hWnd, IDC_UNREGISTER_BUTTON ), FALSE );
            
            g_atom = 0;
        }
    }
}

BOOL CALLBACK DialogFunc ( HWND hWnd,
    UINT nMessage,
    WPARAM wParam,
    LPARAM lParam )
{
    switch ( nMessage ) {
    case WM_INITDIALOG:
        EnableWindow ( GetDlgItem ( hWnd, IDC_UNREGISTER_BUTTON ), FALSE );        
        return TRUE;
    case WM_COMMAND:
        switch ( LOWORD ( wParam ) ) {
        case IDC_REGISTER_BUTTON:
            {
                // ATOM登録
                g_atom = GlobalAddAtom ( _TEXT ( "SamHK" ) );
                if ( 0 == g_atom )
                {
                    MessageBox ( hWnd,
                        _TEXT ( "すでにATOM \"SamHK\" が登録されています" ),
                        _TEXT ( "エラー" ),
                        MB_OK | MB_ICONSTOP );
                    return TRUE;
                }

                // ホットキー登録
                if ( !RegisterHotKey ( hWnd, g_atom, MOD_ALT | MOD_CONTROL | MOD_SHIFT, _TEXT ( 'H' ) ) )
                {
                    MessageBox ( hWnd,
                        _TEXT ( "Ctrl + Alt + Shift + H をホットキーとして登録できません" ),
                        _TEXT ( "エラー" ),
                        MB_OK | MB_ICONSTOP );
                }
                else
                {
                    MessageBox ( hWnd,
                        _TEXT ( "Ctrl + Alt + Shift + H キーが登録されました" ),
                        _TEXT ( "確認" ),
                        MB_OK );

                    EnableWindow ( GetDlgItem ( hWnd, IDC_REGISTER_BUTTON ), FALSE );        
                    EnableWindow ( GetDlgItem ( hWnd, IDC_UNREGISTER_BUTTON ), TRUE );        
                }
            }
            return TRUE;
        case IDC_UNREGISTER_BUTTON:
            {
                Unregister ( hWnd );
            }
            return TRUE;
        case IDCANCEL:
        case IDOK:
            Unregister ( hWnd );
            EndDialog ( hWnd, 0 );
            return TRUE;
        }
    case WM_HOTKEY:
        {
            WORD wKey;
            wKey = HIWORD ( lParam );
            WORD wModKey;
            wModKey = LOWORD ( lParam );
            if ( _TEXT ( 'H' ) == wKey
                && ( MOD_ALT | MOD_CONTROL | MOD_SHIFT ) == wModKey )
            {
                MessageBox ( hWnd,
                    _TEXT ( "Ctrl + Alt + Shift + H キーが押されました" ),
                    _TEXT ( "確認" ),
                    MB_OK );
            }
        }
        return TRUE;
    }

    return FALSE;
}


int WINAPI _tWinMain ( HINSTANCE hThisInstance,
    HINSTANCE,
    _TCHAR *,
    int )
{
    int nResponse;
    nResponse = DialogBox ( hThisInstance,
        MAKEINTRESOURCE ( IDD_MAIN_DIALOG ),
        NULL,
        DialogFunc );

    return nResponse;
}
■ resource.h
#define IDD_MAIN_DIALOG                 101
#define IDC_REGISTER_BUTTON             1000
#define IDC_UNREGISTER_BUTTON           1001
■ resrc.rc
#include "resource.h"

#include <winres.h>

IDD_MAIN_DIALOG DIALOG DISCARDABLE  0, 0, 87, 72
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "ホットキー サンプル"
FONT 9, "MS Pゴシック"
BEGIN
    PUSHBUTTON      "登録(&R)",IDC_REGISTER_BUTTON,18,12,50,14
    PUSHBUTTON      "解除(&U)",IDC_UNREGISTER_BUTTON,18,42,50,14
END

  ■ ご利用に際して ■ 更新履歴 ■ お問い合わせ ■ このホームページについて Copyright © 2014 A.Morita