LoginSignup
11
12

More than 3 years have passed since last update.

ctypes.windll.user32について

Last updated at Posted at 2018-02-20

はじめに

  • 個人的な備忘録です。
  • Python初心者です。
  • Pythonからウィンドやマウスの操作をする方法を調べてます。
  • pyautoguiは使えません。
  • 良いサンプル等がありましたら、教えて下さい。
  • 調べて-> 試して-> 随時更新します。

メッセージボックスの表示

MessageBoxW.py
# -*- coding: utf-8 -*-
import ctypes

ctypes.windll.user32.MessageBoxW(0, u'Hello World', u'タイトル', 0x00000040)

ウィンドウの作成

  • 参考サイト

CreateWindowサンプルコード

CreateWindow
from ctypes import *
from ctypes.wintypes import *


WNDPROCTYPE = WINFUNCTYPE(c_int, HWND, c_uint, WPARAM, LPARAM)

# Window Styles
# https://msdn.microsoft.com/ja-jp/library/ms632600.aspx
WS_EX_APPWINDOW = 0x40000
WS_OVERLAPPEDWINDOW = 0xcf0000
WS_CAPTION = 0xc00000

SW_SHOWNORMAL = 1
SW_SHOW = 5

CS_HREDRAW = 2
CS_VREDRAW = 1

CW_USEDEFAULT = 0x80000000

WM_DESTROY = 2

WHITE_BRUSH = 0


class WNDCLASSEX(Structure):
    _fields_ = [("cbSize", c_uint),
                ("style", c_uint),
                ("lpfnWndProc", WNDPROCTYPE),
                ("cbClsExtra", c_int),
                ("cbWndExtra", c_int),
                ("hInstance", HANDLE),
                ("hIcon", HANDLE),
                ("hCursor", HANDLE),
                ("hBrush", HANDLE),
                ("lpszMenuName", LPCWSTR),
                ("lpszClassName", LPCWSTR),
                ("hIconSm", HANDLE)]

def PyWndProcedure(hWnd, Msg, wParam, lParam):
    if Msg == WM_DESTROY:
        windll.user32.PostQuitMessage(0)
    else:
        return windll.user32.DefWindowProcW(hWnd, Msg, wParam, lParam)
    return 0



def main():
    WndProc = WNDPROCTYPE(PyWndProcedure)
    hInst = windll.kernel32.GetModuleHandleW(0)
    wclassName = 'My Python Win32 Class'
    wname = 'My test window'

    wndClass = WNDCLASSEX()
    wndClass.cbSize = sizeof(WNDCLASSEX)
    wndClass.style = CS_HREDRAW | CS_VREDRAW
    wndClass.lpfnWndProc = WndProc
    wndClass.cbClsExtra = 0
    wndClass.cbWndExtra = 0
    wndClass.hInstance = hInst
    wndClass.hIcon = 0
    wndClass.hCursor = 0
    wndClass.hBrush = windll.gdi32.GetStockObject(WHITE_BRUSH)
    wndClass.lpszMenuName = 0
    wndClass.lpszClassName = wclassName
    wndClass.hIconSm = 0

    regRes = windll.user32.RegisterClassExW(byref(wndClass))

    hWnd = windll.user32.CreateWindowExA(
    0,wclassName,wname,
    WS_OVERLAPPEDWINDOW | WS_CAPTION,
    CW_USEDEFAULT, CW_USEDEFAULT,
    300,300,0,0,hInst,0)

    if not hWnd:
        print('Failed to create window')
        exit(0)
    print('ShowWindow', windll.user32.ShowWindow(hWnd, SW_SHOW))
    print('UpdateWindow', windll.user32.UpdateWindow(hWnd))

    msg = MSG()
    lpmsg = pointer(msg)

    print('Entering message loop')
    while windll.user32.GetMessageA(lpmsg, 0, 0, 0) != 0:
        windll.user32.TranslateMessage(lpmsg)
        windll.user32.DispatchMessageA(lpmsg)

    print('done.')


if __name__ == "__main__":
    print "Win32 Application in python"
    main()

親ウィンドウハンドルの取得

FindWindowW.py
# -*- coding: utf-8 -*-
import ctypes

class FindWindowW(object):

    def __init__(self, window_title):
        self.pwh = ctypes.windll.user32.FindWindowW(0, window_title)

    def get(self):
        return self.pwh

    def view(self):
        print(self.pwh)

子ウィンドハンドルの取得

EnumChildWindows.py
# -*- coding: utf-8 -*-
import ctypes
import array

class EnumChildWindows(object):

    def __init__(self, parent_window_handler):
        self.cwhs = array.array('i')
        ctypes.windll.user32.EnumChildWindows(\
          parent_window_handler,\
          EnumChildWindows.getCallback(), \
          ctypes.py_object(self.cwhs))

    @classmethod
    def getCallback(cls):
        cls.ENUM_CHILD_WINDOWS = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.py_object)
        def callback(handle, list):
            list.append(handle)
            return 1
        return cls.ENUM_CHILD_WINDOWS(callback)

    def get(self):
        return self.cwhs

    def view(self):
        print(self.cwhs)

ウィンドウにメッセージを送る

SendMessageW.py
# -*- coding: utf-8 -*-
import ctypes

class SendMessageW(object):

    def __init__(self, hwnd, msg, w_param, l_param):
        self.hwnd = hwnd
        self.msg = msg
        self.w_param = w_param
        self.l_param = l_param

    def send(self):
        ctypes.windll.user32.SendMessageW(self.hwnd, self.msg, self.w_param, self.l_param)

マウス操作

Point

Point.py
# -*- coding: utf-8 -*-
import ctypes.wintypes

class Point(object):

    def __init__(self):
        self.pt = ctypes.wintypes.POINT()

    def point(self):
        return self.pt

Mouse

Mouse.py
# -*- coding: utf-8 -*-
import ctypes
import Point

class Mouse(object):

    def __init__(self):
        self.pt = Point.Point().point()

    def setPos(self, x, y):
        self.pt.x = x
        self.pt.y = y
        print(self.pt.x, self.pt.y)

    def moveTo(self, x, y):
        ctypes.windll.user32.SetCursorPos(x, y)

    def getPos(self):
        ctypes.windll.user32.GetCursorPos(ctypes.byref(self.pt))
        return self.pt

Main

main.py
# -*- coding: utf-8 -*-
from window.FindWindowW import FindWindowW as FW
from window.EnumChildWindows import EnumChildWindows as ECW
from SendMessageW import SendMessageW as SM
from mouse.Mouse import Mouse
#from Source import Source
#Source.log(Mouse)

m = Mouse()
pt = m.getPos()
print(pt.x, pt.y)

m.setPos(200, 200)

pt = m.getPos()
print(pt.x, pt.y)

m.moveTo(300, 300)
pt = m.getPos()
print(pt.x, pt.y)

fw = FW(u'無題 - TeraPad')
fw.view()

ecw = ECW(fw.get())
ecw.view()

WM_CHAR = 0x0102
w_param = 0x61
l_param = 0
hwnd = ecw.get()
#hwnd = ecw.get()[22]
#sm = SM(hwnd, WM_CHAR, w_param, l_param)
#sm.send()
#"""
#print(len(hwnd))
for i in range(len(hwnd)):
    sm = SM(hwnd[i], WM_CHAR, w_param, l_param)
    sm.send()
#"""

参考リンク

11
12
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
11
12