使用Windows API制作多个Windows的最佳/理想方法是什么?
我有一个带有一堆按钮的窗户。这些按钮上有文件的名称。当用户单击按钮时,我想打开该文件,读取它,将其写入编辑框并在屏幕上显示。我想删除所有按钮,然后制作一个编辑框。当用户按“主页”按钮时,我的程序应将其带到按钮页面。
到目前为止,我正在考虑使用DestroyWindow,然后创建一个新窗口。我不确定这是我应该做的。 (另外,我正在使用python,以防万一您想知道为什么我有python标签)
main.py
from os import listdir
from user32 import *
from button import Button
from pathlib import Path
hInst = windll.kernel32.GetModuleHandleW(0)
buttons = []
BTN_WIDTH = 300
BTN_HEIGHT = 100
LINES = 10
def window_proc(hwnd: HWND, umsg: UINT, wparam: WPARAM, lparam: LPARAM) -> LRESULT:
si = SCROLLINFO()
si_pointer = pointer(si)
match umsg:
case WindowMessage.CREATE:
create_list_of_buttons(get_files(), hwnd)
case WindowMessage.DESTROY:
PostQuitMessage(0)
return 0
case WindowMessage.SIZE:
height = (HIWORD(lparam))
width = (LOWORD(lparam))
si.cbSize = sizeof(si)
si.fMask = ScrollInfoMessage.RANGE | ScrollInfoMessage.PAGE
si.nMin = 0
print(width)
si.nMax = BTN_HEIGHT * 5 - 60
si.nPage = 1;
SetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer, True)
case WindowMessage.COMMAND:
if wparam >= 100:
btn_clicked = ([button for button in buttons if button.hMenu == wparam])
filename = btn_clicked[0].btn_text
print(filename)
rect = RECT()
rect_p = pointer(rect)
# print(GetClientRect(hwnd, rect_p))
# print(rect.top, rect.bottom, rect.left, rect.right)
case WindowMessage.VSCROLL:
si.cbSize = sizeof(si)
si.fMask = ScrollInfoMessage.ALL
GetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer)
yPos = si.nPos
match LOWORD(wparam).value:
case ScrollBarCommands.LINEUP:
si.nPos -= 1
case ScrollBarCommands.TOP:
si.nPos = si.nMin
case ScrollBarCommands.BOTTOM:
si.nPos = si.nMax
case ScrollBarCommands.LINEUP:
si.nPos -= 1
case ScrollBarCommands.LINEDOWN:
si.nPos += 1
case ScrollBarCommands.PAGEUP:
si.nPos -= si.nPage
case ScrollBarCommands.PAGEDOWN:
si.nPos += si.nPage
case ScrollBarCommands.THUMBTRACK:
si.nPos = si.nTrackPos
si.fMask = ScrollInfoMessage.POS
SetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer, True)
GetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer)
if(si.nPos != yPos):
ScrollWindowEx(hwnd, -0, (yPos - si.nPos), None, None, None, None, 0x0001|0x0002)
hdwp = BeginDeferWindowPos(1)
recent_hdwp = DeferWindowPos(hdwp, hwnd, None, 0, 0, 100, 100, 0x0020|0x0004|0x0001|0x0002)
EndDeferWindowPos(recent_hdwp)
UpdateWindow(hwnd)
return DefWindowProcW(hwnd, umsg, wparam, lparam)
def create_window(className, windowName):
wnd_main = CreateWindowExW(
0,
className,
windowName,
WindowStyles.OVERLAPPED
| WindowStyles.CAPTION
| WindowStyles.SYSMENU
| WindowStyles.THICKFRAME
| WindowStyles.MINIMIZEBOX
| WindowStyles.MAXIMIZEBOX
| WindowStyles.CAPTION
| WindowStyles.VSCROLL,
CW_USEDEFAULT,
CW_USEDEFAULT,
600,
600,
0,
0,
hInst,
0,
)
if not wnd_main:
print("Window Creation Falid: ", GetLastError())
return
return wnd_main
def get_files():
folder_path = Path(__file__).parent / "log"
return [file for file in listdir(folder_path) if file.endswith(".txt")]
def create_list_of_buttons(filenames: list[str], parent_window):
"""
Makes a list of button that have the file's name as their heading
"""
x, y = 0, 0
for button_id, filename in enumerate(filenames, 100):
button = Button(filename, x, y, BTN_WIDTH, BTN_HEIGHT, parent_window, button_id)
button.create_button()
buttons.append(button)
y += BTN_HEIGHT
return buttons
def main():
wclassName = ctypes.c_wchar_p("My")
wname = ctypes.c_wchar_p("Left")
wndClass = WNDCLASSEXW()
wndClass.cbSize = sizeof(WNDCLASSEXW)
wndClass.style = ClassStyles.HREDRAW | ClassStyles.VREDRAW
wndClass.lpfnWndProc = WNDPROC(window_proc)
wndClass.cbClsExtra = 0
wndClass.cbWndExtra = 0
wndClass.hInstance = hInst
wndClass.hIcon = 0
wndClass.hCursor = 0
wndClass.hBrush = windll.gdi32.GetStockObject(0)
wndClass.lpszMenuName = 0
wndClass.lpszClassName = wclassName
wndClass.hIconSm = 0
RegisterClassExW(byref(wndClass))
wnd_main = create_window(wclassName, wname)
ShowWindow(wnd_main, 5)
UpdateWindow(wnd_main)
msg = MSG()
lpmsg = pointer(msg)
while (GetMessageW(lpmsg, 0, 0, 0)) != 0:
TranslateMessage(lpmsg)
DispatchMessageW(lpmsg)
main()
user32.py
import ctypes
import enum
from ctypes import *
from ctypes.wintypes import *
WNDPROC = ctypes.WINFUNCTYPE(c_int, HWND, c_uint, WPARAM, LPARAM)
LRESULT = c_long
LONG_PTR = LPARAM
CW_USEDEFAULT = 0x80000000
WNDENUMPROC = ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM)
user32 = windll.user32
class WindowStyles(enum.IntFlag):
BORDER = 0x00800000
CAPTION = 0x00C00000
CHILD = 0x40000000
CHILDWINDOW = 0x40000000
CLIPCHILDREN = 0x02000000
CLIPSIBLINGS = 0x04000000
DISABLED = 0x08000000
DLGFRAME = 0x00400000
GROUP = 0x00020000
HSCROLL = 0x00100000
ICONIC = 0x20000000
MAXIMIZE = 0x01000000
MAXIMIZEBOX = 0x00010000
MINIMIZE = 0x20000000
MINIMIZEBOX = 0x00020000
OVERLAPPED = 0x00000000
SYSMENU = 0x00080000
THICKFRAME = 0x00040000
TILED = 0x00000000
VISIBLE = 0x10000000
VSCROLL = 0x00200000
SIZEBOX = 0x00040000
TABSTOP = 0x00010000
POPUP = 0x80000000
TILEDWINDOW = (
OVERLAPPED | CAPTION | SYSMENU | THICKFRAME | MINIMIZEBOX | MAXIMIZEBOX
)
OVERLAPPEDWINDOW = (
OVERLAPPED | CAPTION | SYSMENU | THICKFRAME | MINIMIZEBOX | MAXIMIZEBOX
)
POPUPWINDOW = POPUP | BORDER | SYSMENU
class WindowMessage(enum.IntEnum):
SETFOCUS = 0x0007
KILLFOCUS = 0x0006
ENABLE = 0x000A
SETREDRAW = 0x000B
SETTEXT = 0x000C
SETFONT = 0x0030
GETFONT = 0x0031
GETTEXT = 0x000D
GETTEXTLENGTH = 0x000E
PAINT = 0x000F
CLOSE = 0x00010
QUIT = 0x0012
SHOWWINDOW = 0x0018
NULL = 0x0000
CREATE = 0x0001
DESTROY = 0x0002
MOVE = 0x0003
SIZE = 0x0005
ACTIVATE = 0x0006
COMMAND = 0x0111
NOTIFY = 0x004E
VSCROLL = 0x0115
class ClassStyles(enum.IntFlag):
VREDRAW = 0x0001
HREDRAW = 0x0002
DBLCLKS = 0x0008
OWNDC = 0x0020
CLASSDC = 0x0040
PARENTDC = 0x0080
NOCLOSE = 0x0200
SAVEBITS = 0x0800
BYTEALIGNCLIENT = 0x1000
BYTEALIGNWINDOW = 0x2000
GLOBALCLASS = 0x4000
class ButtonStyle(enum.IntFlag):
PUSHBUTTON = 0x00000000
DEFPUSHBUTTON = 0x00000001
CHECKBOX = 0x00000002
AUTOCHECKBOX = 0x00000003
RADIOBUTTON = 0x00000004
_3STATE = 0x00000005
AUTO3STATE = 0x00000006
GROUPBOX = 0x00000007
USERBUTTON = 0x00000008
AUTORADIOBUTTON = 0x00000009
PUSHBOX = 0x0000000A
OWNERDRAW = 0x0000000B
TYPEMASK = 0x0000000F
LEFTTEXT = 0x00000020
TEXT = 0x00000000
ICON = 0x00000040
BITMAP = 0x00000080
LEFT = 0x00000100
RIGHT = 0x00000200
CENTER = 0x00000300
TOP = 0x00000400
BOTTOM = 0x00000800
VCENTER = 0x00000C00
PUSHLIKE = 0x00001000
MULTILINE = 0x00002000
NOTIFY = 0x00004000
FLAT = 0x00008000
RIGHTBUTTON = LEFTTEXT
class WNDCLASSEXW(Structure):
_fields_ = [
("cbSize", c_uint),
("style", c_uint),
("lpfnWndProc", WNDPROC),
("cbClsExtra", c_int),
("cbWndExtra", c_int),
("hInstance", HANDLE),
("hIcon", HANDLE),
("hCursor", HANDLE),
("hBrush", HANDLE),
("lpszMenuName", LPCWSTR),
("lpszClassName", LPCWSTR),
("hIconSm", HANDLE),
]
class MSG(Structure):
_fields_ = [
("hwnd", HWND),
("message", c_int),
("wParam", WPARAM),
("lParam", LPARAM),
("time", DWORD),
("pt", POINT),
("lPrivate", DWORD),
]
class GetWindowLong(enum.IntEnum):
EXSTYLE = -20
HINSTANCE = -6
HWNDPARENT = -8
ID = -12
STYLE = -16
USERDATA = -21
WNDPROC = -4
class SCROLLINFO(Structure):
_fields_ = [
("cbSize", UINT),
("fMask", UINT),
("nMin", c_int),
("nMax", c_int),
("nPage", UINT),
("nPos", c_int),
("nTrackPos", c_int),
]
class ScrollInfoMessage(enum.IntEnum):
RANGE = 0x0001
PAGE = 0x0002
POS = 0x0004
DISABLENOSCROLL = 0x0008
TRACKPOS = 0x0010
ALL = RANGE | PAGE | POS | TRACKPOS
class ScrollBarConstants(enum.IntEnum):
HORZ = 0
VERT = 1
CTL = 2
BOTH = 3
class ScrollBarCommands(enum.IntEnum):
LINEUP = 0
LINELEFT = 0
LINEDOWN = 1
LINERIGHT = 1
PAGEUP = 2
PAGELEFT = 2
PAGEDOWN = 3
PAGERIGHT = 3
THUMBPOSITION = 4
THUMBTRACK = 5
TOP = 6
LEFT = 6
BOTTOM = 7
RIGHT = 7
ENDSCROLL = 8
def HIWORD(l):
return WORD((l >> 16) & 0xFFFF)
def LOWORD(l):
return WORD(l & 0xFFFF)
LPMSG = POINTER(MSG)
LPCSCROLLINFO = POINTER(SCROLLINFO)
DefWindowProcW = user32.DefWindowProcW
DefWindowProcW.argtypes = [HWND, UINT, WPARAM, LPARAM]
DefWindowProcW.restype = LRESULT
CreateWindowExW = user32.CreateWindowExW
CreateWindowExW.argtypes = [
DWORD,
LPCWSTR,
LPCWSTR,
DWORD,
c_int,
c_int,
c_int,
c_int,
HWND,
HMENU,
HINSTANCE,
LPVOID,
]
CreateWindowExW.restype = HWND
LPWNDCLASSW = POINTER(WNDCLASSEXW)
RegisterClassExW = user32.RegisterClassExW
RegisterClassExW.argtypes = [LPWNDCLASSW]
RegisterClassExW.restype = ATOM
ShowWindow = user32.ShowWindow
ShowWindow.argtypes = [HWND, c_int]
ShowWindow.restype = BOOL
UpdateWindow = user32.UpdateWindow
UpdateWindow.argtypes = [HWND]
UpdateWindow.restype = BOOL
GetMessageW = user32.GetMessageW
GetMessageW.argtypes = [LPMSG, HWND, UINT, UINT]
GetMessageW.restype = BOOL
TranslateMessage = user32.TranslateMessage
TranslateMessage.argtypes = [LPMSG]
TranslateMessage.restype = BOOL
DispatchMessageW = user32.DispatchMessageW
DispatchMessageW.argtypes = [LPMSG]
DispatchMessageW.restype = LRESULT
PostQuitMessage = user32.PostQuitMessage
PostQuitMessage.argtypes = [c_int]
PostQuitMessage.restype = None
GetWindowLongPtrW = user32.GetWindowLongPtrW
GetWindowLongPtrW.argtypes = [HWND, c_int]
GetWindowLongPtrW.restype = LONG_PTR
GetWindow = user32.GetWindow
GetWindow.argtypes = [HWND, UINT]
GetWindow.restype = HWND
ScrollWindowEx = user32.ScrollWindowEx
ScrollWindowEx.argtypes = [HWND, c_int, c_int, LPRECT, LPRECT, HRGN, LPRECT, UINT]
ScrollWindowEx.restype = int
SetScrollInfo = user32.SetScrollInfo
SetScrollInfo.argtypes = [HWND, c_int, LPCSCROLLINFO, BOOL]
SetScrollInfo.restype = int
GetScrollInfo = user32.GetScrollInfo
GetScrollInfo.argtypes = [HWND, c_int, LPCSCROLLINFO]
GetScrollInfo.restype = BOOL
GetClientRect = user32.GetClientRect
GetClientRect.argtypes = [HWND, LPRECT]
GetClientRect.restype = BOOL
BeginDeferWindowPos = user32.BeginDeferWindowPos
BeginDeferWindowPos.argtypes = [c_int]
BeginDeferWindowPos.restype = HDWP
DeferWindowPos = user32.DeferWindowPos
DeferWindowPos.argtypes = [HDWP, HWND, HWND, c_int, c_int, c_int, c_int, c_uint]
DeferWindowPos.restype = HDWP
EndDeferWindowPos = user32.EndDeferWindowPos
EndDeferWindowPos.argtypes = [HDWP]
EndDeferWindowPos.restype = BOOL
button.py
from ctypes.wintypes import HINSTANCE, HMENU, HWND, LPCWSTR, LPVOID
from dataclasses import dataclass
from ctypes import *
from user32 import (
ButtonStyle,
CreateWindowExW,
GetWindowLongPtrW,
WindowStyles,
GetWindowLong,
)
@dataclass
class Button:
btn_text: LPCWSTR
x: c_int
y: c_int
width: c_int
height: c_int
hwnd_parent: HWND
hMenu: HMENU
def create_button(self):
button = CreateWindowExW(
0,
"BUTTON",
self.btn_text,
WindowStyles.TABSTOP
| WindowStyles.VISIBLE
| WindowStyles.CHILD
| ButtonStyle.PUSHBUTTON,
self.x,
self.y,
self.width,
self.height,
self.hwnd_parent,
HMENU(self.hMenu),
cast(
GetWindowLongPtrW(self.hwnd_parent, GetWindowLong.HINSTANCE), HINSTANCE
),
None,
)
return button
I have a window with a bunch of buttons. Those buttons have file's names on them. When the user clicks a button, I want to open that file, read it, write it to an edit box and display it on the screen. I would like to delete all the buttons and just make an edit box. When the user presses the home button, my program should take them to the button page.
So far, I am thinking of using DestroyWindow and then create a new window. I am not sure if this is how I am supposed to do it. (Also, I am using python, just in case you were wondering why I have the python tag)
main.py
from os import listdir
from user32 import *
from button import Button
from pathlib import Path
hInst = windll.kernel32.GetModuleHandleW(0)
buttons = []
BTN_WIDTH = 300
BTN_HEIGHT = 100
LINES = 10
def window_proc(hwnd: HWND, umsg: UINT, wparam: WPARAM, lparam: LPARAM) -> LRESULT:
si = SCROLLINFO()
si_pointer = pointer(si)
match umsg:
case WindowMessage.CREATE:
create_list_of_buttons(get_files(), hwnd)
case WindowMessage.DESTROY:
PostQuitMessage(0)
return 0
case WindowMessage.SIZE:
height = (HIWORD(lparam))
width = (LOWORD(lparam))
si.cbSize = sizeof(si)
si.fMask = ScrollInfoMessage.RANGE | ScrollInfoMessage.PAGE
si.nMin = 0
print(width)
si.nMax = BTN_HEIGHT * 5 - 60
si.nPage = 1;
SetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer, True)
case WindowMessage.COMMAND:
if wparam >= 100:
btn_clicked = ([button for button in buttons if button.hMenu == wparam])
filename = btn_clicked[0].btn_text
print(filename)
rect = RECT()
rect_p = pointer(rect)
# print(GetClientRect(hwnd, rect_p))
# print(rect.top, rect.bottom, rect.left, rect.right)
case WindowMessage.VSCROLL:
si.cbSize = sizeof(si)
si.fMask = ScrollInfoMessage.ALL
GetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer)
yPos = si.nPos
match LOWORD(wparam).value:
case ScrollBarCommands.LINEUP:
si.nPos -= 1
case ScrollBarCommands.TOP:
si.nPos = si.nMin
case ScrollBarCommands.BOTTOM:
si.nPos = si.nMax
case ScrollBarCommands.LINEUP:
si.nPos -= 1
case ScrollBarCommands.LINEDOWN:
si.nPos += 1
case ScrollBarCommands.PAGEUP:
si.nPos -= si.nPage
case ScrollBarCommands.PAGEDOWN:
si.nPos += si.nPage
case ScrollBarCommands.THUMBTRACK:
si.nPos = si.nTrackPos
si.fMask = ScrollInfoMessage.POS
SetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer, True)
GetScrollInfo(hwnd, ScrollBarConstants.VERT, si_pointer)
if(si.nPos != yPos):
ScrollWindowEx(hwnd, -0, (yPos - si.nPos), None, None, None, None, 0x0001|0x0002)
hdwp = BeginDeferWindowPos(1)
recent_hdwp = DeferWindowPos(hdwp, hwnd, None, 0, 0, 100, 100, 0x0020|0x0004|0x0001|0x0002)
EndDeferWindowPos(recent_hdwp)
UpdateWindow(hwnd)
return DefWindowProcW(hwnd, umsg, wparam, lparam)
def create_window(className, windowName):
wnd_main = CreateWindowExW(
0,
className,
windowName,
WindowStyles.OVERLAPPED
| WindowStyles.CAPTION
| WindowStyles.SYSMENU
| WindowStyles.THICKFRAME
| WindowStyles.MINIMIZEBOX
| WindowStyles.MAXIMIZEBOX
| WindowStyles.CAPTION
| WindowStyles.VSCROLL,
CW_USEDEFAULT,
CW_USEDEFAULT,
600,
600,
0,
0,
hInst,
0,
)
if not wnd_main:
print("Window Creation Falid: ", GetLastError())
return
return wnd_main
def get_files():
folder_path = Path(__file__).parent / "log"
return [file for file in listdir(folder_path) if file.endswith(".txt")]
def create_list_of_buttons(filenames: list[str], parent_window):
"""
Makes a list of button that have the file's name as their heading
"""
x, y = 0, 0
for button_id, filename in enumerate(filenames, 100):
button = Button(filename, x, y, BTN_WIDTH, BTN_HEIGHT, parent_window, button_id)
button.create_button()
buttons.append(button)
y += BTN_HEIGHT
return buttons
def main():
wclassName = ctypes.c_wchar_p("My")
wname = ctypes.c_wchar_p("Left")
wndClass = WNDCLASSEXW()
wndClass.cbSize = sizeof(WNDCLASSEXW)
wndClass.style = ClassStyles.HREDRAW | ClassStyles.VREDRAW
wndClass.lpfnWndProc = WNDPROC(window_proc)
wndClass.cbClsExtra = 0
wndClass.cbWndExtra = 0
wndClass.hInstance = hInst
wndClass.hIcon = 0
wndClass.hCursor = 0
wndClass.hBrush = windll.gdi32.GetStockObject(0)
wndClass.lpszMenuName = 0
wndClass.lpszClassName = wclassName
wndClass.hIconSm = 0
RegisterClassExW(byref(wndClass))
wnd_main = create_window(wclassName, wname)
ShowWindow(wnd_main, 5)
UpdateWindow(wnd_main)
msg = MSG()
lpmsg = pointer(msg)
while (GetMessageW(lpmsg, 0, 0, 0)) != 0:
TranslateMessage(lpmsg)
DispatchMessageW(lpmsg)
main()
user32.py
import ctypes
import enum
from ctypes import *
from ctypes.wintypes import *
WNDPROC = ctypes.WINFUNCTYPE(c_int, HWND, c_uint, WPARAM, LPARAM)
LRESULT = c_long
LONG_PTR = LPARAM
CW_USEDEFAULT = 0x80000000
WNDENUMPROC = ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM)
user32 = windll.user32
class WindowStyles(enum.IntFlag):
BORDER = 0x00800000
CAPTION = 0x00C00000
CHILD = 0x40000000
CHILDWINDOW = 0x40000000
CLIPCHILDREN = 0x02000000
CLIPSIBLINGS = 0x04000000
DISABLED = 0x08000000
DLGFRAME = 0x00400000
GROUP = 0x00020000
HSCROLL = 0x00100000
ICONIC = 0x20000000
MAXIMIZE = 0x01000000
MAXIMIZEBOX = 0x00010000
MINIMIZE = 0x20000000
MINIMIZEBOX = 0x00020000
OVERLAPPED = 0x00000000
SYSMENU = 0x00080000
THICKFRAME = 0x00040000
TILED = 0x00000000
VISIBLE = 0x10000000
VSCROLL = 0x00200000
SIZEBOX = 0x00040000
TABSTOP = 0x00010000
POPUP = 0x80000000
TILEDWINDOW = (
OVERLAPPED | CAPTION | SYSMENU | THICKFRAME | MINIMIZEBOX | MAXIMIZEBOX
)
OVERLAPPEDWINDOW = (
OVERLAPPED | CAPTION | SYSMENU | THICKFRAME | MINIMIZEBOX | MAXIMIZEBOX
)
POPUPWINDOW = POPUP | BORDER | SYSMENU
class WindowMessage(enum.IntEnum):
SETFOCUS = 0x0007
KILLFOCUS = 0x0006
ENABLE = 0x000A
SETREDRAW = 0x000B
SETTEXT = 0x000C
SETFONT = 0x0030
GETFONT = 0x0031
GETTEXT = 0x000D
GETTEXTLENGTH = 0x000E
PAINT = 0x000F
CLOSE = 0x00010
QUIT = 0x0012
SHOWWINDOW = 0x0018
NULL = 0x0000
CREATE = 0x0001
DESTROY = 0x0002
MOVE = 0x0003
SIZE = 0x0005
ACTIVATE = 0x0006
COMMAND = 0x0111
NOTIFY = 0x004E
VSCROLL = 0x0115
class ClassStyles(enum.IntFlag):
VREDRAW = 0x0001
HREDRAW = 0x0002
DBLCLKS = 0x0008
OWNDC = 0x0020
CLASSDC = 0x0040
PARENTDC = 0x0080
NOCLOSE = 0x0200
SAVEBITS = 0x0800
BYTEALIGNCLIENT = 0x1000
BYTEALIGNWINDOW = 0x2000
GLOBALCLASS = 0x4000
class ButtonStyle(enum.IntFlag):
PUSHBUTTON = 0x00000000
DEFPUSHBUTTON = 0x00000001
CHECKBOX = 0x00000002
AUTOCHECKBOX = 0x00000003
RADIOBUTTON = 0x00000004
_3STATE = 0x00000005
AUTO3STATE = 0x00000006
GROUPBOX = 0x00000007
USERBUTTON = 0x00000008
AUTORADIOBUTTON = 0x00000009
PUSHBOX = 0x0000000A
OWNERDRAW = 0x0000000B
TYPEMASK = 0x0000000F
LEFTTEXT = 0x00000020
TEXT = 0x00000000
ICON = 0x00000040
BITMAP = 0x00000080
LEFT = 0x00000100
RIGHT = 0x00000200
CENTER = 0x00000300
TOP = 0x00000400
BOTTOM = 0x00000800
VCENTER = 0x00000C00
PUSHLIKE = 0x00001000
MULTILINE = 0x00002000
NOTIFY = 0x00004000
FLAT = 0x00008000
RIGHTBUTTON = LEFTTEXT
class WNDCLASSEXW(Structure):
_fields_ = [
("cbSize", c_uint),
("style", c_uint),
("lpfnWndProc", WNDPROC),
("cbClsExtra", c_int),
("cbWndExtra", c_int),
("hInstance", HANDLE),
("hIcon", HANDLE),
("hCursor", HANDLE),
("hBrush", HANDLE),
("lpszMenuName", LPCWSTR),
("lpszClassName", LPCWSTR),
("hIconSm", HANDLE),
]
class MSG(Structure):
_fields_ = [
("hwnd", HWND),
("message", c_int),
("wParam", WPARAM),
("lParam", LPARAM),
("time", DWORD),
("pt", POINT),
("lPrivate", DWORD),
]
class GetWindowLong(enum.IntEnum):
EXSTYLE = -20
HINSTANCE = -6
HWNDPARENT = -8
ID = -12
STYLE = -16
USERDATA = -21
WNDPROC = -4
class SCROLLINFO(Structure):
_fields_ = [
("cbSize", UINT),
("fMask", UINT),
("nMin", c_int),
("nMax", c_int),
("nPage", UINT),
("nPos", c_int),
("nTrackPos", c_int),
]
class ScrollInfoMessage(enum.IntEnum):
RANGE = 0x0001
PAGE = 0x0002
POS = 0x0004
DISABLENOSCROLL = 0x0008
TRACKPOS = 0x0010
ALL = RANGE | PAGE | POS | TRACKPOS
class ScrollBarConstants(enum.IntEnum):
HORZ = 0
VERT = 1
CTL = 2
BOTH = 3
class ScrollBarCommands(enum.IntEnum):
LINEUP = 0
LINELEFT = 0
LINEDOWN = 1
LINERIGHT = 1
PAGEUP = 2
PAGELEFT = 2
PAGEDOWN = 3
PAGERIGHT = 3
THUMBPOSITION = 4
THUMBTRACK = 5
TOP = 6
LEFT = 6
BOTTOM = 7
RIGHT = 7
ENDSCROLL = 8
def HIWORD(l):
return WORD((l >> 16) & 0xFFFF)
def LOWORD(l):
return WORD(l & 0xFFFF)
LPMSG = POINTER(MSG)
LPCSCROLLINFO = POINTER(SCROLLINFO)
DefWindowProcW = user32.DefWindowProcW
DefWindowProcW.argtypes = [HWND, UINT, WPARAM, LPARAM]
DefWindowProcW.restype = LRESULT
CreateWindowExW = user32.CreateWindowExW
CreateWindowExW.argtypes = [
DWORD,
LPCWSTR,
LPCWSTR,
DWORD,
c_int,
c_int,
c_int,
c_int,
HWND,
HMENU,
HINSTANCE,
LPVOID,
]
CreateWindowExW.restype = HWND
LPWNDCLASSW = POINTER(WNDCLASSEXW)
RegisterClassExW = user32.RegisterClassExW
RegisterClassExW.argtypes = [LPWNDCLASSW]
RegisterClassExW.restype = ATOM
ShowWindow = user32.ShowWindow
ShowWindow.argtypes = [HWND, c_int]
ShowWindow.restype = BOOL
UpdateWindow = user32.UpdateWindow
UpdateWindow.argtypes = [HWND]
UpdateWindow.restype = BOOL
GetMessageW = user32.GetMessageW
GetMessageW.argtypes = [LPMSG, HWND, UINT, UINT]
GetMessageW.restype = BOOL
TranslateMessage = user32.TranslateMessage
TranslateMessage.argtypes = [LPMSG]
TranslateMessage.restype = BOOL
DispatchMessageW = user32.DispatchMessageW
DispatchMessageW.argtypes = [LPMSG]
DispatchMessageW.restype = LRESULT
PostQuitMessage = user32.PostQuitMessage
PostQuitMessage.argtypes = [c_int]
PostQuitMessage.restype = None
GetWindowLongPtrW = user32.GetWindowLongPtrW
GetWindowLongPtrW.argtypes = [HWND, c_int]
GetWindowLongPtrW.restype = LONG_PTR
GetWindow = user32.GetWindow
GetWindow.argtypes = [HWND, UINT]
GetWindow.restype = HWND
ScrollWindowEx = user32.ScrollWindowEx
ScrollWindowEx.argtypes = [HWND, c_int, c_int, LPRECT, LPRECT, HRGN, LPRECT, UINT]
ScrollWindowEx.restype = int
SetScrollInfo = user32.SetScrollInfo
SetScrollInfo.argtypes = [HWND, c_int, LPCSCROLLINFO, BOOL]
SetScrollInfo.restype = int
GetScrollInfo = user32.GetScrollInfo
GetScrollInfo.argtypes = [HWND, c_int, LPCSCROLLINFO]
GetScrollInfo.restype = BOOL
GetClientRect = user32.GetClientRect
GetClientRect.argtypes = [HWND, LPRECT]
GetClientRect.restype = BOOL
BeginDeferWindowPos = user32.BeginDeferWindowPos
BeginDeferWindowPos.argtypes = [c_int]
BeginDeferWindowPos.restype = HDWP
DeferWindowPos = user32.DeferWindowPos
DeferWindowPos.argtypes = [HDWP, HWND, HWND, c_int, c_int, c_int, c_int, c_uint]
DeferWindowPos.restype = HDWP
EndDeferWindowPos = user32.EndDeferWindowPos
EndDeferWindowPos.argtypes = [HDWP]
EndDeferWindowPos.restype = BOOL
button.py
from ctypes.wintypes import HINSTANCE, HMENU, HWND, LPCWSTR, LPVOID
from dataclasses import dataclass
from ctypes import *
from user32 import (
ButtonStyle,
CreateWindowExW,
GetWindowLongPtrW,
WindowStyles,
GetWindowLong,
)
@dataclass
class Button:
btn_text: LPCWSTR
x: c_int
y: c_int
width: c_int
height: c_int
hwnd_parent: HWND
hMenu: HMENU
def create_button(self):
button = CreateWindowExW(
0,
"BUTTON",
self.btn_text,
WindowStyles.TABSTOP
| WindowStyles.VISIBLE
| WindowStyles.CHILD
| ButtonStyle.PUSHBUTTON,
self.x,
self.y,
self.width,
self.height,
self.hwnd_parent,
HMENU(self.hMenu),
cast(
GetWindowLongPtrW(self.hwnd_parent, GetWindowLong.HINSTANCE), HINSTANCE
),
None,
)
return button
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论