Hi,
I have an application that handles several text edit controls.
At one point it flips from the first to the second (after you have entered the fourth character).
This is done by a function, which does (simplified) this:
{ DWORD startsel,endsel;
PostMessageA(hwnd1,EM_GETSEL,&startsel,&endsel); SetFocus(hwnd2); PostMessageA(hwnd2,EM_SETSEL,0,0); /* ... */ CallWindowProcA(hwnd,....); return; }
According to the +relay,+edit trace the EM_GETSEL is executed way _AFTER_ the return from the function, so, since it uses stackvalues, it then smashes the stack somewhere else.
My suspicion is that SetFocus() in Windows drains all posted messages by doing something like: while (PeekMessage()) { TranslateMessage(); DispatchMessage(); } but I do not really know.
Does anybody have more knowledge of this?
The respective trace is here, starting with the posting of the message with the pointers into the stack:
Ciao, Marcus
Call user32.455: PostMessageA(000006b4,000000b0,40599904,40599908) ret=0041a99b fs=008f Ret user32.455: PostMessageA() retval=00000001 ret=0041a99b fs=008f Call user32.254: GetDlgItem(000002bc,000007d7) ret=0041a9ab fs=008f Ret user32.254: GetDlgItem() retval=0000074c ret=0041a9ab fs=008f Call user32.527: SetFocus(0000074c) ret=0041a9b2 fs=008f trace:relay:WINPROC_CallWndProc (wndproc=0x41a73f,hwnd=000006b4,msg=WM_KILLFOCU S,wp=0000074c,lp=00000000) Call user32.254: GetDlgItem(000002bc,000007da) ret=0041aa40 fs=008f Ret user32.254: GetDlgItem() retval=000004e4 ret=0041aa40 fs=008f Call user32.254: GetDlgItem(000002bc,000007d6) ret=0041aa5e fs=008f Ret user32.254: GetDlgItem() retval=000006b4 ret=0041aa5e fs=008f Call user32.21: CallWindowProcA(41060311,000006b4,00000008,0000074c,00000000) r et=0041aa26 fs=008f trace:relay:WINPROC_CallWndProc (wndproc=0x406dcf00,hwnd=000006b4,msg=WM_KILLFO CUS,wp=0000074c,lp=00000000) trace:relay:WINPROC_CallWndProc (wndproc=0x40702990,hwnd=000002bc,msg=WM_COMMAN D,wp=020007d6,lp=000006b4) trace:relay:WINPROC_CallWndProc (wndproc=0x41ae53,hwnd=000002bc,msg=WM_COMMAND, wp=020007d6,lp=000006b4) trace:relay:WINPROC_CallWndProc (wndproc=0x41ae53,hwnd=000002bc,msg=WM_COMMAND, wp=020007d6,lp=000006b4) retval=00000000 trace:relay:WINPROC_CallWndProc (wndproc=0x40702990,hwnd=000002bc,msg=WM_COMMAN D,wp=020007d6,lp=000006b4) retval=00000000 trace:relay:WINPROC_CallWndProc (wndproc=0x406dcf00,hwnd=000006b4,msg=WM_KILLFO CUS,wp=0000074c,lp=00000000) retval=00000000 Ret user32.21: CallWindowProcA() retval=00000000 ret=0041aa26 fs=008f trace:relay:WINPROC_CallWndProc (wndproc=0x41a73f,hwnd=000006b4,msg=WM_KILLFOCU S,wp=0000074c,lp=00000000) retval=00000000 trace:relay:WINPROC_CallWndProc (wndproc=0x41a73f,hwnd=0000074c,msg=WM_SETFOCUS ,wp=000006b4,lp=00000000) Call user32.254: GetDlgItem(000002bc,000007da) ret=0041aa40 fs=008f Ret user32.254: GetDlgItem() retval=000004e4 ret=0041aa40 fs=008f Call user32.254: GetDlgItem(000002bc,000007d6) ret=0041aa5e fs=008f Ret user32.254: GetDlgItem() retval=000006b4 ret=0041aa5e fs=008f Call user32.254: GetDlgItem(000002bc,000007d7) ret=0041aa7c fs=008f Ret user32.254: GetDlgItem() retval=0000074c ret=0041aa7c fs=008f Call user32.21: CallWindowProcA(41060311,0000074c,00000007,000006b4,00000000) r et=0041aa26 fs=008f trace:relay:WINPROC_CallWndProc (wndproc=0x406dcf00,hwnd=0000074c,msg=WM_SETFOC US,wp=000006b4,lp=00000000) trace:relay:WINPROC_CallWndProc (wndproc=0x40702990,hwnd=000002bc,msg=WM_COMMAN D,wp=010007d7,lp=0000074c) trace:relay:WINPROC_CallWndProc (wndproc=0x41ae53,hwnd=000002bc,msg=WM_COMMAND, wp=010007d7,lp=0000074c) trace:relay:WINPROC_CallWndProc (wndproc=0x41ae53,hwnd=000002bc,msg=WM_COMMAND, wp=010007d7,lp=0000074c) retval=00000000 trace:relay:WINPROC_CallWndProc (wndproc=0x40702990,hwnd=000002bc,msg=WM_COMMAN D,wp=010007d7,lp=0000074c) retval=00000000 trace:relay:WINPROC_CallWndProc (wndproc=0x406dcf00,hwnd=0000074c,msg=WM_SETFOC US,wp=000006b4,lp=00000000) retval=00000000 Ret user32.21: CallWindowProcA() retval=00000000 ret=0041aa26 fs=008f trace:relay:WINPROC_CallWndProc (wndproc=0x41a73f,hwnd=0000074c,msg=WM_SETFOCUS ,wp=000006b4,lp=00000000) retval=00000000 Ret user32.527: SetFocus() retval=000006b4 ret=0041a9b2 fs=008f Call user32.254: GetDlgItem(000002bc,000007d7) ret=0041a9cc fs=008f Ret user32.254: GetDlgItem() retval=0000074c ret=0041a9cc fs=008f Call user32.455: PostMessageA(0000074c,000000b1,00000000,00000000) ret=0041a9d3 fs=008f Ret user32.455: PostMessageA() retval=00000001 ret=0041a9d3 fs=008f
Call user32.254: GetDlgItem(000002bc,000007da) ret=0041aa40 fs=008f Ret user32.254: GetDlgItem() retval=000004e4 ret=0041aa40 fs=008f Call user32.254: GetDlgItem(000002bc,000007d6) ret=0041aa5e fs=008f Ret user32.254: GetDlgItem() retval=000006b4 ret=0041aa5e fs=008f Call user32.21: CallWindowProcA(41060311,000006b4,00000102,00000048,00230001) r et=0041aa26 fs=008f trace:relay:WINPROC_CallWndProc (wndproc=0x406dcf00,hwnd=000006b4,msg=WM_CHAR,w p=00000048,lp=00230001) trace:relay:WINPROC_CallWndProc (wndproc=0x40702990,hwnd=000002bc,msg=WM_COMMAN D,wp=040007d6,lp=000006b4) trace:relay:WINPROC_CallWndProc (wndproc=0x41ae53,hwnd=000002bc,msg=WM_COMMAND, wp=040007d6,lp=000006b4) trace:relay:WINPROC_CallWndProc (wndproc=0x41ae53,hwnd=000002bc,msg=WM_COMMAND, wp=040007d6,lp=000006b4) retval=00000000 trace:relay:WINPROC_CallWndProc (wndproc=0x40702990,hwnd=000002bc,msg=WM_COMMAN D,wp=040007d6,lp=000006b4) retval=00000000 trace:relay:WINPROC_CallWndProc (wndproc=0x40702990,hwnd=000002bc,msg=WM_COMMAN D,wp=030007d6,lp=000006b4) trace:relay:WINPROC_CallWndProc (wndproc=0x41ae53,hwnd=000002bc,msg=WM_COMMAND, wp=030007d6,lp=000006b4) trace:relay:WINPROC_CallWndProc (wndproc=0x41ae53,hwnd=000002bc,msg=WM_COMMAND, wp=030007d6,lp=000006b4) retval=00000000 trace:relay:WINPROC_CallWndProc (wndproc=0x40702990,hwnd=000002bc,msg=WM_COMMAN D,wp=030007d6,lp=000006b4) retval=00000000 trace:relay:WINPROC_CallWndProc (wndproc=0x406dcf00,hwnd=000006b4,msg=WM_CHAR,w p=00000048,lp=00230001) retval=00000000 Ret user32.21: CallWindowProcA() retval=00000000 ret=0041aa26 fs=008f trace:relay:WINPROC_CallWndProc (wndproc=0x41a73f,hwnd=000006b4,msg=WM_CHAR,wp= 00000068,lp=00230001) retval=00000000
After this it directly returns from the function.
trace:relay:WINPROC_CallWndProc (wndproc=0x41a73f,hwnd=000006b4,msg=EM_GETSEL32 ,wp=40599904,lp=40599908) Call user32.254: GetDlgItem(000002bc,000007da) ret=0041aa40 fs=008f Ret user32.254: GetDlgItem() retval=000004e4 ret=0041aa40 fs=008f Call user32.254: GetDlgItem(000002bc,000007d6) ret=0041aa5e fs=008f Ret user32.254: GetDlgItem() retval=000006b4 ret=0041aa5e fs=008f Call user32.21: CallWindowProcA(41060311,000006b4,000000b0,40599904,40599908) r et=0041aa26 fs=008f trace:relay:WINPROC_CallWndProc (wndproc=0x406dcf00,hwnd=000006b4,msg=EM_GETSEL 32,wp=40599904,lp=40599908) trace:relay:WINPROC_CallWndProc (wndproc=0x406dcf00,hwnd=000006b4,msg=EM_GETSEL 32,wp=40599904,lp=40599908) retval=00040004 Ret user32.21: CallWindowProcA() retval=00040004 ret=00000004 fs=008f
... but still uses its stack values here.
faulted at EIP=0x00000004, CR2=0x00000004, EAX 0x00040004 EBX 0x407936fc, ECX 0x00000001, EBP 0x40599950 EDI 0x40599904, ESP 0x002b:0x40599908 FS 0x008f, pid 1772
On Mon, 5 Feb 2001, Marcus Meissner wrote:
PostMessageA(hwnd1,EM_GETSEL,&startsel,&endsel);
Eek.
My suspicion is that SetFocus() in Windows drains all posted messages by doing something like: while (PeekMessage()) { TranslateMessage(); DispatchMessage(); } but I do not really know.
From something (admittedly tangential/irrelevant to this problem) I
remember Ulrich have been talking about (http://www.winehq.com/News/1999-48.html#2, last paragraph), there's also the possibility that Windows recognizes that it's a message known to contain pointers, and so just drops the message, so that EM_GETSEL is simply never dispatched?
Or maybe the edit control uses IsBadWritePtr or exception handlers (though that would be even worse, race conditions...).
At least message loops in SetFocus really doesn't seem right.
Ove Kaaven wrote:
From something (admittedly tangential/irrelevant to this problem) I remember Ulrich have been talking about (http://www.winehq.com/News/1999-48.html#2, last paragraph), there's also the possibility that Windows recognizes that it's a message known to contain pointers, and so just drops the message, so that EM_GETSEL is simply never dispatched?
Yes. EM_GETSEL is classified as 'pointer message', and the 32-bit PostMessage in Win9x simply drops it. (The 16-bit PostMessage doesn't appear to care, but if a 16-bit message with pointers is about to be *received* by a 32-bit app, the Get/PeekMessage call drops the message ...)
You get DebugOutput messages like "PostMessage: ignoring posted message with pointer" or "GetMessage: ignoring retrieved message with pointer" when this happens.
Bye, Ulrich