7. [pywin32] Caret 관련 함수

pywin32/win32gui|2021. 12. 24. 00:36

CreateCaret(hWnd, hBitmap, nWidth, nHeight)

새로운 문자가 출력될 위치를 알려주는 Caret 객체를 만드는 함수입니다.

 

인자로는 hWnd : int, hBitmap : PyGdiHANDLE, nWidth : int, nHeight : int 가 있습니다.

 

hWnd: 윈도우 핸들 값

 

hBitmap: Caret 모양으로 삼을 비트맵 핸들 값, None으로 둘 시 Solid 형태의 Caret이 만들어 집니다.

 

nWidth: Caret의 넓이

 

nHeight: Caret의 높이

 

 

SetCaretPos(x, y)

Caret의 위치를 설정하는 함수입니다.

 

인자로는 x : int, y : int 가 있습니다.

 

x: x 좌표

 

y: y 좌표

 

 

int,int = GetCaretPos()

Caret의 위치를 리턴하는 함수입니다.

 

인자는 없으며, 리턴값으로 (x, y) 좌표를 리턴합니다.

 

 

ShowCaret(hWnd)

Caret을 보여주는 함수입니다.

 

인자로는 hWnd : PyHANDLE 가 있습니다.

 

hWnd: 윈도우의 핸들 값

 

 

HideCaret(hWnd)

Caret을 숨기는 함수입니다.

 

인자로는 hWnd : PyHANDLE 가 있습니다.

 

hWnd: 윈도우의 핸들 값

 

 

DestroyCaret()

Caret 객체를 파괴하는 함수입니다.

 

인자와 리턴값은 없습니다.

 

import win32gui
import win32api
import win32con

# WM_CREATE가 안생겨서 만든 WM_CREATE 대용 메시지
UM_CREATE = win32con.WM_USER + 1


class WindowProcFunc:
    def __init__(self):
        self.str=""
        pass

    def OnCreate(self, hwnd, iMsg, wParam, lParam):
        win32gui.CreateCaret(hwnd, None, 5, 15)

        
    def OnDestroy(self, hwnd, iMsg, wParam, lParam):
        win32gui.PostQuitMessage(0)


    def OnPaint(self, hwnd, iMsg, wParam, lParam):
        hdc, ps = win32gui.BeginPaint(hwnd)
        cx, cy = win32gui.GetTextExtentPoint32(hdc, self.str)
        win32gui.ExtTextOut(hdc, 0, 0, win32con.ETO_OPAQUE, None, self.str, None)

        win32gui.SetCaretPos(cx, 0)
        caretPosX, caretPosY = win32gui.GetCaretPos()
        print(f"caretPos : {caretPosX}, {caretPosY}")
        
        win32gui.ShowCaret(hwnd)
        win32gui.EndPaint(hwnd, ps)
        
    def OnChar(self, hwnd, iMsg, wParam, lParam):

        if wParam == win32con.VK_BACK:
            self.str = self.str[:-1]
        else:
            self.str+=chr(wParam)

        win32gui.InvalidateRgn(hwnd, None, win32con.TRUE)

    def OnClose(self, hwnd, iMsg, wParam, lParam):
        win32gui.HideCaret(hwnd)
        win32gui.DestroyCaret()
        win32gui.DestroyWindow(hwnd)


wndProcFunc = WindowProcFunc()

wndProc={
    UM_CREATE:wndProcFunc.OnCreate,
    win32con.WM_DESTROY: wndProcFunc.OnDestroy,
    win32con.WM_PAINT: wndProcFunc.OnPaint,
    win32con.WM_CHAR: wndProcFunc.OnChar,
    win32con.WM_CLOSE: wndProcFunc.OnClose,
}

def winMain():
    hInstance = win32api.GetModuleHandle()


    className = 'SimpleWin32'

    wndClass                = win32gui.WNDCLASS()
    wndClass.style          = win32con.CS_HREDRAW | win32con.CS_VREDRAW | win32con.CS_OWNDC
    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()

 

 

반응형

댓글()

6. [pywin32] LineAndCurve 관련 함수 - 2

pywin32/win32gui|2021. 12. 17. 00:45

1. Arc(hdc, LeftRect, TopRect, RightRect, BottomRect, XRadial1, YRadial1, XRadial2, YRadial2)

아크를 그리는 함수입니다. 타원을 그린 후 라디안 위치와 타원의 중심을 잇는 가상의 선을 이용해서 아크를 정하는 함수인 듯 합니다.

 

인자로는 hdc : PyHANDLE, LeftRect : int, TopRect : int, RightRect : int, BottomRect : int, XRadial1 : int, YRadial1 : int, XRadial2 : int, YRadial2 : int 가 있습니다.

 

hdc: device context 핸들 값입니다.

 

LeftRect: 아크를 그릴 타원이 외접하는 사각형의 왼쪽 위치 값입니다.

 

TopRect: 아크를 그릴 타원이 외접하는 사각형의 위쪽 위치 값입니다.

 

RightRect: 아크를 그릴 타원이 외접하는 사각형의 오른쪽 위치 값입니다.

 

BottomRect: 아크를 그릴 타원이 외접하는 사각형의 아래쪽 위치 값입니다.

 

XRadial1: 1번 라디안의 수평 위치 값

 

YRadial1: 1번 라디안의 수직 위치 값

 

XRadial2: 2번 라디안의 수평 위치 값

 

YRadial2: 2번 라디안의 수직 위치 값

 

 

2. ArcTo(hdc, LeftRect, TopRect, RightRect, BottomRect, XRadial1, YRadial1, XRadial2, YRadial2)

Arc() 함수와 같습니다. 추가로 아크를 그린 후 현재 위치를 아크가 끝나는 위치로 이동시킵니다.

 

인자는 Arc() 함수와 같으므로 생략하겠습니다.

 

 

3. AngleArc(hdc, X, Y, Radius, StartAngle, SweepAngle)

다른 방식으로 아크를 그리는 함수입니다.

 

인자로는 hdc : PyHANDLE, X : int, Y : int, Radius : int, StartAngle : float, SweepAngle : float 가 있습니다.

 

hdc: device context 핸들 값

 

X: 원의 중심 X 좌표

 

Y: 원의 중심 Y 좌표

 

Radius: 윈의 반지름

 

StartAngle: 아크를 그릴 시작 각도

 

SweepAngle: 아크를 끝낼 각도, 시작 각도 기준으로 상대적인 각도입니다.

 

 

4. PolyBezier(hdc, Points)

베지에 곡선을 그리는 함수입니다.

 

인자로는 hdc : PyHANDLE, Points : [(int,int),...] 가 있습니다.

 

hdc: device context 핸들 값

 

Points: (x,y)좌표의 튜플 값으로 이 좌표 방향으로 선이 휘어지는 듯 합니다.

 - 반드시 3의 배수 + 1의 갯수여야 한다고 합니다.

 

 

5. PolyBezierTo(hdc, Points)

PolyBezier()함수와 같습니다. 추가로 베제에 곡선을 그린 후 현재 위치를 Points의 마지막 위치로 이동시킵니다.

 

인자로는 hdc : PyHANDLE, Points : [(int,int),...] 가 있습니다.

 

hdc: device context 핸들 값

 

Points: (x,y)좌표의 튜플 값으로 이 좌표 방향으로 선이 휘어지는 듯 합니다.

 - 최소 3개의 포인트를 포함해야 한다고 합니다.

 

 

6. Polyline(hdc, Points)

연속적인 선을 그리는 함수입니다.

 

인자로는 hdc : PyHANDLE, Points : [(int,int),...] 가 있습니다.

 

hdc: device context 핸들 값

 

Points: (x,y)좌표의 튜플 값으로 이 좌표들 끼리 선들이 그어집니다.

 

 

7. PolylineTo(hdc, Points)

Polyline() 함수와 같습니다. 추가로 선을 그린 후 현재 위치를 Points의 마지막 위치로 이동시킵니다.

 

인자는 Poluline()함수와 같으므로 생략하겠습니다.

 

 

from typing import cast
import win32gui
import win32api
import win32con

# WM_CREATE가 안생겨서 만든 WM_CREATE 대용 메시지
UM_CREATE = win32con.WM_USER + 1


class WindowProcFunc:
    def __init__(self):
        pass

    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):
        hdc, ps = win32gui.BeginPaint(hwnd)

        #hPen = win32gui.CreatePen(win32con.PS_DOT, 1, win32api.RGB(255, 0, 0))
        lb = {'Style' : win32con.BS_SOLID, 'Color':win32api.RGB(255, 0, 0), 'Hatch':None} 
        hPen = win32gui.ExtCreatePen(win32con.PS_COSMETIC | win32con.PS_DOT, 1, lb, None)
        oldPen = win32gui.SelectObject(hdc, hPen)
        

        win32gui.SetArcDirection(hdc, win32con.AD_CLOCKWISE)

        # 1번
        #win32gui.Arc(hdc, 300, 10, 400, 100, 400, 10, 400, 100)
        
        # 2번 
        #win32gui.MoveToEx(hdc, 350, 150)
        #win32gui.ArcTo(hdc, 300, 10, 400, 100, 400, 10, 400, 100)

        # 3번
        win32gui.MoveToEx(hdc, 300, 100)
        win32gui.AngleArc(hdc, 300, 100, 100, 30, 60)

        # 4번
        prePos = win32gui.MoveToEx(hdc, 10, 10)
        win32gui.LineTo(hdc, 50, 50)

        # 5번
        polygonPos=((10, 75), (125, 30), (250, 75), (175, 150), (75, 150))
        win32gui.Polyline(hdc, polygonPos)
        
        #6번
        #prePos = win32gui.MoveToEx(hdc, 400, 400)
        #win32gui.PolylineTo(hdc,polygonPos)
        
        # 7번
        bezierPos=((55, 215), (75, 100), (200, 300), (275, 75))
        #win32gui.PolyBezier(hdc, bezierPos)

        #8번
        bezierToPos=((75, 100), (200, 300), (275, 75))
        prePos = win32gui.MoveToEx(hdc, 55, 215)
        win32gui.PolyBezierTo(hdc, bezierToPos)
        

        win32gui.SelectObject(hdc, oldPen)
        win32gui.DeleteObject(hPen)

        arcDirect = win32gui.GetArcDirection(hdc)
        print(f"Arc Direct : {'시계방향' if win32con.AD_CLOCKWISE==arcDirect else '반시계방향'}")

        win32gui.EndPaint(hwnd, ps)


    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,
}

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.WS_VSCROLL | win32con.WS_HSCROLL,
        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()

# 1번 ~ # 8번 으로 구분된 함수니 주석 처리를 통해 원하는 함수만 실행이 가능하실겁니다.

 

 

 

 

반응형

댓글()

5. [pywin32] LineAndCurve 관련 함수 - 1

