pythonでホットキーの取得方法[pywin32 画面外からショートカットキーを取得する方法 windowproc]

Python
この記事は約5分で読めます。

おひさしぶりです。
今回は、PythonでWindowsのショートカットキーを実行画面以外から取得する方法について紹介します。
たとえば、Ctrl+Cを入力するとテキストがコピーされますが、そういったイメージで違うアプリにフォーカスが当たっていても、実行したPythonアプリでキー入力を取得できるようになります。

ホットキーとは

まず、今回のように画面外にいてもキー入力を取得できる機能のことホットキーを言います。

正確には、特定のキーとウィンドウ(アプリ)でWindowに対して登録しておくと、どのような画面にいてもそのアプリでのキー入力をキャンセルし、登録したウィンドウのWM_HOTKEYとして通知されてくるものです。
このホットキーはショートカットキーとは別ものとなります。ショートカットキーはフォーカスが当たっているアプリ内でのみ動作するキー入力イベントのことを言います。

ライブラリのインストール

これで、これから何をしたいのかをひとまず理解いただけたかと思います。
ではこのプログラムを作るにあたって、Windowsから通知を受け取るために1つライブラリをインストールする必要がありますのでそれについて紹介します。

今回インストールするライブラリは、pywin32というものです。
windowsでアプリの開発をしていた方は聞いたことがあると思いますが、そうですこれはwin32apiを使用するためのライブラリとなります。

インストールはいつも通りコマンドプロンプトを起動して、以下のコマンドを実行すればインストールできます。

pip install pywin32

以下のような感じでインストールできます。

プログラム全体

ここまでで、プログラミングをするための準備は完了しました。
まずは、いつも通り今回作成したプログラムの全体を記載します。

このプログラムでは、「Ctrl+Shift+A」をクリックするとアプリが終了するように組んであります。

import threading 
from ctypes import *          # windll 使用のため
from ctypes.wintypes import * # handle取得のため
import win32api,win32gui,win32con # win32のAPI使用のため

#ホットキーIDは このプログラムで使用するための物なので適当な値を設定する
#0x0000-0xBFFFの間で設定
HOTKEY_ID_1 = 0x0001
exit_flg = False

def Regist_selfhotkey():
    global exit_flg
    try:
        hInstance  = win32api.GetModuleHandle(None)
        CLASS_NAME   = "myAppl"
        lpWindowName = CLASS_NAME
        
        wc = win32gui.WNDCLASS()
        wc.lpfnWndProc = WindowProc
        wc.hInstance = hInstance
        wc.lpszClassName = CLASS_NAME
        win32gui.RegisterClass(wc)
        
        hwnd = win32gui.CreateWindowEx(0,CLASS_NAME,lpWindowName,win32con.WS_OVERLAPPEDWINDOW,
                                       win32con.CW_USEDEFAULT,win32con.CW_USEDEFAULT,win32con.CW_USEDEFAULT,
                                       win32con.CW_USEDEFAULT,None,None,hInstance,None)
        
        if hwnd != None:
            windll.user32.RegisterHotKey(hwnd,HOTKEY_ID_1,win32con.MOD_CONTROL | win32con.MOD_SHIFT,0x41)

        msg = MSG()
        while (windll.user32.GetMessageW(pointer(msg),0,0,0)):
            windll.user32.TranslateMessage(pointer(msg))
            windll.user32.DispatchMessageW(pointer(msg))
            if exit_flg == True:
                break
    finally:
        windll.user32.UnregisterHotKey(None,HOTKEY_ID_1)    
    

def WindowProc(hwnd,uMsg,wParam,lPram):
    global exit_flg
    if uMsg == win32con.WM_HOTKEY:
        if wParam == HOTKEY_ID_1:
            print("receive Ctrl Shift A")
            exit_flg = True
    return windll.user32.DefWindowProcW(hwnd,uMsg,wParam,lPram)

def main():
    Regist_selfhotkey()
    

if __name__ == '__main__':
    main()

実行結果は以下の通りで、「Ctrl+Shift+A」が入力入力されると”receive Ctrl Shift A”と出力してアプリが終了しています。

続いてはプログラムの解説ですが、解説は次ページにて記載します。

コメント

タイトルとURLをコピーしました