1. hdc, paintstruct = BeginPaint()
윈도우에 그림을 그리기 위한 화면 영역을 가져오는 함수입니다.
인자는 없으며, 리턴값으로 hdc, paintstruct 를 갖습니다.
hdc: device context의 핸들 값
paintstruct: 클라이언트 영역의 정보를 포함하는 구조체
2. PyLOGFONT = LOGFONT()
LOGFONT 객체를 만들기 위한 함수입니다.
LOGFONT는 폰트 설정을 위한 값들을 저장한 구조체입니다.
인자는 없으며, 리턴값으로 PyLOGFONT 구조체를 갖습니다.
* 참조: http://timgolden.me.uk/pywin32-docs/PyLOGFONT.html
* 참조: https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfonta
3. PyGdiHandle = CreateFontIndirect(lplf)
논리적 폰트를 생성하는 함수입니다.
인자로는 lplf : PyLOGFONT 가 있습니다.
lplf: LOGFONT()함수로 만든 PyLOGFONT 객체입니다.
리턴값으로 폰트 객체를 리턴합니다.
4. int = SetTextAlign(hdc, Mode )
텍스트의 가로, 세로 정렬을 설정하는 함수입니다.
인자로는 hdc : PyHANDLE, Mode : int 가 있습니다.
hdc: device context의 핸들 값
Mode: 어떤식으로 정렬할지 설정 값(win32con.TA_*)
* 참조: https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-settextalign
리턴값은 이전 TextAlign 설정 값입니다.
5. int = SetTextCharacterExtra(hdc, CharExtra )
문자간의 공백을 설정하는 함수입니다.
인자로는 hdc : PyHANDLE, CharExtra : int 가 있습니다.
hdc: device context의 핸들 값
CharExtra: 문자간 공백 값
리턴값으로는 이전 공백 설정 값입니다.
6. int = SetTextColor(hdc, color )
텍스트의 색을 변경하는 함수입니다.
인자로는 hdc : int, color : int 가 있습니다.
hdc: device context의 핸들 값
color: color 값으로 win32api.RGB()함수의 리턴값을 사용
리턴값으로는 이전 텍스트 color 값입니다.
7. int = GetTextAlign(hdc)
텍스트 정렬 값을 반환하는 함수입니다.
인자로는 hdc : int 가 있습니다.
hdc: device context의 핸들 값
리턴값으로는 현재 텍스트 정렬 값입니다.
8. int = GetTextCharacterExtra(hdc)
텍스트 공백 값을 반환하는 함수입니다.
인자로는 hdc : int 가 있습니다.
hdc: device context의 핸들 값
리턴값으로는 현재 텍스트 공백 값입니다.
9. int = GetTextColor(hdc)
텍스트 color 값을 반환하는 함수입니다.
인자로는 hdc : int 가 있습니다.
hdc: device context의 핸들 값
리턴값으로는 현재 텍스트 color 값입니다.
10. cx, cy = GetTextExtentPoint32(hdc, str )
텍스트의 높이와 길이를 계산하는 함수입니다.
인자로는 hdc : PyHANDLE, str : string 가 있습니다.
hdc: device context의 핸들 값
str: 문자열
리턴값으로는 cx, cy가 있으며, 문자열의 길이와 높이 입니다.
11. PyUnicode = GetTextFace(hdc)
현재 텍스트의 폰트 이름을 반환합니다.
인자로는 hdc : int 가 있습니다.
hdc: device context의 핸들 값
리턴값으로는 현재 텍스트 폰트명입니다.
12. dict = GetTextMetrics()
폰트의 정보를 반환하는 함수입니다.
인자는 없으며, 리턴값으로는 폰트의 정보를 사전형으로 갖습니다.
13. int = ExtTextOut(hdc, int , int , int , rect , string , tuple )
화면에 텍스트를 출력하는 함수입니다. 근데 아래의 DrawText를 쓰는게 더 좋아보입니다.
인자로는 hdc : PyHANDLE, x : int, y : int, nOption : int, rect : PyRECT, text : string, (width1, width2) : tuple 이 있습니다.
hdc: device context 핸들 값
x: 텍스트 출력을 시작할 x 좌표(왼쪽 상단 위 기준)
y: 텍스트 출력을 시작할 y 좌표(왼쪽 상단 위 기준)
nOptions: 사각형 영역을 어떻게 사용할지를 정의합니다. 다음의 값을 하나 혹은 두개를 사용할 수 있습니다.
- win32con.ETO_CLIPPED: 텍스트가 사각형 영역에 의해 잘립니다.
- win32con.ETO_OPAQUE: 현재의 배경색을 사각형 영역을 채우는데 사용합니다.
rect: 텍스트를 출력할 사각형 영역
text: 출력할 텍스트
(width1, width2, ...): 문자 사이의 거리를 설정하는 튜플 값
14. int, PyRECT = DrawText(hDC, String , nCount , Rect , Format )
텍스트를 출력하는 함수입니다. ExtTextOut 보다 엔터 값을 쉽게 취급할 수 있어 얘를 사용하는 게 더 좋아보입니다,
인자로는 hDC : int/PyHANDLE, String : str, nCount : int, Rect : PyRECT, Format : int 가 있습니다.
hDC: device context 핸들 값
String: 출력할 텍스트
nCount: 텍스트의 길이
Rect: 텍스트를 출력할 사각형 영역
Format: 텍스트 출력 형식
* 참조: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-drawtext
리턴값으로 int, PyRECT를 갖습니다.
int: 문자열의 높이값
PyRECT: 문자열이 출력된 사각형 영역
15. int,PyRECT = DrawTextW(hDC, String , Count , Rect , Format )
위의 DrawText와 같습니다. 유니코드용이라는데, 크게 차이는 없는 것 같습니다.
16. EndPaint(hwnd, ps)
BegintPaint()를 사용한 후 그리기 작업을 끝냈다면, EndPaint()함수로 device context 핸들을 닫아주어야 합니다.
인자로는 hwnd : int, ps : paintstruct 가 있습니다.
hwnd: 윈도우 핸들 값
ps: BegintPaint()함수의 리턴값인 paintstruct
17. PyGdiHandle = CreateRectRgnIndirect(rc)
사각형 영역을 만드는 함수입니다.
인자로는 rc : PyRECT가 있습니다.
rc: 사각형 영역으로 튜플 값입니다.
리턴값은 Region에 대한 핸들값입니다.
18. InvalidateRect(hWnd, Rect, Erase)
윈도우 영역을 무효화, 즉 다시 그리도록 하는 함수입니다.
인자로는 hWnd : PyHANDLE, Rect : PyRECT, Erase : boolean 가 있습니다.
hWnd: 윈도우의 핸들 값입니다.
Rect: 사각형 영역으로 튜플 값입니다.
Erase: 배경도 지울건지 설정하는 값입니다.
19. InvalidateRgn(hWnd, hRgn, Erase)
위의 InvalidateRect와 같은 역할의 함수입니다.
차이점이라면, 2번재 인자가 hRgn으로 Region 핸들 값이 필요하다는 점입니다.
20. ValidateRgn(hWnd, hRgn)
InvalidateRgn()함수 (InvalidateRect()함수도 포함)와는 반대로 영역을 유효화, 즉 다시 그리지 않겠다 라는 함수입니다.
인자로는 hWnd : PyHANDLE, hRgn : PyGdiHANDLE 가 있습니다.
hWnd: 윈도우의 핸들 값입니다.
hRgn: Regint 핸들 값입니다.
21. RedrawWindow(hWnd, rcUpdate, hrgnUpdate, flags)
윈도우의 클라이언트 영역을 다시 그리는 함수입니다.
인자로는 hWnd : PyHANDLE, rcUpdate : (int,int,int,int), hrgnUpdate : PyGdiHANDLE, flags : int가 있습니다.
hWnd: 윈도우의 핸들값입니다.
rcUpdate: Rect 영역 값으로 None 이 가능합니다. hrgnUpdate 영역에 값이 있으면 이 값은 무시됩니다.
hrgnUpdate: Region 영역 핸들 값으로 None이 가능합니다. rcUpdate와 함께 None이라면 전체 영역으로 설정됩니다.
flags: 그리기 플래그 값입니다. 이 플래그에 따라 Invalidate, Validate 를 설정 가능합니다.
* 참조: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-redrawwindow
import win32gui
import win32api
import win32con
# WM_CREATE가 안생겨서 만든 WM_CREATE 대용 메시지
UM_CREATE = win32con.WM_USER + 1
class WindowProcFunc:
def __init__(self):
self.str=""
def OnCreate(self, hwnd, iMsg, wParam, lParam):
pass
def OnDestroy(self, hwnd, iMsg, wParam, lParam):
win32gui.PostQuitMessage(0)
def OnPaint(self, hwnd, iMsg, wParam, lParam):
rect = (1, 1, 1000, 1000)
hdc, ps = win32gui.BeginPaint(hwnd)
logfont = win32gui.LOGFONT()
logfont.lfHeight = 20
logfont.lfWidth = 20
logfont.lfEscapement = 20
logfont.lfOrientation = 20
logfont.lfWeight = win32con.FW_BOLD
logfont.lfItalic = win32con.TRUE
logfont.lfUnderline = win32con.TRUE
logfont.lfStrikeOut = win32con.TRUE
logfont.lfCharSet = win32con.DEFAULT_CHARSET
hFont = win32gui.CreateFontIndirect(logfont)
oldFont = win32gui.SelectObject(hdc, hFont)
oldTextAlign = win32gui.SetTextAlign(hdc, win32con.TA_CENTER)
oldTextExtra = win32gui.SetTextCharacterExtra(hdc, 20)
oldTextColor = win32gui.SetTextColor(hdc, win32api.RGB(0, 0, 255))
#win32gui.ExtTextOut(hdc, 0, 0, win32con.ETO_OPAQUE, rect, self.str, (10, 20, 30, 40, 50))
height, rt = win32gui.DrawText(hdc, self.str, len(self.str), rect, win32con.DT_TOP | win32con.DT_LEFT)
#height, rt = win32gui.DrawTextW(hdc, self.str, len(self.str), rect, win32con.DT_TOP | win32con.DT_LEFT)
print(f"text height is {height}")
print(f"rect is {rt}")
textAlign = win32gui.GetTextAlign(hdc)
textColor = win32gui.GetTextColor(hdc)
bValue = textColor >> 16 & 0xFF
gValue = textColor >> 8 & 0xFF
rValue = textColor & 0xFF
cx, cy = win32gui.GetTextExtentPoint32(hdc, self.str)
textFace = win32gui.GetTextFace(hdc)
textMetrics = win32gui.GetTextMetrics(hdc)
textExtra = win32gui.GetTextCharacterExtra(hdc)
print(f"textAlign is {textAlign}")
print(f"textColor RGB is {rValue, gValue, bValue}")
print(f"text's width is {cx}, height is {cy}")
print(f"textFace is {textFace}")
print(f"textMetrics is {textMetrics}")
print(f"textExtra is {textExtra}")
win32gui.SelectObject(hdc, oldFont)
win32gui.DeleteObject(hFont)
win32gui.EndPaint(hwnd, ps)
def OnChar(self, hwnd, iMsg, wParam, lParam):
# wParam에 입력한 문자 정보가 들어있다
if wParam == win32con.VK_BACK:
self.str = self.str[:-1]
else:
self.str+=chr(wParam)
#win32gui.InvalidateRgn(hwnd, None, win32con.TRUE)
#win32gui.InvalidateRect(hwnd, None, win32con.TRUE)
win32gui.RedrawWindow(hwnd, None, None, win32con.RDW_INVALIDATE)
rc=(10, 10, 50, 50)
hrgn = win32gui.CreateRectRgnIndirect(rc)
win32gui.ValidateRgn(hwnd, hrgn) # 무효화 영역 무시 (유효화)
#win32gui.RedrawWindow(hwnd, rc, None, win32con.RDW_VALIDATE)
def OnClose(self, hwnd, iMsg, wParam, lParam):
win32gui.DestroyWindow(hwnd)
wndProcFunc = WindowProcFunc()
wndProc={
UM_CREATE:wndProcFunc.OnCreate,
win32con.WM_DESTROY: wndProcFunc.OnDestroy,
win32con.WM_PAINT: wndProcFunc.OnPaint,
win32con.WM_CLOSE: wndProcFunc.OnClose,
win32con.WM_CHAR: wndProcFunc.OnChar,
}
def winMain():
hInstance = win32api.GetModuleHandle()
className = 'SimpleWin32'
wndClass = win32gui.WNDCLASS()
wndClass.style = win32con.CS_HREDRAW | win32con.CS_VREDRAW
wndClass.lpfnWndProc = wndProc
wndClass.hInstance = hInstance
wndClass.hIcon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)
wndClass.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)
wndClass.hbrBackground = win32gui.GetStockObject(win32con.WHITE_BRUSH)
wndClass.lpszClassName = className
wndClassAtom = win32gui.RegisterClass(wndClass)
hwnd = win32gui.CreateWindow(
wndClassAtom,
"title test",
win32con.WS_OVERLAPPEDWINDOW,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
0,
0,
hInstance,
None)
win32gui.SendMessage(hwnd, UM_CREATE, 0, 0)
win32gui.ShowWindow(hwnd, win32con.SW_SHOWNORMAL)
win32gui.UpdateWindow(hwnd)
win32gui.PumpMessages()
return 0
if __name__ == "__main__":
x = winMain()