pywin32/win32gui|2021. 12. 10. 00:40

1. PyGdiHANDLE = CreatePen(PenStyle, Width , Color )

선 그리기에 사용할 Pen 스타일을 지정해서 Pen 핸들값을 만드는 함수입니다.

 

인자로는 PenStyle : int, Width : int, Color : int 가 있습니다.

 

PenSytle: Pen의 스타일을 지정합니다.

 * 참조: https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createpen

 

Width: Pen의 굵기를 지정합니다. 0으로 설정 시 1픽셀의 굵기를 갖습니다.

 

Color: Pen의 색을 지정합니다. win32api.RGB() 함수를 사용합니다.

 

리턴값은 Pen 핸들값입니다.

 

 

2. PyHANDLE = ExtCreatePen(PenStyle, Width , lb , Style )

CreatePen()함수처럼 Pen 스타일을 만드는 함수입니다. CreatePen()함수보다 여러 설정값을 가질 수 있습니다.

 

인자로는 PenStyle : int, Width : intlb : PyLOGBRUSH, Style=None : (int, ...) 가 있습니다.

 

PenStyle: Pen의 스타일을 지정합니다. 반드시 win32con.PS_GEOMETRIC, win32con.PS_COSMETIC 둘 중 하나를 포함해야 합니다. 그런데 두 스타일의 차이가 아직 이해가 안가더군요...

 * 참조: https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-extcreatepen

 

Width: Pen의 굵기를 지정합니다. PenStyle에 win32con.PS_COSMETIC 이 있으면, 반드시 1이여햐 한다고 합니다.

 

lb: PyLOGBRUSH 라는 사전형 값을 가집니다. Pen 에 지정할 Brush 값을 나타내는 듯 합니다. PenStyle에 win32con.PS_COSMETIC 이 있으면, 'Style'이 반드시 win32con.BS_SOLID 여야 합니다.

 * PyLOGBRUSH (사전형)

  - 'Style': Brush 스타일 지정

  - 'Color': win32api.RGB() 함수로 지정하는 색

  - 'Hatch': Hatch 스타일 지정(Hatch는 무늬를 뜻하는 듯 합니다.), BS_SOLID와 BS_HOLLOW에는 필요없는 값이라고 합니다.

   * 참조: https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logbrush

 

Style: PS_USERSTYLE 일 때만 사용하는 값으로 사용자 지정 스타일을 줄 떄 사용되는 값인 듯 합니다.

 

리턴값은 Pen 핸들값입니다.

 

 

3. HGDIOBJ = SelectObject(hdc, object )

위의 CreatePen()함수처럼 GDI 핸들을 만든 후 SelectObject()함수를 사용해야 프로그램에 적용할 수 있습니다.

 

인자로는 hdc : int, object : int 가 있습니다.

 

hdc: device context 핸들 값입니다.

 

object: 적용할 GDI 핸들값입니다.

 

리턴값은 새로운 GDI 객체를 적용하기 전 사용하고 있던 GDI 객체입니다. 나중에 GDI 객체를 다시 되돌리고 싶을 때 사용합니다.

 

 

4. DeleteObject(handle)

사용하지 않는 GDI 핸들을 삭제하는 함수입니다.

 

인자로는 handle : PyGdiHANDLE 가 있습니다.

 

handle: 삭제할 GDI 핸들 값입니다.

 

 

5. int = SetArcDirection(hdc, ArcDirection )

도형을 그릴 때 그리는 방향을 지정하는 함수입니다. 기본값은 반시계 방향입니다.

 

인자로는 hdc : PyHANDLE, ArcDirection : int 가 있습니다.

 

hdc: device context 핸들값

 

ArcDirection: 그리기 방향. 아래의 값 둘 중 하나를 설정가능합니다.

 - win32con.AD_COUNTERCLOCKWISE: 반시계 방향

 - win32con.AD_CLOCKWISE: 시계 방향

 

리턴값으로는 기존의 방향 값을 리턴합니다.

 

 

6. int = GetArcDirection(hdc)

현재 그리기 방향이 무엇인지 반환하는 함수입니다.

 

인자로는 hdc : PyHANDLE가 있습니다.

 

hdc: device context 핸들값

 

리턴값으로는 현재 설정된 그리기 방향 값을 리턴합니다.

 

 

7. (int, int) = MoveToEx(hdc, X , Y )

현재의 위치를 이동시켜줍니다. 선이나 도형을 그릴 때 어디에서 부터 그릴 것인지를 정할 수 있습니다. (보통 왼쪽상단에서 시작합니다.)

 

인자로는 hdc : PyHANDLE, X : int, Y : int 가 있습니다.

 

hdc: device context 핸들값

 

X: 이동할 x 좌표 (왼쪽상단 위 기준, 오른쪽방향)

 

Y: 이동할 y 좌표 (왼쪽상단 위 기준, 아래방향)

 

리턴값은 기존의 x,y 좌표입니다.

 

 

8. LineTo(hdc, XEnd, YEnd)

현재위치에서 지정된 위치까지 선을 그리는 함수입니다. 끝에 To 가 들어간 함수이므로, MoveToEx()함수처럼 위치를 이동시켜주는 역할도 합니다. 현재위치에서 지정된 위치까지 선을 그리고, 현재위치가 지정된 위치로 이동하게 됩니다. 그래서 LinTo()함수를 계속 호출하면 선이 계속 이어지게 됩니다.

 

인자로는 hdc : PyHANDLE, XEnd : int, YEnd : int 가 있습니다.

 

hdc: device context 핸들값

 

X: 지정할 위치의 x 좌표 (왼쪽상단 위 기준, 오른쪽방향)

 

Y: 지정할 위치의 y 좌표 (왼쪽상단 위 기준, 아래방향)

 

 

이 외에도 추가적인 함수에 대한 설명은 2부에서 하고, 일단 예제를 올려두겠습니다. 번호 별로 주석처리 및 해제를 해보시면서 실행시켜보시면 됩니다.

 

 

from typing import cast
import win32gui
import win32api
import win32con

# WM_CREATE가 안생겨서 만든 WM_CREATE 대용 메시지
UM_CREATE = win32con.WM_USER + 1


class WindowProcFunc:
    def __init__(self):
        pass

    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):
        hdc, ps = win32gui.BeginPaint(hwnd)

        #hPen = win32gui.CreatePen(win32con.PS_DOT, 1, win32api.RGB(255, 0, 0))
        lb = {'Style' : win32con.BS_SOLID, 'Color':win32api.RGB(255, 0, 0), 'Hatch':None} 
        hPen = win32gui.ExtCreatePen(win32con.PS_COSMETIC | win32con.PS_DOT, 1, lb, None)
        oldPen = win32gui.SelectObject(hdc, hPen)
        

        win32gui.SetArcDirection(hdc, win32con.AD_CLOCKWISE)

        # 1번
        #win32gui.Arc(hdc, 300, 10, 400, 100, 400, 10, 400, 100)
        
        # 2번 
        #win32gui.MoveToEx(hdc, 350, 150)
        #win32gui.ArcTo(hdc, 300, 10, 400, 100, 400, 10, 400, 100)

        # 3번
        win32gui.MoveToEx(hdc, 300, 100)
        win32gui.AngleArc(hdc, 300, 100, 100, 30, 60)

        # 4번
        prePos = win32gui.MoveToEx(hdc, 10, 10)
        win32gui.LineTo(hdc, 50, 50)

        # 5번
        polygonPos=((10, 75), (125, 30), (250, 75), (175, 150), (75, 150))
        win32gui.Polyline(hdc, polygonPos)
        
        #6번
        #prePos = win32gui.MoveToEx(hdc, 400, 400)
        #win32gui.PolylineTo(hdc,polygonPos)
        
        # 7번
        bezierPos=((55, 215), (75, 100), (200, 300), (275, 75))
        #win32gui.PolyBezier(hdc, bezierPos)

        #8번
        bezierToPos=((75, 100), (200, 300), (275, 75))
        prePos = win32gui.MoveToEx(hdc, 55, 215)
        win32gui.PolyBezierTo(hdc, bezierToPos)
        

        win32gui.SelectObject(hdc, oldPen)
        win32gui.DeleteObject(hPen)

        arcDirect = win32gui.GetArcDirection(hdc)
        print(f"Arc Direct : {'시계방향' if win32con.AD_CLOCKWISE==arcDirect else '반시계방향'}")

        win32gui.EndPaint(hwnd, ps)


    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,
}

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.WS_VSCROLL | win32con.WS_HSCROLL,
        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()

 

 

 

 

반응형

댓글()

4. [pywin32] FontAndText 관련 함수

pywin32/win32gui|2021. 12. 6. 20:18

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()

 

 

 

 

반응형

댓글()

3. [pywin32] Windows 관련 함수 - 2

pywin32/win32gui|2021. 1. 13. 00:59

어제 진행했던 1부에 계속 이어나가겠습니다

 

8. SendMessage(hwnd, idMessage, wParam, lParam)

 

윈도우에게 메시지를 보냅니다.

 

인자로는 hwnd : PyHANDLE, idMessage : int, wParam=None : int/string, lParam=None : int/string 가 있습니다.

 

hwnd: 윈도우의 핸들값입니다.

 

idMessage: 보낼 메시지 입니다. 사용자 정의 메시지도 가능합니다.

 

wParam: 메시지와 함께 보낼 데이터입니다.

 

lParam: 메시지와 함께 보낼 데이터입니다. (2)

 

 

9. AnimateWindow(hwnd, Time, Flags)

 

윈도우를 보여주거나 숨길 때 애니메이션 효과를 부여합니다.

 

인자로는 hwnd : PyHANDLE, Time : int, Flags : int 가 있습니다.

 

hwnd: 윈도우의 핸들값입니다.

 

Time: 애니메이션 효과 주기 시간입니다.(ms 단위)

 

Flags: 애니메이션 효과 플래그입니다.

 * 참조: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-animatewindow

 

 

 

10. boolean = ShowWindow(hWnd, cmdShow )

 

윈도우를 어떻게 보여줄지를 정하는 함수입니다.

 

인자로는 hWnd : int, cmdShow : int가 있습니다.

 

hWnd: 윈도우의 핸들값입니다.

 

cmdShow: 윈도우를 어떻게 보여줄지를 정하는 값입니다. win32con.SW_* 플래그를 사용합니다. 보통 win32con.SW_SHOWNORMAL을 많이 사용합니다.

 * 참조: docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow

 

리턴값은 boolean으로 이전에 윈도우가 볼 수 있는 상태라면 True, 아니면 False를 리턴합니다.

 

 

10. UpdateWindow(hwnd)

 

WM_PAINT 메시지를 날려서 윈도우 영역을 업데이트 시킵니다.

 

인자로는 hwnd : int 가 있습니다.

 

hwnd: 윈도우의 핸들값입니다.

 

 

