おひさしぶりです。
今回は、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”と出力してアプリが終了しています。

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