[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)<
'''
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()
####################################################################################################################################