11. MSG = GetMessage(hwnd, min , max )

 

메시지 큐에서 메시지를 검색해서 가져옵니다.

 

인자로는 hwnd : int, min : int, max : int 가 있습니다.

 

hwnd: 윈도우 핸들값입니다.

 

min: 검색해서 가져올 메시지의 최소값을 정합니다.

 

max: 검색해서 가져올 메시지의 최대값을 정합니다. min과 max가 둘다 0이라면 모든 메시지를 검색하고 가져옵니다.

 

리턴값은 MSG(=PyMSG)라고 되있는데 실제 사용하는 MSG와 와 형식이 좀 다르더군요... 그래서 예제에서는 MSG를 좀 변경했습니다.

일단 MSG 형식은 다음과 같습니다.

 

* MSG(=PyMSG)

[0] PyHANDLE : hwnd : 윈도우 핸들값입니다.

[1] int : message : GetMessage로 가져온 메시지의 식별자입니다.

[2] int : wParam : 메시지와 함께 가져온 부가 데이터입니다.

[3] int : lParam : 메시지와 함께 가져온 부가 데이터입니다. (2)

[4] int : time : 메시지가 게시된 시간입니다.

[5] (int, int) : point : 메시지가 게시될 때 마우스 커서의 위치입니다. (x,y 좌표)

 

 

12. int = TranslateMessage(msg)

 

가상 키 메시지를 실제 메시지로 번역해줍니다. 예를 들어 키를 눌렀다 뗐을 때 WM_KEYDOWN과 WM_KEYUP 메시지가 발생하는 데 TranslateMessage는 WM_CHAR 메시지를 추가로 생성한다.

 

인자로는 msg : MSG가 있습니다.

 

msg: 윈도우 메시지입니다.

 

리턴값은 int로 msg가 제대로 번역이 되지 않았다면 0을, 제대로 번역이 되거나, WM_KEYDOWN, WM_SYSKEYDOWN일 경우(번역과 상관없이) 0이 아닌 값을 리턴합니다.

 

 

13. int = DispatchMessage(msg)

 

메시지를 윈도우 처리 함수로 보내는 함수입니다.

 

인자로는 msg : MSG 가 있습니다.

 

리턴값은 윈도우 처리 함수의 리턴값인데 보통 사용하지 않는다고 합니다.

 

 

14. PumpMessages()

 

이 함수는 pywin32에서 만든 함수로 보입니다. GetMessage, TranslateMessage, DisplatchMessage 의 역할을 하며, 3가지 함수대신 이 함수를 이용해 윈도우 메시지를 처리할 수 있습니다.

 

WM_QUIT메시지가 나올 때까지 메시지를 처리합니다.

 

 

15. PostQuitMessage(rc)

 

시스템에게 현재 쓰레드를 종료시킬 거라고 알려주는 함수입니다. 보통 WM_DESTROY 메시지를 처리할 때 사용합니다.

 

인자로는 rc : int 가 있습니다.

 

rc: 종료 코드를 나타냅니다. WM_QUIT 메시지를 처리할 때 wParam에 넣어져서 사용된다고 합니다.

 

16. DestroyWindow(hwnd)

 

윈도우를 파괴하는 함수입니다. 이 함수가 호출되면 WM_DESTROY, WM_NCDESTROY 메시지를 보냅니다.

 

윈도우 프로시저는 이 함수를 통해 WM_DESTROY 메시지를 받고, WM_DESTROY 처리 함수에서 윈도우 종료를 처리합니다.

 

인자로는 hwnd : int 가 있습니다.

 

hwnd: 윈도우의 핸들 값

 

 

17. int = DefWindowProc(hwnd, message , wparam , lparam )

 

디폴트 윈도우 메시지 처리 함수를 호출합니다. 개발자가 작성한 윈도우 메시지 처리 함수에서 사용하지 않는 메시지에 대해 디폴트 처리를 수행합니다.

 

인자로는 hwnd : int, message : int, wparam : int, lparam : int

 

hwnd: 윈도우의 핸들값입니다.

 

message: 보낼 메시지 입니다.

 

wparam: 메시지와 함께 보낼 데이터입니다.

 

lparam: 메시지와 함께 보낼 데이터입니다. (2)

 

보통 윈도우 메시지 처리 함수에 인자로 들어오는 값을 그대로 사용합니다.

 

 

import win32gui
import win32api
import win32con
 
# WM_CREATE가 안생겨서 만든 WM_CREATE 대용 메시지
UM_CREATE=win32con.WM_USER + 1

PAINT_CNT=0
 
def WndProc(hwnd, iMsg, wParam, lParam):
    global PAINT_CNT
     
    if iMsg == UM_CREATE:
        print("create!")
        return 0
    elif iMsg == win32con.WM_DESTROY:
        print("destroy!")
        win32gui.PostQuitMessage(0)
        return 0
 
    elif iMsg == win32con.WM_PAINT:
        if PAINT_CNT == 0:
            print("paint")
            PAINT_CNT=1
        return 0
    elif iMsg == win32con.WM_CLOSE:
        win32gui.DestroyWindow(hwnd)
 
    return win32gui.DefWindowProc(hwnd, iMsg, wParam, lParam)
     
 
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 = None
    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.AnimateWindow(hwnd, 500, win32con.AW_CENTER)
    #win32gui.ShowWindow(hwnd, win32con.SW_SHOWNORMAL)
    win32gui.UpdateWindow(hwnd)

    win32gui.PumpMessages()
    return 0
     
    '''
    msg = win32gui.GetMessage(hwnd, 0, 0)
    msg = msg[1]
 
 
    while msg[1]:
        win32gui.TranslateMessage(msg)
        win32gui.DispatchMessage(msg)
        msg = win32gui.GetMessage(hwnd, 0, 0)
        msg = msg[1]
     
    return msg[2]
    '''
 
 
if __name__ == "__main__":
    x = WinMain()

위의 예제 실행 시 윈도우 창이 하나 뜨고 다음의 내용을 Python Shell 에서 확인할 수 있습니다.

 

 

 

 

반응형

댓글()

2. [pywin32] Windows 관련 함수 - 1

pywin32/win32gui|2021. 1. 12. 01:42

1. int = GetModuleHandle(fileName)

win32api 함수로 여기서는 HINSTANCE를 얻기 위해 사용되었습니다. 리턴값으로 현재 프로그램의 인스턴스 핸들값을 리턴합니다.

자세한 설명은 win32api에서 다루겠습니다.

 

 

2. PyWNDCLASS = WNDCLASS()

윈도우를 만들기 위한 기초 구조체로 CreateWindow 혹은 CreateWindowEx 함수를 통해 윈도우로 생성됩니다.

 

리턴값은 PyWNDCLASS 구조체로 다음의 객체를 가지며, 객체를 설정해주어야 합니다.

객체 의미
style 윈도우의 스타일을 지정해줍니다. 주로 CS_HREDRAW와 CS_VREDRAW를 많이 사용합니다.
 * 참조: docs.microsoft.com/en-us/windows/win32/winmsg/window-class-styles
cbWndExtra 윈도우가 내부적으로 사용하는 예약 영역이다. 0으로 두거나 그대로 두면 됩니다.
hInstance 인스턴스 핸들값을 넣어주며, GetModuleHandle() 의 리턴값을 사용합니다.
hIcon 윈도우의 아이콘 모양을 지정해줍니다. LoadIcon의 리턴값을 사용합니다.
hCursor 윈도우의 커서 모양을 지정해줍니다. LoadCursor의 리턴값을 사용합니다.
hbrBackground 윈도우의 바탕색을 지정해줍니다. GetStockObject의 리턴값을 사용합니다.
lpszMenuName 윈도우 프로그램이 사용할 메뉴를 지정합니다. 이 항목은 추후에 다루겠습니다.
lpszClassName 윈도우 클래스 이름을 지정합니다. CreateWindow에서 사용합니다.
lpfnWndProc 윈도우 메시지 처리 함수를 지정합니다.

 

 

3. HCURSOR = LoadIcon(hinstance, resource_id )

등록된 아이콘을 가져오는 함수입니다.

 

인자로는 hinstance : int, resource_id : int/string 가 있습니다.

 

hinstance: 아이콘 리소스를 갖고 있는 파일의 인스턴스 핸들입니다. 시스템에서 제공하는 아이콘을 사용하기 위해서는 0으로 두어야 합니다.

 

resource_id: 아이콘 리소스 ID 값입니다. 디폴트로 win32con.IDI_APPLICATION을 사용합니다.

 * 참조: docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadicona

 

리턴값은 HCURSOR로 아이콘 리소스 핸들입니다. (HICON이 아닌 HCURSOR인 이유는 모르겠습니다...)

 

 

4. HCURSOR = LoadCursor(hinstance, resid )

등록된 커서를 가져오는 함수입니다.

 

인자로는 hinstance : int, resid : int 가 있습니다.

 

hinstance: 커서 리소스를 갖고 있는 파일의 인스턴스 핸들입니다. 시스템에서 제공하는 커서를 사용하기 위해서는 0으로 두어야 합니다.

 

resid: 커서 리소스 ID 값입니다. 디폴트로 win32con.IDC_ARROW를 사용합니다.

 * 참조: docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadcursora

 

리턴값은 HCURSOR로 커서 리소스 핸들입니다.

 

 

5. PyHANDLE = GetStockObject(Object)

시스템의 표준 GDI 객체를 생성하는 함수입니다.

 

인자로는 Object : int 가 있습니다.

 

Object: 어떤 GDI 객체를 생성할 지 선택합니다.

 - *_BRUSH, *_PEN, *_FONT, *_PALLETTE 값이 올 수 있습니다.

 

리턴값은 선택한 GDI 객체 핸들 값입니다.

 

 

6. int = RegisterClass(wndClass)

윈도우 클래스를 등록하는 함수입니다.

 

인자로는 wndClass : PyWNDCLASS가 있습니다.

 

wndClass: WNDCLASS() 함수로 생성한 윈도우 클래스 구조체입니다.

 

리턴값은 WNDCLASS 에 대한 고유 식별자입니다.

 

 

7. int = CreateWindow(className, windowTitle , style , x , y , width , height , parent , menu , hinstance , reserved )

실제로 윈도우를 생성하는 함수입니다.

 

인자로는 className : int/string, windowTitle : string, style : int, x : int, y : int, width : int, height : int, parent : int, menu : int, hinstance : int, reserved : None 가 있습니다.

 

className: 클래스 이름으로 RegisterClass 의 리턴값을 넣어줍니다.

 

windowTitle: 윈도우의 타이틀 바에 나타낸 제목입니다.

 

style: 윈도우의 형태를 지정합니다. 보통 win32con.WS_OVERLAPPEDWINDOW를 많이 사용합니다.

 * 참조: docs.microsoft.com/en-us/windows/win32/winmsg/window-styles

 

