吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 15149|回复: 14
收起左侧

[Python 转载] Python调用Win32API写win32程序(感受一下Python无所不能!!!)

  [复制链接]
lovingxiaobing 发表于 2019-2-7 14:41


来感受一下"Python无所不能"!!!

通过"ctypes"模块间接的调用win32api


代码中会用到的一些ctypes提供的功能:
。基础变量类型
。结构体
。指针
。回调函数
。ctypes提供的win32SDK的变量类型
。等等


下面的Demo会以使用opengl画图的方式展示上面提及的一些基本的功能。


先上图给大家欣赏欣赏~~~
TIM截图20190207143633.png


还可以吧,嘻嘻


下面是代码,如果大家COPY了不能运行,那就下载附件吧,Python对空白符敏感


[Python] 纯文本查看 复制代码
#coding:utf-8

#*****************************************************************
__author__ = "lovingxiaobing|小冰哟"
__email__  = "lovingxiaobing@qq.com"
__note__   = "Python 写 Win32GUI 程序 (Python无所不能!!!)\n"\
             "用到user32.dll|kernel32.dll|opengl32.dll|gdi32.dll\n"\
             "通过ctypes内建模块间接调用Win32API"
#*****************************************************************

import sys
import ctypes
from ctypes.wintypes import *

windll = ctypes.windll

####################################################################################################################################
## variable types ##
_LRESULT = ctypes.c_long
_HCURSOR = ctypes.c_void_p
_LPMSG = ctypes.c_void_p
_LPWNDCLASSA = ctypes.c_void_p
_ULONG_PTR = LPVOID
_LPPAINTSTRUCT = LPVOID
_ARGB = DWORD
_HGLRC = LPVOID

WNDPROC = ctypes.WINFUNCTYPE(_LRESULT, HWND, UINT, WPARAM, LPARAM,)
####################################################################################################################################

## structure ##
### WNDCLASSA ##
class WNDCLASSA(ctypes.Structure):
    _fields_ = [
        ("style",       UINT),
        ("lpfnWndProc", WNDPROC),
        ("cbClsExtra",  INT),
        ("cbWndExtra",  INT),
        ("hInstance",   HINSTANCE),
        ("hIcon",       HICON),
        ("hCursor",     _HCURSOR),
        ("hbrBackground", HBRUSH),
        ("lpszMenuName",  LPCSTR),
        ("lpszClassName", LPCSTR)
    ]


class PIXELFORMATDESCRIPTOR(ctypes.Structure):
    _fields_ = [
        ("nSize",           WORD),
        ("nVersion",        WORD),
        ("dwFlags",         DWORD),
        ("iPixelType",      BYTE),
        ("cColorBits",      BYTE),
        ("cRedBits",        BYTE),
        ("cRedShift",       BYTE),
        ("cGreenBits",      BYTE),
        ("cGreenShift",     BYTE),
        ("cBlueBits",       BYTE),
        ("cBlueShift",      BYTE),
        ("cAlphaBits",      BYTE),
        ("cAlphaShift",     BYTE),
        ("cAccumBits",      BYTE),
        ("cAccumRedBits",   BYTE),
        ("cAccumGreenBits", BYTE),
        ("cAccumBlueBits",  BYTE),
        ("cAccumAlphaBits", BYTE),
        ("cDepthBits",      BYTE),
        ("cStencilBits",    BYTE),
        ("cAuxBuffers",     BYTE),
        ("iLayerType",      BYTE),
        ("bReserved",       BYTE),
        ("dwLayerMask",     DWORD),
        ("dwVisibleMask",   DWORD),
        ("dwDamageMask",    DWORD)
    ]

####################################################################################################################################
## kernel32.dll ##
### kernel32.dll exports ##
GetModuleHandle = windll.kernel32.GetModuleHandleA
GetModuleHandle.restype = HMODULE

####################################################################################################################################
## user32.dll ##
user32 = windll.LoadLibrary("user32.dll")
### user32.dll exports ##
#窗口类注册函数
RegisterClass = user32.RegisterClassA
RegisterClass.argtypes = (_LPWNDCLASSA,)
RegisterClass.restype = ATOM

#窗口显示函数
ShowWindow = user32.ShowWindow
ShowWindow.argtypes = (HWND, INT,)

#发送窗口线程结束消息
PostQuitMessage = user32.PostQuitMessage
PostQuitMessage.argtypes = (INT,)

#默认处理窗口过程 函数
DefWindowProc = user32.DefWindowProcA
DefWindowProc.argtypes = (HWND, UINT, WPARAM, LPARAM,)
DefWindowProc.restype = _LRESULT

#创建窗口函数
CreateWindowEx = user32.CreateWindowExA
CreateWindowEx.restype = HWND

