1
2

More than 1 year has passed since last update.

[Python] マウスカーソルの形状判定

Last updated at Posted at 2023-08-28

はじめに

pyautoguiでマウスカーソル形状で判定するためにwin32gui.GetCursorInfo()で状態を取得していましたが、返り値であるハンドルがどの形状を表しているのかいまいちわかっていなかったので調べてみました。

マウスカーソル形状の種類

そもそもWindows標準のマウスカーソル形状は以下のようなものがあるようです。
(画像引用元:https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/617changecursor/changecursor.html
image.png

win32gui.GetCursorInfo()で得られる返り値

参考としたサイトから、win32con.IDC_*で設定される定数から、win32gui.LoadCursor(0, win32con.IDC_*)でハンドルが得られることがわかりました。

返り値 win32con
定数名
win32con
定数値
意味
65561 IDC_APPSTARTING 32650 標準の矢印カーソルと小さい砂時計カーソル
65539 IDC_ARROW 32512 標準の矢印カーソル
65545 IDC_CROSS 32515 十字カーソル
65567 IDC_HAND 32649 Windows 2000:ハンドカーソル
65563 IDC_HELP 32651 矢印と疑問符
65541 IDC_IBEAM 32513 アイビーム( 縦線)カーソル
0 IDC_ICON 32641 使われていない*。代わりにIDC_ARROWを使う。
65559 IDC_NO 32648 禁止カーソル( 円に左上から右下への斜線)
0 IDC_SIZE 32640 使われていない*。代わりに IDC_SIZEALL を使う。
65557 IDC_SIZEALL 32646 4 方向の矢印カーソル
65551 IDC_SIZENESW 32643 右上と左下を指す両方向矢印カーソル
65555 IDC_SIZENS 32645 上下を指す両方向矢印カーソル
65549 IDC_SIZENWSE 32642 左上と右下を指す両方向矢印カーソル
65553 IDC_SIZEWE 32644 左右を指す両方向矢印カーソル
65547 IDC_UPARROW 32516 上を指す垂直の矢印カーソル
65543 IDC_WAIT 32514 砂時計カーソル

* バージョンが 4.0 以降(Windows NT 4.0 以降)とマークされたアプリケーションにおいて

一覧は以下のコードから得られます(「意味」は参考サイトを引用)。

import win32con
from win32gui import LoadCursor

DEFAULT_CURSORS = {
    win32con.IDC_APPSTARTING: 'appStarting',
    win32con.IDC_ARROW: 'Arrow',
    win32con.IDC_CROSS: 'Cross',
    win32con.IDC_HAND: 'Hand',
    win32con.IDC_HELP: 'Help',
    win32con.IDC_IBEAM: 'IBeam',
    win32con.IDC_ICON: 'ICon',
    win32con.IDC_NO: 'No',
    win32con.IDC_SIZE: 'Size',
    win32con.IDC_SIZEALL: 'sizeAll',
    win32con.IDC_SIZENESW: 'sizeNESW',
    win32con.IDC_SIZENS: 'sizeNS',
    win32con.IDC_SIZENWSE: 'sizeNWSE',
    win32con.IDC_SIZEWE: 'sizeWE',
    win32con.IDC_UPARROW: 'upArrow',
    win32con.IDC_WAIT: 'Wait',
}

for key, value in DEFAULT_CURSORS.items():
    print(f'{LoadCursor(0, key)}, {key}, {value}')
出力結果
65561, 32650, appStarting
65539, 32512, Arrow
65545, 32515, Cross
65567, 32649, Hand
65563, 32651, Help
65541, 32513, IBeam
0, 32641, ICon
65559, 32648, No
0, 32640, Size
65557, 32646, sizeAll
65551, 32643, sizeNESW
65555, 32645, sizeNS
65549, 32642, sizeNWSE
65553, 32644, sizeWE
65547, 32516, upArrow
65543, 32514, Wait

pyautoguiでの使用例

というわけで、pyautoguiで判定する際には以下のような関数が、意図するところがわかりやすい気がしています。

import pyautogui
from win32con import IDC_APPSTARTING, IDC_WAIT
from win32gui import LoadCursor, GetCursorInfo

def wait_hourglass(**kwargs):
    wait_limit = kwargs.pop('wait_limit', 60) * 5
    hourglass = [LoadCursor(0, IDC_APPSTARTING), LoadCursor(0, IDC_WAIT)]
    for _ in range(wait_limit):
        pyautogui.failSafeCheck()
        if GetCursorInfo()[1] not in hourglass:
            return GetCursorInfo()[1]
        sleep(0.2)
    raise TimeoutError()

参考サイト

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2