x, y, width, height: x, y는 윈도우의 시작 좌표를 의미하며, width와 height는 넓이와 높이를 의미합니다. 기본적으로 win32con.CW_USEDEFAULT를 사용합니다.

 

parent: 부모 윈도우의 핸들값을 의미하며, 없으면 0으로 둡니다.

 

menu: 메뉴의 핸들값을 의미하며, 없으면 0으로 둡니다.

 

hinstance: 인스턴스 핸들로 GetModuleHandle()의 리턴값을 넣어줍니다.

 

reserved: 예약 영역으로 None으로 두어야 합니다.

 

리턴값은 윈도우 핸들값입니다.

 

 

일단 예제는 아래와 같습니다만, 아직 설명하지 않은 함수가 있어 마무리하고 결과를 보여드리겠습니다.ㅎㅎ

 - 2부에 계속 -

 

import win32gui
import win32api
import win32con
 
# WM_CREATE가 안생겨서 만든 WM_CREATE 대용 메시지
UM_CREATE=win32con.WM_USER + 1

PAINT_CNT=0
 
def WndProc(hwnd, iMsg, wParam, lParam):
    global PAINT_CNT
     
    if iMsg == UM_CREATE:
        print("create!")
        return 0
    elif iMsg == win32con.WM_DESTROY:
        print("destroy!")
        win32gui.PostQuitMessage(0)
        return 0
 
    elif iMsg == win32con.WM_PAINT:
        if PAINT_CNT == 0:
            print("paint")
            PAINT_CNT=1
        return 0
    elif iMsg == win32con.WM_CLOSE:
        win32gui.DestroyWindow(hwnd)
 
    return win32gui.DefWindowProc(hwnd, iMsg, wParam, lParam)
     
 
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 = None
    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.AnimateWindow(hwnd, 500, win32con.AW_CENTER)
    #win32gui.ShowWindow(hwnd, win32con.SW_SHOWNORMAL)
    win32gui.UpdateWindow(hwnd)

    win32gui.PumpMessages()
    return 0
     
    '''
    msg = win32gui.GetMessage(hwnd, 0, 0)
    msg = msg[1]
 
 
    while msg[1]:
        win32gui.TranslateMessage(msg)
        win32gui.DispatchMessage(msg)
        msg = win32gui.GetMessage(hwnd, 0, 0)
        msg = msg[1]
     
    return msg[2]
    '''
 
 
if __name__ == "__main__":
    x = WinMain()

 

 

 

 

반응형

댓글()

14. [pywin32] SetProcess... 관련 함수

pywin32/win32process|2020. 12. 30. 00:43

1. SetPriorityClass(handle, dwPriorityClass)

 

프로세스의 우선순위 클래스를 설정하는 함수입니다.

 

인자로는 handle : PyHANDLE, dwPriorityClass : int 가 있습니다.

 

handle: 프로세스의 핸들값입니다.

 

dwPriorityClass: 우선순위 클래스로 이전 포스트의 GetPriorityClass 함수를 참조하실 수 있습니다.

 

[pywin32/win32process] - 13. [pywin32] GetProcess... 관련 함수 - 3

 

2. SetProcessAffinityMask(hProcess, mask)

 

CPU 선호도(Affinity)를 설정하는 함수입니다.

 

인자로는 hProcess : PyHANDLE, mask : int 가 있습니다.

 

hProcess: 프로세스의 핸들값입니다.

 

mask: 설정할 CPU 값으로 비트마스크 형식으로 되어있습니다. (CPU0=1, CPU1=2, CPU2=4...., 만약 CPU0,1 둘다 설정하기 위해서는 1+2=3 값을 넣으면 됩니다.) 작업관리자에서 CPU 갯수를 확인할 수 있습니다.

 - SetThreadAffinityMask 함수를 참조하실 수 있습니다.

 

[pywin32/win32process] - 7. [pywin32] SetThreadAffinityMask & SetThreadIdealProcessor 함수

 

7. [pywin32] SetThreadAffinityMask & SetThreadIdealProcessor 함수

1. int = SetThreadAffinityMask(hThread, ThreadAffinityMask ) 쓰레드의 CPU 선호도를 설정합니다. 선호도란 멀티 프로세서의 경우 어떤 CPU에 작업을 할당할 지를 말합니다. 위의 이미지는 작업관리자 > 프로..

ssjune.tistory.com

 

 

3. SetProcessPriorityBoost(Process, DisablePriorityBoost)

 

프로세스의 동적인 우선순위 레벨 상승이 가능하도록 설정하는 함수입니다.

 

인자로는 Process: PyHANDLE, DisablePriorityBoost : boolean가 있습니다.

 

Thread는 쓰레드의 핸들값입니다.

 

DisablePriorityBoost는 동적인 우선순위 레벨 상승이 가능하게 하는 값으로 True/False 입니다.

 - win32con.TRUE: 동적인 우선순위 레벨 상승을 불가능하게 합니다.

 - win32con.FALSE: 동적인 우선순위 레벨 상승을 가능하게 합니다.

값과 의미가 반대인 것에 주의해야 합니다.

 

 

4. SetProcessShutdownParameters(Level, Flags)

 

프로세스의 셧다운 우선순위와 플래그를 설정하는 함수입니다.

 

인자로는 Level : int, Flags : int 가 있습니다.

 

Level: 우선순위로 다음의 값을 갖습니다. 응용프로그램의 프로세스는 0x100 - 0x3FF중에서 설정해야 하는 듯 합니다.

의미
0x000 - 0x0FF 시스템 프로세스가 셧다운 마지막에 종료됨
0x100 - 0x1FF 응용프로그램 프로세스가 셧다운 마지막에 종료됨
0x200 - 0x2FF 응용프로그램 프로세스가 셧다운 중간에 종료됨
0x300 - 0x3FF 응용프로그램 프로세스가 셧다운 처음에 종료됨
0x400 - 0x4FF 시스템 프로세스가 셧다운 처음에 종료됨

 

Flag: 셧다운 플래그로 다음의 값을 갖습니다.

이름 의미
0 - 기본값
1 win32con.SHUTDOWN_NORETRY 프로세스를 종료하는데 지정된 시간보다 오래 걸릴 시 재시도 대화상자를 띄위지 않고 프로세스를 종료함

 

 

5. SetProcessWorkingSetSize(hProcess, MinimumWorkingSetSize, MaximumWorkingSetSize)

 

프로세스이 워킹 셋의 최소/최대 사이즈를 설정하는 함수입니다.

 

인자로는 hProcess : PyHANDLE, MinimumWorkingSetSize : int, MaximumWorkingSetSize : int 가 있습니다.

 

hProcess: 프로세스의 핸들값입니다.

 

MinimumWorkingSetSize: 최소로 설정할 사이즈입니다. (바이트 단위), 설정할 수 있는 최소값은 20page로 만약 1page에 4K(4096 Bytes)라면 최소 81920 Bytes 부터 설정해야 합니다.

 

MaximumWorkingSetSize: 최대로 설정할 사이즈입니다. (바이트 단위), 최소 13page(53248 Bytes) 이상의 값을 설정해야 하며, 최대 시스템에서 지원하는 최대값에서 512page를 뺀 값까지 설정할 수 있습니다.

 

만약 MinimumWorkingSetSize와 MaximumWorkingSetSize가 둘다 -1로 설정한다면, 프로세스의 워킹 셋에서 가능한 많은 page를 제거합니다.

 

 

import win32process
import win32con
import win32event

prog = "C:/Users/admin/Documents/notepad.exe"
# 프로그램 경로

pinfo = win32process.STARTUPINFO()

pHandle = win32process.CreateProcess(prog, None, None, None, win32con.FALSE, \
                                     win32con.CREATE_NEW_CONSOLE, None, None, pinfo)

win32event.WaitForSingleObject(pHandle[0], 2000)

priorityClass = win32process.GetPriorityClass(pHandle[0])
affinityMask = win32process.GetProcessAffinityMask(pHandle[0])
priorityBoost = win32process.GetProcessPriorityBoost(pHandle[0])
shutdownParam = win32process.GetProcessShutdownParameters()
workingSize = win32process.GetProcessWorkingSetSize(pHandle[0])

print(f"priorityClass : {priorityClass}")
print(f"affinityMask : {affinityMask}")
print(f"priorityBoost : {priorityBoost}")
print(f"shutdownParam : {shutdownParam}")
print(f"workingSize : {workingSize}")

win32process.SetPriorityClass(pHandle[0], win32process.HIGH_PRIORITY_CLASS)
win32process.SetProcessAffinityMask(pHandle[0], 0x01)
win32process.SetProcessPriorityBoost(pHandle[0], win32con.TRUE)
win32process.SetProcessShutdownParameters(0x100, win32con.SHUTDOWN_NORETRY)
win32process.SetProcessWorkingSetSize(pHandle[0], -1, -1)


priorityClass = win32process.GetPriorityClass(pHandle[0])
affinityMask = win32process.GetProcessAffinityMask(pHandle[0])
priorityBoost = win32process.GetProcessPriorityBoost(pHandle[0])
shutdownParam = win32process.GetProcessShutdownParameters()
workingSize = win32process.GetProcessWorkingSetSize(pHandle[0])

print(f"new priorityClass : {priorityClass}")
print(f"new affinityMask : {affinityMask}")
print(f"new priorityBoost : {priorityBoost}")
print(f"new shutdownParam : {shutdownParam}")
print(f"new workingSize : {workingSize}")

위의 코드를 실행한 결과입니다.

 

 

 

 

반응형

댓글()

13. [pywin32] GetProcess... 관련 함수 - 3

pywin32/win32process|2020. 12. 29. 00:46

1. int = GetPriorityClass(handle)

 

프로세스의 우선순위를 클래스를 반환하는 함수입니다.

 

인자로는 handle : PyHANDLE 가 있습니다.

 

handle: 프로세스의 핸들값입니다.

 

리턴값은 다음과 같습니다.

이름 의미
0x8000 win32process.ABOVE_NORMAL_PRIORITY_CLASS NORMAL 이상, HIGH 이하의 우선순위 클래스
0x4000 win32process.BELOW_NORMAL_PRIORITY_CLASS IDLE 이상, NORMAL 이하의 우선순위 클래스
0x0080 win32process.HIGH_PRIORITY_CLASS NORMAL, IDLE 보다 높은 우선순위 클래스
0x0040 win32process.IDLE_PRIORITY_CLASS 화면 보호기 처럼 유휴 상태에서 동작하는 우선순위
0x0020 win32process.NORMAL_PRIORITY_CLASS 기본 보통 우선순위 클래스
0x0100 win32process.REALTIME_PRIORITY_CLASS 실시간 우선순위 클래스, 남용하면 마우스 입력 같은 기본적인 입출력 프로세스가 우선순위를 빼앗길 수 있음

 

 