#从消息队列获取消息 函数
GetMessage = user32.GetMessageA
GetMessage.argtypes = (_LPMSG, HWND, WPARAM, LPARAM,)
GetMessage.restype = BOOL

#下面是一些消息加工以及派发给窗口的 函数
TranslateMessage = user32.TranslateMessage
TranslateMessage.argtypes = (_LPMSG,)
DispatchMessage = user32.DispatchMessageA
DispatchMessage.argtypes = (_LPMSG,)

#加载窗口图标
LoadIcon = user32.LoadIconA
LoadIcon.argtypes = (HINSTANCE, LPCSTR,)
LoadIcon.restype = HICON

#加载窗口鼠标指针
LoadCursor = user32.LoadCursorA
LoadCursor.argtypes = (HINSTANCE, LPCSTR,)
LoadCursor.restype = _HCURSOR

#收到WM_PAINT后处理函数
BeginPaint = user32.BeginPaint
BeginPaint.argtypes = (HWND, _LPPAINTSTRUCT,)
BeginPaint.restype = HDC
EndPaint = user32.EndPaint
EndPaint.argtypes = (HWND, _LPPAINTSTRUCT,)
EndPaint.restype = HDC

GetDC = user32.GetDC
GetDC.argtypes = (HWND,)
GetDC.restype = HDC

ReleaseDC = user32.ReleaseDC
ReleaseDC.argtypes = (HWND, HDC,)
ReleaseDC.restype = INT

####################################################################################################################################
## opengl32.dll ##
opengl32 = windll.LoadLibrary("opengl32.dll")

wglCreateContext = opengl32.wglCreateContext
wglCreateContext.argtypes = (HDC,)
wglCreateContext.restype = _HGLRC

wglMakeCurrent = opengl32.wglMakeCurrent
wglMakeCurrent.argtypes = (HDC, _HGLRC,)
wglMakeCurrent.restype = BOOL

wglDeleteContext = opengl32.wglDeleteContext
wglDeleteContext.argtypes = (_HGLRC,)
wglDeleteContext.restype = BOOL

glClearColor = opengl32.glClearColor
glClearColor.argtypes = (FLOAT, FLOAT, FLOAT, FLOAT,)

glClear = opengl32.glClear
glClear.argtypes = (UINT,)

glBegin = opengl32.glBegin
glBegin.argtypes = (UINT,)

glEnd = opengl32.glEnd

glColor3f = opengl32.glColor3f
glColor3f.argtypes = (FLOAT, FLOAT, FLOAT,)

glColor4f = opengl32.glColor4f
glColor4f.argtypes = (FLOAT, FLOAT, FLOAT, FLOAT,)

glVertex2f = opengl32.glVertex2f
glVertex2f.argtypes = (FLOAT, FLOAT,)

glEnable = opengl32.glEnable
glEnable.argtypes = (UINT,)

glDisable = opengl32.glDisable
glDisable.argtypes = (UINT,)

glBlendFunc = opengl32.glBlendFunc
glBlendFunc.argtypes = (UINT, UINT,)

glHint = opengl32.glHint
glHint.argtypes = (UINT, UINT,)

glViewport = opengl32.glViewport
glViewport.argtypes = (INT, INT, INT, INT,)

####################################################################################################################################
## gdi32.dll ##
gdi32 = windll.LoadLibrary("gdi32.dll")

SetPixelFormat = gdi32.SetPixelFormat
SetPixelFormat.argtypes = (HDC, INT, ctypes.POINTER(PIXELFORMATDESCRIPTOR),)
SetPixelFormat.restype = BOOL

ChoosePixelFormat = gdi32.ChoosePixelFormat
ChoosePixelFormat.argtypes = (HDC, ctypes.POINTER(PIXELFORMATDESCRIPTOR),)
ChoosePixelFormat.restype = INT

SwapBuffers = gdi32.SwapBuffers
SwapBuffers.argtypes = (HDC,)
SwapBuffers.restype = BOOL

####################################################################################################################################
## macro ##
NULL = None
FALSE = BOOL(0)
TRUE = BOOL(1)

SW_SHOWDEFAULT = 0xA

CS_VREDRAW = 0x0001
CS_HREDRAW = 0x0002

WS_OVERLAPPED = 0x00000000
WS_SYSMENU = 0x00080000
WS_SIZEBOX = 0x00040000

CW_USEDEFAULT = 0x80000000

COLOR_BACKGROUND = 0x00000001

WM_DESTROY = 0x0002
WM_CREATE = 0x0001
WM_PAINT = 0x000F
WM_SIZE = 0x0005

IDI_APPLICATION = 32512
IDC_ARROW = 32512

'''
AlphaShift  = 24
RedShift    = 16
GreenShift  = 8
BlueShift   = 0
MakeARGB = lambda a,r,g,b: ((b)<<BlueShift)|((g)<<GreenShift)|((r)<<RedShift)|((a)<<AlphaShift)
'''

