okay ... that's too elaborate, all the functions to create and manipulate applications on windows are written in C and are stored in win32 api dlls on windows for example this is how you do it in C as stated in win32 docs
this program needs to be translated to python through ctypes, which will be calling C code from within python, you will be writing C code in python which is almost 4 times the code you would've written in C, and it will work 100 times slower and you have to have very good experience in C and python and win32 api to get a useful application working .... that can be advanced for a lot of senior developers out there.
so the track is:
learn C -> learn win32 api -> learn python -> learn ctypes -> learn python-C ABI -> make a simple hello world program
it's much easier (and faster) to write your code entirely in C then wrap it into a python module as done in tkinter and wxwidgets and QT and almost every other framework out there.
this is a gist of how it would be done in 32 bit python , but it won't work on 64 bit python because the types of variables have changed between 32 and 64 bit windows dlls.
https://gist.github.com/mouseroot/6128651
this is another gist on 64 bit systems, which fixes the types problem.
https://gist.github.com/syegulalp/7cf217677e893881a18d10020f2966e4
# Adapted for Python 3.6 + 64-bit Windows
from ctypes import *
from ctypes.wintypes import *
WNDPROCTYPE = WINFUNCTYPE(c_int, HWND, c_uint, WPARAM, LPARAM)
WS_EX_APPWINDOW = 0x40000
WS_OVERLAPPEDWINDOW = 0xcf0000
WS_CAPTION = 0xc00000
SW_SHOWNORMAL = 1
SW_SHOW = 5
CS_HREDRAW = 2
CS_VREDRAW = 1
CW_USEDEFAULT = 0x80000000
WM_DESTROY = 2
WHITE_BRUSH = 0
class WNDCLASSEX(Structure):
_fields_ = [("cbSize", c_uint),
("style", c_uint),
("lpfnWndProc", WNDPROCTYPE),
("cbClsExtra", c_int),
("cbWndExtra", c_int),
("hInstance", HANDLE),
("hIcon", HANDLE),
("hCursor", HANDLE),
("hBrush", HANDLE),
("lpszMenuName", LPCWSTR),
("lpszClassName", LPCWSTR),
("hIconSm", HANDLE)]
user32 = ctypes.WinDLL('user32', use_last_error=True)
user32.DefWindowProcW.argtypes = [HWND, c_uint, WPARAM, LPARAM]
def PyWndProcedure(hWnd, Msg, wParam, lParam):
if Msg == WM_DESTROY:
user32.PostQuitMessage(0)
return 0
return user32.DefWindowProcW(hWnd, Msg, wParam, lParam)
def main():
WndProc = WNDPROCTYPE(PyWndProcedure)
hInst = windll.kernel32.GetModuleHandleW(0)
wclassName = u'My Python Win32 Class'
wname = u'My test window'
wndClass = WNDCLASSEX()
wndClass.cbSize = sizeof(WNDCLASSEX)
wndClass.style = CS_HREDRAW | CS_VREDRAW
wndClass.lpfnWndProc = WndProc
wndClass.cbClsExtra = 0
wndClass.cbWndExtra = 0
wndClass.hInstance = hInst
wndClass.hIcon = 0
wndClass.hCursor = 0
wndClass.hBrush = windll.gdi32.GetStockObject(WHITE_BRUSH)
wndClass.lpszMenuName = 0
wndClass.lpszClassName = wclassName
wndClass.hIconSm = 0
regRes = windll.user32.RegisterClassExW(byref(wndClass))
hWnd = windll.user32.CreateWindowExW(
0, wclassName, wname,
WS_OVERLAPPEDWINDOW | WS_CAPTION,
CW_USEDEFAULT, CW_USEDEFAULT,
300, 300, 0, 0, hInst, 0)
if not hWnd:
print('Failed to create window')
exit(0)
print('ShowWindow', windll.user32.ShowWindow(hWnd, SW_SHOW))
print('UpdateWindow', windll.user32.UpdateWindow(hWnd))
msg = MSG()
lpmsg = pointer(msg)
print('Entering message loop')
while windll.user32.GetMessageA(lpmsg, 0, 0, 0) != 0:
windll.user32.TranslateMessage(lpmsg)
windll.user32.DispatchMessageA(lpmsg)
print('done.')
if __name__ == "__main__":
print("Win32 Application in python")
main()
after all this mess with your code being too messy and slow, your code will work only on your operating system, so you will still have to suffer 10 times the headache to port it to another operating system, so using a library to handle this stuff is preferred.