2. int, int = GetProcessAffinityMask(hProcess)

 

CPU 선호도(Affinity)를 반환하는 함수입니다.

 

인자로는 hProcess : PyHANDLE 가 있습니다.

 

hProcess: 프로세스의 핸들값입니다.

 

리턴값은 int,int 로 비트마스크 값이며 앞에는 프로세스 선호도 값이고, 뒤에는 시스템의 선호도 값을 나타냅니다.

 

 

3. bool = GetProcessPriorityBoost(Process)

 

프로세스의 동적인 우선순위 레벨 상승이 가능한지 여부를 반환하는 함수입니다.

 

인자로는 Process : PyHANDLE가 있습니다.

 

Process: 프로세스의 핸들값입니다.

 

리턴값이 True 일 경우, 동적 상승이 불가능하며, False일 경우, 동적 상승이 가능하다는 뜻으로 True와 False가 반대인 것에 주의해야 합니다.

 

 

4. int,int = GetProcessShutdownParameters()

 

현재 프로세스의 셧다운 우선순위와 플래그를 반환합니다.

 

리턴값은 int, int로 앞에는 셧다운 우선순위, 뒤에는 셧다운 플래그를 나타냅니다.

 - 셧다운 우선순위

의미
0x000 - 0x0FF 시스템 프로세스가 셧다운 마지막에 종료됨
0x100 - 0x1FF 응용프로그램 프로세스가 셧다운 마지막에 종료됨
0x200 - 0x2FF 응용프로그램 프로세스가 셧다운 중간에 종료됨
0x300 - 0x3FF 응용프로그램 프로세스가 셧다운 처음에 종료됨
0x400 - 0x4FF 시스템 프로세스가 셧다운 처음에 종료됨

모든 프로세스는 0x280 우선순위를 기본으로 갖습니다.

 

 - 셧다운 플래그

이름 의미
0 - 기본값
1 win32con.SHUTDOWN_NORETRY 프로세스를 종료하는데 지정된 시간보다 오래 걸릴 시 재시도 대화상자를 띄위지 않고 프로세스를 종료함

 

 

5. int,int = GetProcessWorkingSetSize(hProcess)

 

워킹 셋 사이즈를 반환하는 함수입니다.

 

인자로는 hProcess : PyHANDLE 가 있습니다.

 

hProcess: 프로세스의 핸들값입니다.

 

리턴값은 int, int로 최소 워킹 셋 사이즈(바이트) 와 최대 워킹 셋 사이즈(바이트)를 나타냅니다.

 

이 함수가 앞에서 다뤘던 GetProcessMemoryInfo 함수의 리턴값과 관련이 있을 것 같은데 이건 아직 잘 모르겠군요...

 

 

import win32process

curPs = win32process.GetCurrentProcess()

priorityClass = win32process.GetPriorityClass(curPs)
affinityMask = win32process.GetProcessAffinityMask(curPs)
priorityBoost = win32process.GetProcessPriorityBoost(curPs)
shutdownParam = win32process.GetProcessShutdownParameters()
workingSize = win32process.GetProcessWorkingSetSize(curPs)

print(f"priorityClass : {priorityClass}")
print(f"affinityMask : {affinityMask}")
print(f"priorityBoost : {priorityBoost}")
print(f"shutdownParam : {shutdownParam}")
print(f"workingSize : {workingSize}")

현재 프로세스의 핸들값을 이용했습니다.

실행결과입니다

 

 

 

 

 

반응형

댓글()

12. [pywin32] GetProcess... 관련 함수 - 2

pywin32/win32process|2020. 12. 28. 00:19

1. int = GetGuiResources(Process, Flags )

 

프로세스의 GDI 혹은 USER Object 핸들 갯수를 반환하는 함수입니다.

GDI Object는 그래픽 출력과 관련있는 Object를 말하는 듯 합니다.(ex. bitmap, brush...)

 - MSDN 사이트의 GDI Objects 참조

 

USER Object는 사용자 인터페이스와 관련있는 Object를 말하는 듯 합니다.(ex. window, menu...)

 - MSDN 사이트의 USER Objects 참조

 

인자로는 Process : PyHANDLE, Flags : int 가 있습니다.

 

Process: 프로세스의 핸들값입니다. (PROCESS_QUERY_INFORMATION 권한 필요)

 

Flags: 어떤 Object를 반환할지 정하는 값입니다.

 - win32con.GR_GDIOBJECTS: GDI Object의 갯수

 - win32con.GR_USEROBJECTS: USER Object의 갯수

 

리턴값은 GUI Object의 갯수입니다.

 

 

2. dict = GetProcessIoCounters(hProcess)

 

프로세스의 I/O 통계를 반환합니다. IO_COUNTERS 구조체에 맵핑됩니다.

 

인자로는 hProcess : PyHANDLE 가 있습니다.

 

hProcess: 프로세스의 핸들값입니다. (PROCESS_QUERY_INFORMATION 권한 or PROCESS_QUERY_LIMITED_INFORMATION 권한 필요)

 

리턴값은 dict 형으로 IO_COUNTERS 구조체에 맵핑됩니다.

 - ReadOperationCount: 읽기 동작이 수행된 횟수

 - WriteOperationCount: 쓰기 동작이 수행된 횟수

 - OtherOperationCount: 읽기와 쓰기를 제외한 I/O 동작이 수행된 횟수

 - ReadTransferCount: 읽기 동작에 사용된 바이트 수

 - WriteTransferCount: 쓰기 동작에 사용된 바이트 수

 - OtherTransferCount: 읽기와 쓰기를 제외한 I/O 동작에 사용된 바이트 수

 

 

3. dict = GetProcessMemoryInfo(hProcess)

 

프로세스의 메모리 통계를 반환합니다. PROCESS_MEMORY_COUNTERS 구조체에 맵핑됩니다.

 

인자로는 hProcess : PyHANDLE 가 있습니다.

 

hProcess: 프로세스의 핸들값입니다. (PROCESS_QUERY_INFORMATION 권한 or PROCESS_QUERY_LIMITED_INFORMATION 권한 필요)

 

리턴값은 dict 형으로 PROCESS_MEMORY_COUNTERS 구조체에 맵핑됩니다.

 - PageFaultCount: 페이지 폴트의 수
 - PeakWorkingSetSize: 최대 워킹 셋 사이즈 (바이트)
 - WorkingSetSize: 현재 워킹 셋 사이즈 (바이트)
 - QuotaPeakPagedPoolUsage: 최대 페이징 풀 사용량 (바이트)
 - QuotaPagedPoolUsage: 현재 페이징 풀 사용량 (바이트)
 - QuotaPeakNonPagedPoolUsage: 최대 non 페이징 풀 사용량 (바이트)
 - QuotaNonPagedPoolUsage: 현재 non 페이징 풀 사용량 (바이트)
 - PagefileUsage: 메모리 관리자가 실행중인 메모리에 커밋한 총 메모리(Commit Charge) 양 (바이트)
 - PeakPagefileUsage: 이 프로세스의 동작 중 Commit Charge 최대 값 (바이트)

 

 

4. dict = GetProcessTimes(hProcess)

 

프로세스의 시간정보를 반환하는 함수입니다.

 

인자로는 hProcess : PyHANDLE가 있습니다.

 

hProcess: 프로세스의 핸들값입니다.

 

리턴값은 dict 형태로, 4개의 값을 리턴합니다.

 - CreationTim: 프로세스가 생성된 시간입니다.

 - ExitTime: 프로세스가 종료된 시간입니다.

 - KernelTime: 프로세스가 커널모드에서 동작한 시간입니다.

 - UserTime: 프로세스가 유저모드에서 동작한 시간입니다.

 

 

5. int = GetProcessVersion(processId)

 

프로세스가 실행되는 시스템의 메이저, 마이너 번호를 반환합니다.

 

인자로는 processId : int 가 있습니다.

 

리턴값은 메이저, 마이너 번호가 합쳐진 값이며, high word 부분이 메이저 번호, low word 부분이 마이너 번호입니다. 이를 나누기 위해서 win32api의 HIWORD, LOWORD 함수를 사용하였습니다.

 

 

import win32process
import win32con
import win32api


curPs = win32process.GetCurrentProcess()
curPsId = win32process.GetCurrentProcessId()

gdiCnt = win32process.GetGuiResources(curPs, win32con.GR_GDIOBJECTS)
userCnt = win32process.GetGuiResources(curPs, win32con.GR_USEROBJECTS)

ioConuters = win32process.GetProcessIoCounters(curPs)
psMemInfo = win32process.GetProcessMemoryInfo(curPs)
psTime = win32process.GetProcessTimes(curPs)
psVer = win32process.GetProcessVersion(curPsId)
majorPsVer = win32api.HIWORD(psVer)
minorPsVer = win32api.LOWORD(psVer)

print(f"GDI Objects count : {gdiCnt}")
print(f"USER Objects count : {userCnt}")
print(f"IO Counters : {ioConuters}")
print(f"Memory Info : {psMemInfo}")
print(f"Procsss Time : {psTime}")
print(f"Process Major Version : {majorPsVer}")
print(f"Process Minor Version : {minorPsVer}")

위의 코드를 실행한 결과입니다.

 

 

 

 

 

반응형

댓글()

11. [pywin32] EnumProcess 관련 함수

pywin32/win32process|2020. 12. 27. 00:42

1. (long,....) = EnumProcesses()

 

현재 동작하는 프로세스를 열거하는 함수입니다.

 

리턴값은 현재 동작하는 프로세스 아이디 목록입니다.

 

 

2. (long,....) = EnumProcessModules(hProcess)

 

특정 프로세스가 사용하는 모듈의 목록을 반환합니다.

 

인자로는 hProcess : PyHANDLE 가 있습니다.

 

hProcess: 프로세스 핸들값입니다.

 

리턴값은 프로세스가 사용하는 모듈의 핸들값 목록입니다.

 

 

3. (long,....) = EnumProcessModulesEx(hProcess, FilterFlag )

 

EnumProcessModules 처럼 특정 프로세스가 사용하는 모듈의 목록을 반환합니다. 하지만 FilterFlag 변수를 이용해 특정 모듈만 반환할 수 있습니다.

 

인자로는 hProcess : PyHANDLE, FilterFlag=LIST_MODULES_DEFAULT : int 가 있습니다.

 

hProcess: 프로세스 핸들값입니다.

 

FilterFlag: 32bit와 64bit 모듈 중 어떤걸 혹은 다 반환할 지 정하는 값입니다.

이름 의미
0x01 win32process.LIST_MODULES_32BIT 32bit 모듈만을 반환합니다.
0x02 win32process.LIST_MODULES_64BIT 64bit 모듈만을 반환합니다.
0x03 win32process.LIST_MODULES_ALL 모든 모듈을 반환합니다.
0x0 win32process.LIST_MODULES_DEFAULT 기본 동작입니다.

