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