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