리턴값은 프로세스가 사용하는 모듈의 핸들값 목록입니다. 

 

 

4. PyUNICODE = GetModuleFileNameEx(hProcess, hModule )

 

프로세스나 모듈의 이름을 반환합니다.

 

인자로는 hProcess : PyHANDLE, hModule : PyHANDLE 가 있습니다.

 

hProcess: 프로세스 핸들값입니다.

 

hModule: 모듈의 핸들값입니다.

 - 만약, 이 값은 None으로 준다면 hProcess의 프로세스 이름을 반환합니다.

 

리턴값은 프로세스 혹은 모듈의 이름입니다.

 

 

import win32process
import win32api
import win32con


enumProcesses = win32process.EnumProcesses()

for pid in enumProcesses:
    try:        
        if pid==0 or pid==4:
            print(f"{pid} is system process!!")
        else:
            psHandle = win32api.OpenProcess(win32con.MAXIMUM_ALLOWED, \
                                 win32con.FALSE, \
                                 pid)
            
            #enumModule = win32process.EnumProcessModules(psHandle)
            enumModule = win32process.EnumProcessModulesEx(psHandle, win32process.LIST_MODULES_DEFAULT)
   
            psName = win32process.GetModuleFileNameEx(psHandle, None)

            for mod in enumModule:
                mdName = win32process.GetModuleFileNameEx(psHandle, mod)

                print(f"{pid} processName: {psName} module Name : {mdName}")


            win32api.CloseHandle(psHandle)

    except Exception as e:
        print(f"{pid} is error : {e}")

프로세스 핸들값을 얻기 위해 OpenProcess를 사용했으며, 이에 대한 설명은 win32api에서 다루겠습니다. 0과 4의 경우는 시스템 프로세스라 따로 뺐고, 이 외에도 OpenProcess를 통해 프로세스 핸들값은 얻어오지 못하는 프로세스들이 많더라구요... 일단을 핸들값을 얻을 수 있는 애들로만 진행했습니다. 위 예제는 파이썬을 관리자 권한으로 실행시킨 후 진행하셔야 합니다.

 

아래는 결과입니다.

 

 

 

 

 

반응형

댓글()

10. [pywin32] GetProcess... 관련 함수 - 1

pywin32/win32process|2020. 12. 26. 00:17

1. int = GetCurrentProcess()

 

현재 프로세스의 핸들값을 반환하는 함수입니다.

 

리턴값은 현재 프로세스의 핸들값입니다. 그런데 보안을 위해서인지 -1을 반환하는 것으로 고정되어 있습니다.

 

 

2. int = GetCurrentProcessId()

 

현재 프로세스의 아이디를 반환하는 함수입니다.

 

리턴값은 현재 프로세스의 아이디입니다.

 

 

3. int = GetProcessId(Process)

 

특정 프로세스의 아이디를 반환하는 함수입니다.

 

인자로는 Process : PyHANDLE 가 있습니다.

 

Process: 특정 프로세스의 핸들값입니다.

 

리턴값은 특정 프로세스의 아이디입니다.

 

 

import win32process

curPs = win32process.GetCurrentProcess()
curPsId = win32process.GetCurrentProcessId()
psId = win32process.GetProcessId(curPs)

print(f"curPs : {curPs}")
print(f"curPsId : {curPsId}")
print(f"psId : {psId}")

현재 프로세스의 아이디와 핸들값을 이용한 아이디를 출력합니다.

 

 

 

 

반응형

댓글()

9. [pywin32] ExitProcess & TerminateProcee 및 관련 함수

pywin32/win32process|2020. 12. 25. 00:25

1. ExitProcess(exitCode)

 

현재 프로세스를 종료시키는 함수입니다.

 

인자로는 exitCode : int가 있습니다.

 

exitCode: 프로세스가 종료될 때 종료 코드를 설정합니다.

 

 

2. TerminateProcess(handle, exitCode)

 

지정된 프로세스를 종료시키는 함수입니다.

 

인자로는 handle : PyHANDLE, exitCode : int 가 있습니다.

 

handle: 종료시킬 프로세스의 핸들값입니다.

 

exitCode: 프로세스가 종료될 때 종료 코드를 설정합니다.

 

 

3. int = GetExitCodeProcess(handle)

 

지정된 프로세스 핸들로 부터 종료 코드를 반환합니다.

 

인자로는 handle : PyHANDLE 가 있습니다.

 

handle: 종료 코드를 가져올 프로세스의 핸들값입니다.

 

 

import win32process
import win32con
import win32api
import win32event

prog = "C:/Users/admin/Documents/notepad.exe"
# 프로그램 경로


pinfo = win32process.STARTUPINFO()

pHandle = win32process.CreateProcess(prog, None, None, None, win32con.FALSE, \
                                     win32con.CREATE_NEW_CONSOLE, None, None, pinfo)

win32event.WaitForSingleObject(pHandle[0], 3000)

win32process.TerminateProcess(pHandle[0], 3)

errCode = win32process.GetExitCodeProcess(pHandle[0])

print(f"errCode : {errCode}")

win32process.ExitProcess(5)

이번에는 메모장을 이용해봤습니다. 메모장이 열리기는 3초간 기다린 후 종료시킵니다. 종료 코드는 3으로 설정했고요. 현재 프로세스를 종료시키면서 종료 코드를 5로 설정했지만 이건 프로세스가 종료되면서 프로세스 핸들값을 가져올 수 없어 확인은 못했으나, 제대로 설정 됐을 겁니다.ㅎㅎ

 

 

 

 

 

반응형

댓글()

8. [pywin32] CreateProcess 및 기타 함수

pywin32/win32process|2020. 12. 24. 00:33

1. PySTARTUPINFO = STARTUPINFO()

 

STARTUPINFO 구조체를 생성하는 함수입니다. 프로세스를 만들 때 사용하기 때문에 처음에 호출해주어야 합니다.

 

다음의 멤버를 갖고 있습니다.

 

integer dwX: 왼쪽 위의 x 좌표, dwFlags에 win32process.STARTF_USEPOSITION 을 설정해주어야 합니다.

 

integer dwY: 왼쪽 위의 y 좌표, dwFlags에 win32process.STARTF_USEPOSITION 을 설정해주어야 합니다.

 

integer dwXSize: 넓이, dwFlags에 win32process.STARTF_USESIZE을 설정해주어야 합니다.

 

integer dwYSize: 높이, dwFlags에 win32process.STARTF_USESIZE을 설정해주어야 합니다.

 

integer dwXCountChars: 콘솔 프로세스의 경우, 화면 넓이를 지정합니다. (GUI 프로세스의 경우 무시됨), dwFlags에 win32process.STARTF_USECOUNTCHARS을 설정해주어야 합니다.

 

integer dwYCountChars: 콘솔 프로세스의 경우, 화면 높이를 지정합니다. (GUI 프로세스의 경우 무시됨), dwFlags에 win32process.STARTF_USECOUNTCHARS을 설정해주어야 합니다.

 

integer dwFillAttribute: 콘솔 프로세스의 경우, 초기 텍스트와 배경 화면 색을 지정합니다. (GUI 프로세스의 경우 무시됨), dwFlags에 win32process.STARTF_USEFILLATTRIBUTE를 설정해주어야 합니다.

 

integer dwFlags: STARTUPINFO의 속성을 지정합니다. win32con.STARTF_* or win32process.STARTF_* 값을 이용합니다.

 - 자세한 속성값은 MSDN의 STARTUPINFO 구조체에 대한 설명을 참조

 

integer wShowWindow: 윈도우를 어떻게 보여줄지를 지정합니다. win32con.SW_* 값을 이용합니다. dwFlags에 win32process.STARTF_USESHOWWINDOW를 설정해주어야 합니다.

 - 자세한 속성값은 MSDN의 ShowWindow 함수에 대한 설명을 참조

 

integer/PyHANDLE hStdInput: 기본 입출력 핸들 설정과 관련있는 것 같습니다. 여기서는 None으로 설정하였습니다.

 

integer/PyHANDLE hStdOutput: 기본 입출력 핸들 설정과 관련있는 것 같습니다. 여기서는 None으로 설정하였습니다.

 

integer/PyHANDLE hStdError: 기본 입출력 핸들 설정과 관련있는 것 같습니다. 여기서는 None으로 설정하였습니다.

 

string/None lpDesktop: 프로세스가 실행될 윈도우 스테이션과 데스크탑을 지정합니다. 여기서는 None으로 설정하였습니다.

 

string/None lpTitle: 윈도우의 제목을 설정해줍니다.

 

 

2. PyHANDLE, PyHANDLE, int, int = CreateProcess(appName, commandLine , processAttributes , threadAttributes , bInheritHandles , dwCreationFlags , newEnvironment , currentDirectory , startupinfo )

 

프로세스를 생성하는 함수입니다. exe 확장자로 끝나는 프로그램만 실행시킬 수 있는 듯 합니다.

 

인자로는 appName : string, commandLine : string, processAttributes : PySECURITY_ATTRIBUTES, threadAttributes : PySECURITY_ATTRIBUTES, bInheritHandles : int, dwCreationFlags : int, newEnvironment : dictionary/None, currentDirectory : string, startupinfo : PySTARTUPINFO 가 있습니다.

 

appName: 실행할 프로그램(exe)의 절대경로입니다.

 

commandLine: appName과 관련된 명령어입니다. 혹은 appName을 None으로 두고 여기서 프로그램 절대경로 까지 넣는 방법도 있습니다.(이 경우 경로를 \\으로 감싸주어야 합니다.)

 

processAttributes: 프로세스의 보안 속성으로 여기서는 None으로 설정하였습니다.

 

threadAttributes: 프로세스 내 쓰레드의 보안 속성으로 여기서는 None으로 설정하였습니다.

 

bInheritHandles: 부모 프로세스의 보안 속성을 상속할지를 정하는 값입니다. win32con.TRUE/win32con.FALSE 2가지 값이 있습니다.

 

dwCreationFlag: 프로세스 생성 시 조건을 설정합니다. 여기서는 win32con.CREATE_NEW_CONSOLE으로 설정하였습니다.(기본값)

 - 자세한 속성값은 MSDN의 Process Creation Flags에 대한 설명을 참조

 

newEnvironment: 프로세스의 환경 구성을 설정합니다. 여기서는 None으로 설정하였습니다.(부모 프로세스의 환경 구성 사용)

 

currentDirectory: 프로세스의 현재 폴더 경로를 적어줍니다. 여기서는 None으로 설정하였습니다.(부모 프로세스의 폴더 사용)

 

startupinfo: 위에서 만든 STARTUPINFO 구조체 변수를 넣어줍니다.

 

 

3. PySTARTUPINFO = GetStartupInfo()

 

해당 함수를 호출한 프로세스의 STARTUPINFO 구조체를 반환합니다.

 

