ctypes.windll.user32について

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

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

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

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

# ウィンドウの作成
- 参考サイト
 
> [CreateWindowサンプルコード](https://gist.github.com/mouseroot/6128651)

```py: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()
```

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

```python: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)
```

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

```python: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)
```

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

```py: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

```py: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

```py: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

```py: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()
#"""
```

### 参考リンク
- [pyautogui](https://github.com/asweigart/pyautogui)
- [Windows APIリスト](https://msdn.microsoft.com/ja-jp/windows/hh240557#10)