MAKEINTRESOURCE = lambda v:LPCSTR(v)
ZeroMemory = lambda addr,nsize: ctypes.memset(addr, 0, nsize)
LOWORD = lambda n: n&0xffff
HIWORD = lambda m: LOWORD(m>>0x10)

PFD_DRAW_TO_WINDOW = 0x00000004
PFD_SUPPORT_OPENGL = 0x00000020
PFD_DOUBLEBUFFER   = 0x00000001
PFD_TYPE_RGBA = 0
PFD_MAIN_PLANE = 0

GL_COLOR_BUFFER_BIT = 0x00004000
GL_TRIANGLES = 0x0004
GL_LINE_LOOP = 0x0002
GL_BLEND = 0x0BE2
GL_SRC_ALPHA = 0x0302
GL_ONE_MINUS_SRC_ALPHA = 0x0303
GL_LINE_SMOOTH = 0x0B20
GL_NICEST = 0x1102
####################################################################################################################################

## globals ##
g_ClassName = ctypes.create_string_buffer("SupriseWindowByPythonCoding".encode('gbk'))
g_WindowTitle = ctypes.create_string_buffer("嘤嘤嘤窗口".encode('gbk'))
g_hwnd = NULL
g_border_width = 640
g_border_height = 640

g_hwnd = HWND(NULL)
g_hdc = HDC(NULL)
g_hrc = _HGLRC(NULL)
####################################################################################################################################

def InitAppliction(hInstance):
    global WindowProc
    wndcls = WNDCLASSA(
        lpszClassName = ctypes.addressof(g_ClassName),
        lpfnWndProc = WindowProc,
        style = CS_VREDRAW|CS_HREDRAW,
        cbClsExtra = 0,
        cbWndExtra = 0,
        hInstance = hInstance,
        hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)),
        hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)),
        hbrBackground = COLOR_BACKGROUND,
        lpszMenuName = LPCSTR(NULL)
    )

    return True if RegisterClass(ctypes.addressof(wndcls)) else False

####################################################################################################################################

#主函数
def WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow):
    if False == InitAppliction(hInstance):
        raise ctypes.WinError("[RegisterClass]Last Error Code: %d" % (ctypes.GetLastError()))

    hwnd = CreateWindowEx(
        0,
        ctypes.addressof(g_ClassName),
        ctypes.addressof(g_WindowTitle),
        WS_OVERLAPPED|WS_SYSMENU|WS_SIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT,
        g_border_width, g_border_height,
        NULL, NULL,
        hInstance,
        NULL
    )

    if NULL == hwnd:
        raise ctypes.WinError("[CreateWindowEx]Last Error Code: %d" % (ctypes.GetLastError()))
    
    ShowWindow(hwnd, nCmdShow)

    messages = MSG()
    lpmessages = ctypes.addressof(messages)

    #消息循环
    while GetMessage(lpmessages, NULL, 0, 0):
        TranslateMessage(lpmessages)
        DispatchMessage(lpmessages)
    
    return messages.wParam

####################################################################################################################################
# 收到重绘消息响应函数
def OnPaint():
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glClear(GL_COLOR_BUFFER_BIT)

    # 线条抗锯齿
    #glEnable(GL_LINE_SMOOTH)
    #glHint(GL_LINE_SMOOTH, GL_NICEST)

    # 混合(透明)
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

    ## 画两个叠在一起的三角形
    glBegin(GL_TRIANGLES)
    glColor3f(1.0, 0.0, 0.0)
    glVertex2f(0.0, 1.0)

    glColor3f(0.0, 1.0, 0.0)
    glVertex2f(0.87, -0.5)

    glColor3f(0.0, 0.0, 1.0)
    glVertex2f(-0.87, -0.5)
    glEnd()

    glBegin(GL_TRIANGLES)
    glColor4f(1.0, 0.0, 0.0, 0.5)
    glVertex2f(0.87, 0.5)

    glColor4f(0.0, 0.0, 1.0, 0.5)
    glVertex2f(-0.87, 0.5)

    glColor4f(0.0, 1.0, 0.0, 0.5)
    glVertex2f(0.0, -1.0)
    glEnd()
    ## ***********
    glDisable(GL_BLEND)

    ## 画六边形彩色边框
    glBegin(GL_LINE_LOOP)

    glColor3f(1.0, 0.0, 0.0)
    glVertex2f(0.0, 1.0)

    glColor3f(0.0, 1.0, 0.0)
    glVertex2f(0.87, 0.5)

    glColor3f(0.0, 0.0, 1.0)
    glVertex2f(0.87, -0.5)

    glColor3f(1.0, 0.0, 0.0)
    glVertex2f(0.0, -1.0)

    glColor3f(0.0, 1.0, 0.0)
    glVertex2f(-0.87, -0.5)

    glColor3f(0.0, 0.0, 1.0)
    glVertex2f(-0.87, 0.5)
    glEnd()

    #glDisable(GL_LINE_SMOOTH)

    SwapBuffers(g_hdc)