이건 특정 프로세스를 타겟으로 호출할 수는 없나 봅니다.(무조건 해당 프로세스의 구조체를 반환)

 

 

4. bool = IsWow64Process(Process)

 

해당 프로세스가 WOW64에서 실행 중인지 확인합니다. 32bit 프로세스의 경우 64bit 윈도우에서 실행되기 위해서 WOW64라는 에뮬레이터를 이용하는데 이걸 확인하는 함수입니다.

 

인자로는 Process=None : PyHANDLE가 있습니다.

 

Process: 확인할 프로세스의 핸들값입니다. 기본값은 None이며, 현재 프로세스를 뜻합니다.

 

리턴값은 True/False 입니다.

 - True: 32bit 프로세스가 64bit 윈도우에서 실행되는 경우 입니다.

 - False: True를 제외한 경우입니다.

 

 

import win32process
import win32con
import win32api
import win32event

prog = "C:/Users/admin/Downloads/ProcessExplorer/procexp.exe"
# 프로그램 경로

pinfo = win32process.STARTUPINFO()

pHandle = win32process.CreateProcess(prog, None, None, None, win32con.FALSE, \
                                     win32con.CREATE_NEW_CONSOLE, None, None, pinfo)

pinfo2 = win32process.GetStartupInfo()

isWOW64 = win32process.IsWow64Process(pHandle[0])
# 32pro on 64bit : true 

win32event.WaitForSingleObject(pHandle[0], 3000)

print(f"isWOW64 : {isWOW64}")

위에서 사용한 prog의 프로그램은 process explorer 입니다. 적절한 32bit 프로그램을 사용하기 위해서 입니다. 64bit OS에서 32bit 프로그램으로 프로세스를 생성하여 IsWow64Process가 True를 반환하였습니다. GetStartupInfo의 경우 호출한 프로세스의 STARTUPINFO 구조체를 반환하여 처음 생성한 STARTUPINFO 구조체와 다른 값이 들어가 있습니다.

 

 

 

 

반응형

댓글()

7. [pywin32] SetThreadAffinityMask & SetThreadIdealProcessor 함수

pywin32/win32process|2020. 12. 23. 00:09

1. int = SetThreadAffinityMask(hThread, ThreadAffinityMask )

 

쓰레드의 CPU 선호도를 설정합니다. 선호도란 멀티 프로세서의 경우 어떤 CPU에 작업을 할당할 지를 말합니다.

 

 

위의 이미지는 작업관리자 > 프로세스 > 선호도 설정의 창입니다. 여기서 CPU를 설정하는 것처럼 이 함수를 통해 설정이 가능합니다. 물론 이건 프로세스의 CPU 선호도를 보여주는 거라 쓰레드도 이렇다 라고 참조만 해주시면 되겠습니다.

 

인자로는 hThread : PyHANDLE, ThreadAffinityMask : int 가 있습니다.

 

hThread: 쓰레드의 핸들값입니다.

 

 

ThreadAffinityMask: 설정할 CPU 값으로 비트마스크 형식으로 되어있습니다. (CPU0=1, CPU1=2, CPU2=4...., 만약 CPU0,1 둘다 설정하기 위해서는 1+2=3 값을 넣으면 됩니다.) 작업관리자에서 CPU 갯수를 확인할 수 있습니다.

 

리턴값은 기존의 AffinityMask 값입니다.

 

2. int = SetThreadIdealProcessor(handle, dwIdealProcessor )

 

쓰레드가 가능한 경우 이 프로세서에서 실행됬으면 좋겠다. 라고 설정하는 함수입니다.

 

인자로는 handle : PyHANDLE, dwIdealProcessor : int 가 있습니다.

 

handle: 쓰레드의 핸들값입니다.

 

dwIdealProcessor: 이상적인 프로세서로 지정할 값입니다. 0부터 시작하며 CPU0=0, CPU1=1, CPU2=..., AffinityMask와 달리 CPU를 하나만 지정할 수 있습니다.) 작업관리자에서 CPU 갯수를 확인할 수 있습니다.

 - win32process.MAXIMUM_PROCESSORS: 이 값을 넣을 경우, 현재 지정된 IdealProcessor 값을 반환하기만 하며, 설정하지는 않습니다.

 

리턴값은 기존의 IdealProcessor 값입니다.

 

import win32process
import win32api
import win32gui
import win32event
import win32con


def cnt1():
    i = 0    
    return 3
    
 
q = tuple()
res1 = win32process.beginthreadex(None, 0, cnt1, q, win32process.CREATE_SUSPENDED)

preThreadAffMask1 = win32process.SetThreadAffinityMask(res1[0], 1)
preThreadAffMask2 = win32process.SetThreadAffinityMask(res1[0], preThreadAffMask1)
#bit 1248...
#cpu 0123...


preThreadIdealPrc1 = win32process.SetThreadIdealProcessor(res1[0], 1)
preThreadIdealPrc2 = win32process.SetThreadIdealProcessor(res1[0], 0)
preThreadIdealPrc3 = win32process.SetThreadIdealProcessor(res1[0], win32process.MAXIMUM_PROCESSORS)


print(f"pre ThreadAffMask1 : {preThreadAffMask1}")
print(f"pre ThreadAffMask2 : {preThreadAffMask2}")

print(f"pre ThreadIdealProcessor1 : {preThreadIdealPrc1}")
print(f"pre ThreadIdealProcessor2 : {preThreadIdealPrc2}")
print(f"pre ThreadIdealProcessor3 : {preThreadIdealPrc3}")


win32process.ResumeThread(res1[0])
win32event.WaitForSingleObject(res1[0], 3000)

 

실행결과입니다.

 

 

 

반응형

댓글()

6. [pywin32] SetThreadPriority & Boost 함수

pywin32/win32process|2020. 12. 22. 00:43

1. SetThreadPriority(handle, nPriority)

 

쓰레드의 우선순위 레벨을 설정하는 함수입니다.

 

인자로는 handle : PyHANDLE, nPriority : int가 있습니다.

 

handle은 쓰레드의 핸들값입니다.

 

nPriority는 쓰레드의 설정할 우선순위 레벨입니다.

 

* GetThreadPriority 함수에서 설명한 것과 같습니다.

이름 의미
1 win32process.THREAD_PRIORITY_ABOVE_NORMAL 우선순위 클래스보다 1포인트 높음
-1 win32process.THREAD_PRIORITY_BELOW_NORMAL 우선순위 클래스보다 1포인트 낮음
2 win32process.THREAD_PRIORITY_HIGHEST 우선순위 클래스보다 2포인트 높음
-15 win32process.THREAD_PRIORITY_IDLE REALTIME_PRIORITY_CLASS 에서는 기본 우선순위가 16이며 그외에는 1임
-2 win32process.THREAD_PRIORITY_LOWEST 우선순위 클래스보다 2포인트 낮음
0 win32process.THREAD_PRIORITY_NORMAL 우선순위 클래스의 보통 우선순위 레벨
15 win32process.THREAD_PRIORITY_TIME_CRITICAL REALTIME_PRIORITY_CLASS 에서는 기본 우선순위가 31이며 그외에는 15임

 

2. SetThreadPriorityBoost(Thread, DisablePriorityBoost)

 

쓰레드의 동적인 우선순위 레벨 상승이 가능하도록 설정하는 함수입니다.

 

인자로는 Thread : PyHANDLE, DisablePriorityBoost : boolean가 있습니다.

 

Thread는 쓰레드의 핸들값입니다.

 

DisablePriorityBoost는 동적인 우선순위 레벨 상승이 가능하게 하는 값으로 True/False 입니다.

 - win32con.TRUE: 동적인 우선순위 레벨 상승을 불가능하게 합니다.

 - win32con.FALSE: 동적인 우선순위 레벨 상승을 가능하게 합니다.

값과 의미가 반대인 것에 주의해야 합니다.

 

 

import win32process
import win32api
import win32gui
import win32event
import win32con


def cnt1():
    i = 0    
    return 3
    
 
q = tuple()
res1 = win32process.beginthreadex(None, 0, cnt1, q, win32process.CREATE_SUSPENDED)


threadIOPendingFlag = win32process.GetThreadIOPendingFlag(res1[0])
threadPriority = win32process.GetThreadPriority(res1[0])
threadPriorityBoost = win32process.GetThreadPriorityBoost(res1[0])

print(f"threadIOPendingFlag : {threadIOPendingFlag}")
print(f"threadPriority : {threadPriority}")
print(f"threadPriorityBoost : {threadPriorityBoost}")

win32process.SetThreadPriorityBoost(res1[0], win32con.TRUE)
win32process.SetThreadPriority(res1[0], win32process.THREAD_PRIORITY_ABOVE_NORMAL)

threadIOPendingFlag = win32process.GetThreadIOPendingFlag(res1[0])
threadPriority = win32process.GetThreadPriority(res1[0])
threadPriorityBoost = win32process.GetThreadPriorityBoost(res1[0])

print(f"new threadIOPendingFlag : {threadIOPendingFlag}")
print(f"new threadPriority : {threadPriority}")
print(f"new threadPriorityBoostDisable : {threadPriorityBoost}")


win32process.ResumeThread(res1[0])
win32event.WaitForSingleObject(res1[0], 3000)

 

실행결과입니다. 실행 중에 IOPendingFlag가 False에서 True로 바뀌는 결과도 확인했습니다. 우선순위 셋트 중에 I/O 요청이 보류되었나 봅니다....

그리고 ThreadPriorityBoost 같은 경우에는 시스템이 동적으로 우선순위 조정하는 것을 컨트롤하는 함수라 True/False에 따른 영향을 확인하지 못했습니다....

 

 

반응형

댓글()

5. [pywin32] GetThread... 관련 함수

pywin32/win32process|2020. 12. 21. 01:38

이번에 설명할 함수는 다음의 6개 함수에 대해서 설명하려고 합니다.

 

1. int = GetExitCodeThread(handle)

 

쓰레드의 종료 코드를 반환하는 함수입니다. 쓰레드 마지막에 return X 라고 쓰면 X값이 종료 코드가 되는 것입니다.

 

인자로는 handle : PyHANDLE가 있으며, 쓰레드의 핸들값입니다.

 

2. bool = GetThreadIOPendingFlag(Thread)

 

쓰레드에 보류중인 I/O 요청이 있는지 여부를 반환하는 함수입니다.

 

인자로는 Thread : PyHANDLE가 있으며, 쓰레드의 핸들값입니다.

 

리턴값은 True/False 이며,

 - True: 보류중인 I/O 요청이 존재함

 - False: 보류중인 I/O 요청이 존재하지 않음

 

3. int = GetThreadPriority(handle)

 

