َA Curiosity question on ATL CWindowImpl class

drjackool 956 Reputation points
2023-07-15T16:32:27.72+00:00

Hi

This code is part of "atlwin.h" file for CWindowImplBaseT class. My question is in WindowProc static member How convert window handle to the corresponding window class object? how this possible? Because to converting we need a table with two column one for Window Handles and one for Object pointers then search it by handle to find corresponding object pointer. But in this code directly convert window handle to object (first line body code)!!!

CWindowImplBaseT< TBase, TWinTraits > pThis = (CWindowImplBaseT< TBase, TWinTraits >)hWnd;**

Thanks

template <class TBase, class TWinTraits>
LRESULT CALLBACK CWindowImplBaseT< TBase, TWinTraits >::WindowProc(
	_In_ HWND hWnd,
	_In_ UINT uMsg,
	_In_ WPARAM wParam,
	_In_ LPARAM lParam)
{
	CWindowImplBaseT< TBase, TWinTraits >* pThis = (CWindowImplBaseT< TBase, TWinTraits >*)hWnd;
	// set a ptr to this message and save the old value
	_ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
	const _ATL_MSG* pOldMsg = pThis->m_pCurrentMsg;
	pThis->m_pCurrentMsg = &msg;
	// pass to the message map to process
	LRESULT lRes = 0;
	BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
	// restore saved value for the current message
	ATLASSERT(pThis->m_pCurrentMsg == &msg);

	// do the default processing if message was not handled
	if(!bRet)
	{
		if(uMsg != WM_NCDESTROY)
			lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
		else
		{
			// unsubclass, if needed
			LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC);
			lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
			if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc)
				::SetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
			// mark window as destroyed
			pThis->m_dwState |= CWindowImplRoot<TBase>::WINSTATE_DESTROYED;
		}
	}
	if((pThis->m_dwState & CWindowImplRoot<TBase>::WINSTATE_DESTROYED) && pOldMsg== NULL)
	{
		// clear out window handle
		HWND hWndThis = pThis->m_hWnd;
		pThis->m_hWnd = NULL;
		pThis->m_dwState &= ~CWindowImplRoot<TBase>::WINSTATE_DESTROYED;
		// clean up after window is destroyed
		pThis->m_pCurrentMsg = pOldMsg;
		pThis->OnFinalMessage(hWndThis);
	}else {
		pThis->m_pCurrentMsg = pOldMsg;
	}
	return lRes;
}

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,728 questions
0 comments No comments
{count} votes

Accepted answer
  1. Viorel 119.6K Reputation points
    2023-07-15T20:33:17.4166667+00:00

    A static function like WindowProc(HWND, MSG, WPARAM, LPARAM) is suitable for processing the messages that are remitted to a window or control.

    In my opinion, to associate an existing ATL C++ object with this messaging, it was decided to create intermediate short functions (having the same signature) at run-time, which receive the calls from Windows, and then redirect these calls to ATL functions, adding the missing ATL object. These things are called “thunks”.

    For unknown reasons, it was chosen to pass the ATL objects via the HWND parameter. (The duplicate value of HWND is available in the m_hWnd member of the object, therefore it is not lost). See the ‘struct _stdcallthunk’ in ATL files for specific instructions generated for different microprocessors. One of the document (https://learn.microsoft.com/en-us/windows/win32/api/atlthunk/nf-atlthunk-atlthunk_initdata) mentions that “An ATL thunk has a signature of WNDPROC”.

    Therefore, the Windows calls the thunk, which then call the ATL function, replacing the first parameter with an object. Then the target function reinterprets the first parameter as an object.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.