I'm really puzzled over this. I have a CRichEditCtrl derived class that is also subclassed in my CDialog as a child control. (The window class for the Win32 rich-edit
window itself is a newer RICHEDIT50W
.)
I'm trying to investigate messages that are broadcast at the moment when the cursor is right at the bottom of the window right before the user hits ENTER to have that control show the vertical scrollbar:
When I check the messages for that window using Spy++, it shows that I'm getting a sequence of WS_STYLECHANGING
/WS_STYLECHANGED
messages. But when I try to trap them in my subclassed WndProc, nothing happens.
So I decided to set up a test (in Debug
build.) Here's my modified WndProc for the subclass, with two breakpoints on br0
and br1
:
LRESULT CMyRichEdit::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
LRESULT lRes;
static BOOL bDoLogging = 0;
if(message == WM_NCCALCSIZE)
{
int br0 = 0; //Breakpoint here
}
if(bDoLogging)
{
TRACE(L"msg=0x%X\n", message);
}
if(message == WM_STYLECHANGED) //0x007D
{
int br1 = 0; //Breakpoint here
}
//Then its regular processing
// ....
return CRichEditCtrl::WindowProc(message, wParam, lParam);
}
So I set up Spy++ to monitor messages for my window and then get to the point in the control itself when its vertical scrollbar is about to be shown (screenshot above) and then hit Enter
. At that point br0
is hit for WM_NCCALCSIZE
message. I then manually set bDoLogging
to 1, remove all breakpoints, and let it run.
Here's the output from Spy++:
And this is the copy of my log:
atlTraceGeneral - msg=0x83 WM_NCCALCSIZE
atlTraceGeneral - msg=0x47 WM_WINDOWPOSCHANGED
atlTraceGeneral - msg=0x5 WM_SIZE
atlTraceGeneral - msg=0xF WM_PAINT
atlTraceGeneral - msg=0x85 WM_NCPAINT
atlTraceGeneral - msg=0x14 WM_ERASEBKGND
atlTraceGeneral - msg=0xF WM_PAINT <<-- missing after this one
atlTraceGeneral - msg=0x87 WM_GETDLGCODE
atlTraceGeneral - msg=0x102 WM_CHAR
atlTraceGeneral - msg=0x87 WM_GETDLGCODE
atlTraceGeneral - msg=0x8 WM_KILLFOCUS
atlTraceGeneral - msg=0x281 WM_IME_SETCONTEXT
atlTraceGeneral - msg=0x282 WM_IME_NOTIFY
See that WS_STYLECHANGING
/WS_STYLECHANGED
messages are missing in my log. The following is their properties from Spy++:
000619 -- WS_STYLECHANGING:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | 00D4
000621 -- WS_STYLECHANGED:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | 00D4
000623 -- WS_STYLECHANGING:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
000625 -- WS_STYLECHANGED:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
000627 -- WS_STYLECHANGING:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
000629 -- WS_STYLECHANGED:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
Additionally, the next time I run the app, I do the same, but now set a specific breakpoint on the root MFC window-procedure AfxWndProc
:
as a condition:
to see if maybe WS_STYLECHANGED
message gets eaten up somewhere in MFC before my subclass receives it. And although that breakpoint hits a couple of times when the app starts up, it never gets hit when the Spy++ is showing it to be.
So what gives: Is it MFC? My code? or a bug in Spy++?
PS. I'm using Spy++ x64 version 15.00.27729
i check - the control really not got WM_STYLECHANGING
and WM_STYLECHANGED
. but when i set SetWindowsHookExW(WH_CALLWNDPROC, ..)
on self thread - i view WM_STYLECHANGING
and WM_STYLECHANGED
here. Spy++ also use WH_CALLWNDPROC
- because this it and log this messages. so why control window procedure not receiver it ? i look under debugger - the window procedure is called from UserCallWinProcCheckWow
, but for some windows messages - the ThemePreWndProc
called first and if it return true - original window procedure not called for this message. so in case WM_STYLECHANGING
and WM_STYLECHANGED
it was "swallowed" by ThemePreWndProc
.
so this not bug in your code or MFC, not bug in Spy++. simply window "feature"