쓰레드의 우선순위 레벨을 반환하는 함수입니다. 참고로 우선순위는 프로세스에서 쓰는 우선순위 클래스와 쓰레드에서 쓰는 우선순위 레벨이 존재합니다. 프로세스내의 쓰레드는 우선순위 클래스가 동일하며, 우선순위 클래스와 우선순위 레벨을 통해 기본 우선순위를 결정합니다.

 

인자로는 handle : PyHANDLE가 있으며, 쓰레드의 핸들값입니다.

 

리턴값은 다음과 같습니다.

 

이름 의미
1 win32process.THREAD_PRIORITY_ABOVE_NORMAL 우선순위 클래스보다 1포인트 높음
-1 win32process.THREAD_PRIORITY_BELOW_NORMAL 우선순위 클래스보다 1포인트 낮음
2 win32process.THREAD_PRIORITY_HIGHEST 우선순위 클래스보다 2포인트 높음
-15 win32process.THREAD_PRIORITY_IDLE REALTIME_PRIORITY_CLASS 에서는 기본 우선순위가 16이며 그외에는 1임
-2 win32process.THREAD_PRIORITY_LOWEST 우선순위 클래스보다 2포인트 낮음
0 win32process.THREAD_PRIORITY_NORMAL 우선순위 클래스의 보통 우선순위 레벨
15 win32process.THREAD_PRIORITY_TIME_CRITICAL REALTIME_PRIORITY_CLASS 에서는 기본 우선순위가 31이며 그외에는 15임

우선순위 클래스의 종류는 GetPrioiryClass 함수를 다룰 때 설명하겠습니다.

 

4. bool = GetThreadPriorityBoost(Thread)

 

쓰레드의 동적인 우선순위 레벨 상승이 가능한지 여부를 반환하는 함수입니다.

 

인자로는 Thread : PyHANDLE가 있으며, 쓰레드의 핸들값입니다.

 

리턴값이 True 일 경우, 동적 상승이 불가능하며, False일 경우, 동적 상승이 가능하다는 뜻으로 True와 False가 반대인 것에 주의해야 합니다.

 

5. int, int = GetWindowThreadProcessId(hwnd)

 

특정 윈도우를 만든 쓰레드와 프로세스의 아이디를 반환하는 함수입니다.

 

인자로는 hwnd : int가 있습니다, 이건 윈도우 핸들값입니다.

 

리턴값은 (threadId, processId) 순서입니다.

 

6. dict = GetThreadTimes(Thread)

 

쓰레드의 시간정보를 반환하는 함수입니다.

 

인자로는 Thread : PyHANDLE가 있으며, 쓰레드의 핸들값입니다.

 

리턴값은 dict 형태로, 4개의 값을 리턴합니다.

 - CreationTim: 쓰레드가 생성된 시간입니다.

 - ExitTime: 쓰레드가 종료된 시간입니다.

 - KernelTime: 쓰레드가 커널모드에서 동작한 시간입니다.

 - UserTime: 쓰레드가 유저모드에서 동작한 시간입니다.

 

 

import win32process
import win32api
import win32gui
import win32event


def cnt1():
    i = 0    
    return 3
    
q = tuple()
res1 = win32process.beginthreadex(None, 0, cnt1, q, win32process.CREATE_SUSPENDED)
win32process.ResumeThread(res1[0])

win32event.WaitForSingleObject(res1[0], 3000)
# 쓰레드가 종료될때 까지 대기

threadExitCode=win32process.GetExitCodeThread(res1[0])
threadIOPendingFlag = win32process.GetThreadIOPendingFlag(res1[0])
threadPriority = win32process.GetThreadPriority(res1[0])
threadPriorityBoost = win32process.GetThreadPriorityBoost(res1[0])
windHwnd = win32gui.GetForegroundWindow()
# 윈도우 핸들 값 획득
windThPsId = win32process.GetWindowThreadProcessId(windHwnd)
threadTime = win32process.GetThreadTimes(res1[0])


print(f"threadExitCode : {threadExitCode}")
print(f"threadIOPendingFlag : {threadIOPendingFlag}")
print(f"threadPriority : {threadPriority}")
print(f"threadPriorityBoost : {threadPriorityBoost}")
print(f"threadID : {windThPsId[0]}, processId : {windThPsId[1]}")
print(f"threadTime : {threadTime}")

 

실행결과 위와 같은 결과를 얻었다

 

 

반응형

댓글()

4. [pywin32] ResumeThread 함수

pywin32/win32process|2020. 10. 27. 00:44

int = ResumeThread(handle)

 

정지된 쓰레드를 재개하는 함수입니다. SuspendThread 함수가 Suspend count를 올린다면 ResumeThread 함수로 count를 낮춰서 0이되면 쓰레드가 재개됩니다.

 

인자로는 handle : PyHANDLE 가 있습니다.

 

handle은 재개할 쓰레드 핸들입니다.

 

리턴 값은 int로 해당 쓰레드의 이전까지의 정지 카운트입니다.

 

 

import win32process
import win32api


res1 = None
res2 = None


def cnt1():
    global res1
    i = win32process.SuspendThread(res1[0])
    print(f"cnt1 : {i}\n")
    
def cnt2(value):
    print(f"cnt2 : {value}\n")
    i = win32process.SuspendThread(res1[0])
    print(f"cnt2 : {i}\n")
    i = win32process.SuspendThread(res1[0])
    print(f"cnt2 : {i}\n")
    i = win32process.SuspendThread(res1[0])
    print(f"cnt2 : {i}\n")

    win32api.Sleep(1000)
    win32process.ResumeThread(res1[0])
    win32api.Sleep(1000)
    win32process.ResumeThread(res1[0])
    win32api.Sleep(1000)
    win32process.ResumeThread(res1[0])
    win32api.Sleep(1000)
    win32process.ResumeThread(res1[0])

q = tuple()
p = (3,)
res1 = win32process.beginthreadex(None, 0, cnt1, q, 0)
res2 = win32process.beginthreadex(None, 0, cnt2, p, 0)

SuspendThread 함수를 4번 호출했기 때문에 ResumeThread 함수 역시 4번 호출해야 합니다.

 

결과입니다~

 

 

반응형

댓글()

3. [pywin32] SuspendThread 함수

pywin32/win32process|2020. 10. 27. 00:26

int = SuspendThread(handle)

 

쓰레드를 정지시키는 함수입니다.

 

인자로는 handle : PyHANDLE 이 있습니다.

 

handle는 정지시킬 쓰레드 핸들입니다.

 

리턴 값은 int 로 해당 쓰레드의 이전까지의 정지 카운트입니다.

 

 

import win32process
import win32api


res1 = None
res2 = None


def cnt1():
    global res1
    i = win32process.SuspendThread(res1[0])
    print(f"cnt1 : {i}\n")

def cnt2(value):
    print(f"cnt2 : {value}\n")
    win32api.Sleep(3000)
    win32process.ResumeThread(res1[0])
    

q = tuple()
p = (3,)
res1 = win32process.beginthreadex(None, 0, cnt1, q, 0)
res2 = win32process.beginthreadex(None, 0, cnt2, p, 0)

 

cnt2 쓰레드가 먼저 실행되고 3초 후 cnt1 쓰레드가 실행됩니다.

 

결과입니다.~

반응형

댓글()

2. [pywin32] beginthreadex 함수

pywin32/win32process|2020. 10. 27. 00:19

PyHANDLE, int = beginthreadex(sa, stackSize , entryPoint , args , flags )

 

쓰레드를 생성하는 함수입니다.

 

인자로는 sa : PySECURITY_ATTRIBUTES, stackSize : int, entryPoint : function, args : tuple, flags : int 가 있습니다.

 

sa는 보안 속성으로 None으로 두셔도 무방합니다.

 

stackSize는 쓰레드에 할당할 스택의 크기로서 0으로 두시면 기본 스택 사이즈를 사용합니다.

 

entryPoint는 쓰레드로 실행시킬 함수를 넣어주시면 됩니다.

 

args는 튜플 형태로 entryPoint에 맞는 인자를 넣어주시면 됩니다.

 

flags는 쓰레드 시작 상태를 정할 수 있습니다.

 - win32process.CREATE_SUSPENDED : 쓰레드를 생성하지만 바로 시작하지 않습니다. (ResumeThread 함수 필요)

 - 0 : 쓰레드를 생성하고 실행합니다.

 

리턴 값은 [PyHANDLE, int] 로 각각 쓰레드 핸들과 쓰레드 ID 입니다.

 

import win32process
import win32api

res1 = None

def cnt1():
    i = 0    
    print(f"cnt1 : {i}\n")

def cnt2(value):
    global res1
    print(f"cnt2 : {value}\n")
    win32api.Sleep(3000)
    win32process.ResumeThread(res1[0]) 
    

q = tuple()
p = (3,)
res1 = win32process.beginthreadex(None, 0, cnt1, q, win32process.CREATE_SUSPENDED)
res2 = win32process.beginthreadex(None, 0, cnt2, p, 0)

 

2개의 쓰레드를 생성하였습니다. cnt2가 먼저 실행되고 3초후 ResumeThread로 cnt1 쓰레드가 실행됩니다.

 

결과입니다~

 

 

반응형

댓글()

21. [pywin32] WaitForInputIdle 함수

pywin32/win32event|2020. 10. 5. 00:30

int = WaitForInputIdle(hProcess, milliseconds )

 

WaitForInputIdle은 특정 프로세스가 만들어지고 완전히 초기화가 될 때까지 대기하는 함수입니다.

 

인자로는 hProcess : PyHANDLE, milliseconds : int 가 있습니다.

 

hProcess: 프로세스의 핸들값입니다.

 

milliseconds: 정한 시간 만큼만 대기하고, 시간이 지나면 타임 아웃이 발생합니다.

 - win32event.INFINITE: 대기 시간을 무한으로 설정합니다.

 

return 값: 프로세스가 준비가 되었는지 타임 아웃이 일어났는지 알려줍니다.

 - 0: 프로세스 준비 완료

 - win32event.WAIT_TIMEOUT: 타임 아웃

 

 

import win32event
import win32process
import win32con

prog = ".\\notepad.exe"
# 프로그램 경로

pinfo = win32process.STARTUPINFO()

pHandle = win32process.CreateProcess(prog, None, None, None, win32con.FALSE, \
                                     win32con.CREATE_NEW_CONSOLE, None, \
                                     None, pinfo)

x = win32event.WaitForInputIdle(pHandle[0], 1000)

if x == 0:
    print("ready\n")

elif x == win32event.WAIT_TIMEOUT:
    print("time out\n")

 

현재 경로의 메모장을 실행시키는 프로세스를 생성 후 WaitForInputIdle 함수를 통해 1초만 기다립니다. 1초 안에 프로세스가 초기화가 완료된다면, ready가 출력됩니다. 만약 1000 을 더 빠르게 설정한다면, 타임 아웃도 보실 수 있습니다.

 

 

 

 

반응형

댓글()