It's well know that ATL hooks a window to it's wndproc by thunking, which actually replace hwnd with this pointer in place and and jumps to the wndproc so that a call to wndproc(hwnd, ...) is actually wndproc(this, ...) .
Below is the assembly code the thunk constructs:
mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
My question is, since this thunk only executes once, how can we be sure that [esp+0x4] will not be overwritten by CPU for calling another procedure, and next time wndproc(...) is called, hwnd is passed in again? My understanding is that [esp+0x4] is a reusable general-purpose register for storing a first parameter of any procedure.
What am wrong here? how the modification of hwnd is guaranteed to be perpetual?
Thanks.
I was wrong about the
this thunk only executes once
part, it actually runs each time a message arrives.
this is because the thunk itself , not CWindowImplBaseT<>::WindowProc()
, is set to be the wndproc of the window class by the following lines CWindowImplBaseT<>::StartWindowProc
in :
WNDPROC pProc = (WNDPROC)&(pThis->m_thunk.thunk);
::SetWindowLong(hWnd, GWL_WNDPROC, (LONG)pProc);