After a window class is registerered with win32gui.RegisterClass and new window of that class is created with win32gui.CreateWindow, the window's wndproc (the dictionary specified as lpfnWndProc in the WNDCLASS object) does not receive the WM_CREATE message. If additional windows of the class are created, subsequent windows do receive WM_CREATE.
This is demonstrated (inadvertently) by the demo win32clipboard_bitmapdemo.py, which has a typo in its WM_CREATE handler but doesn't raise an exception because the handler never gets executed. The program maps WM_CREATE to its OnCreate method:
def go(self):
wndproc = {
...
win32con.WM_CREATE: self.OnCreate,
...
which is defined like this:
def OnCreate(self, hwnd, msg, wp, lp):
self.hwndNextViewer = win32gui.SetClipboardViewer(hwnd)
but SetClipboardViewer is in the win32clipboard module, not in win32gui, so OnCreate would raise an AttributeError if it were ever executed, which would print the message "Python WNDPROC handler failed" and a traceback. But because the delivery of WM_CREATE doesn't work, OnCreate never gets called, so the broken code never runs (i.e. the bug in the demo is masked by the bug in the window creation code).
If the demo program is modified to call CreateWindowEx a second time, OnCreate will be called and a traceback of the AttributeError will be printed.
The problem with WM_CREATE might have something to do with the code in win32gui that has a comment about being "A HUGE HACK". It also says something about "post-process", so perhaps it sets the wndproc too late in the window creation process? As Raymond Chen explains, WM_CREATE is sent before CreateWindow returns.
Steps to reproduce the problem
- Run pywin32's
win32clipboard_bitmapdemo.py.
Expected behavior
The program should execute the OnCreate method during the CreateWindowEx call, which will raise an AttributeError and result in a traceback being printed.
Actual behavior
The program does not execute OnCreate and does not print a traceback.
System information
Tested on:
- pywin32 build 227, Python 3.6.8 (32-bit)
- pywin32 build 311, Python 3.11.9 (64-bit)
Windows Version:
10.0.26100.1
DLL locations:
All inside the respective venvs.
After a window class is registerered with
win32gui.RegisterClassand new window of that class is created withwin32gui.CreateWindow, the window's wndproc (the dictionary specified aslpfnWndProcin theWNDCLASSobject) does not receive theWM_CREATEmessage. If additional windows of the class are created, subsequent windows do receiveWM_CREATE.This is demonstrated (inadvertently) by the demo win32clipboard_bitmapdemo.py, which has a typo in its
WM_CREATEhandler but doesn't raise an exception because the handler never gets executed. The program mapsWM_CREATEto itsOnCreatemethod:which is defined like this:
but
SetClipboardVieweris in thewin32clipboardmodule, not inwin32gui, soOnCreatewould raise anAttributeErrorif it were ever executed, which would print the message "Python WNDPROC handler failed" and a traceback. But because the delivery ofWM_CREATEdoesn't work,OnCreatenever gets called, so the broken code never runs (i.e. the bug in the demo is masked by the bug in the window creation code).If the demo program is modified to call
CreateWindowExa second time,OnCreatewill be called and a traceback of theAttributeErrorwill be printed.The problem with
WM_CREATEmight have something to do with the code in win32gui that has a comment about being "A HUGE HACK". It also says something about "post-process", so perhaps it sets the wndproc too late in the window creation process? As Raymond Chen explains,WM_CREATEis sent beforeCreateWindowreturns.Steps to reproduce the problem
win32clipboard_bitmapdemo.py.Expected behavior
The program should execute the
OnCreatemethod during theCreateWindowExcall, which will raise anAttributeErrorand result in a traceback being printed.Actual behavior
The program does not execute
OnCreateand does not print a traceback.System information
Tested on:
Windows Version:
10.0.26100.1
DLL locations:
All inside the respective venvs.