####################################################################################################################################
#窗口过程函数
@ctypes.WINFUNCTYPE(_LRESULT, HWND, UINT, WPARAM, LPARAM)
def WindowProc(hwnd, message, wParam, lParam):

    if WM_PAINT == message:
        BeginPaint(hwnd, _LPPAINTSTRUCT(NULL))
        OnPaint()
        EndPaint(hwnd, _LPPAINTSTRUCT(NULL))
    elif WM_SIZE == message:
        w = LOWORD(lParam)
        h = HIWORD(lParam)
        glViewport(0, 0, w, h)
    elif WM_DESTROY == message:
        DisableOpenGL()
        PostQuitMessage(0)
    elif WM_CREATE == message:
        global g_hwnd
        g_hwnd = hwnd
        EnableOpenGL()
    else:
        return DefWindowProc(hwnd, message, wParam, lParam)
    
    return 0

####################################################################################################################################
# 初始化Opengl上下文
def EnableOpenGL():
    global g_hwnd
    global g_hdc
    global g_hrc

    g_hdc = GetDC(g_hwnd)
    iFormat = INT(0)

    pfd = PIXELFORMATDESCRIPTOR()
    ZeroMemory(ctypes.addressof(pfd), ctypes.sizeof(pfd))

    pfd.nSize = ctypes.sizeof(pfd)
    pfd.nVersion = 1
    pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER
    pfd.iPixelType = PFD_TYPE_RGBA
    pfd.cColorBits = 24
    pfd.cDepthBits = 16
    pfd.iLayerType = PFD_MAIN_PLANE

    iFormat = ChoosePixelFormat(g_hdc, ctypes.byref(pfd))
    SetPixelFormat(g_hdc, iFormat, ctypes.byref(pfd))

    g_hrc = wglCreateContext(g_hdc)
    wglMakeCurrent(g_hdc, g_hrc)

####################################################################################################################################
# 注销opengl上下文
def DisableOpenGL():
    wglMakeCurrent(NULL, NULL)
    wglDeleteContext(g_hrc)
    ReleaseDC(g_hwnd, g_hdc)

####################################################################################################################################

## 主函数入口参数(应用入口)
def ApplicationEntry():
    hInstance = GetModuleHandle(NULL)
    hPrevInstance = NULL
    lpCmdLine = sys.argv
    nCmdShow = SW_SHOWDEFAULT
    ## 调用主函数
    WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)

####################################################################################################################################

if "__main__" == __name__:
    ApplicationEntry()

####################################################################################################################################



祝大家新年快乐,****(暗示!!!)


GUIAppWithWin32API.zip (3.79 KB, 下载次数: 61)

免费评分

参与人数 5吾爱币 +9 热心值 +3 收起 理由
笙若 + 1 + 1 谢谢@Thanks!
zerglurker + 1 + 1 谢谢@Thanks!
吾爱支持 + 1 谢谢@Thanks!
苏紫方璇 + 5 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
微微笑95 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| lovingxiaobing 发表于 2020-9-4 01:20
shinykers 发表于 2020-2-22 11:25
楼主牛!
不过能不能做是一回事,好不好做也值得考虑啊~
请问楼主,做这个事情,是否有更简单的办法呢?

pywin32:
https://github.com/mhammond/pywin32

现在可以通过pip在线安装,也可以到它的github页下载编译好的模块。
 楼主| lovingxiaobing 发表于 2019-2-9 12:33
hanlu5016 发表于 2019-2-8 15:50
这个能在win7上用不

ctypes的一个小缺陷,使用的数据类型的尺寸是32位机器的大小,但是调用的却是64位的api,这个很伤~~~~
但是32位机器上运行无问题。
小冰运行这个程序的环境是:win10 32位|python3.7.1
xu6456338 发表于 2019-2-7 15:32
头像被屏蔽
加油 发表于 2019-2-7 16:08
提示: 作者被禁止或删除 内容自动屏蔽
吾爱支持 发表于 2019-2-7 16:37
感谢楼主分享……学习了。
送上小CB和祝福
hackysh 发表于 2019-2-7 17:25
成品在哪?  上传啊啊
zjmowu 发表于 2019-2-7 17:31

感谢楼主分享……学习了。
绅士· 发表于 2019-2-7 17:47
楼主可以的
hanlu5016 发表于 2019-2-8 15:50 来自手机
这个能在win7上用不
南川没有北鱼 发表于 2020-2-20 11:31
感谢楼主,学习一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 19:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表