在SOUI里,CSimpleWnd处理了整个真窗口消息的的核心。
对比win32。CSimpleWnd也是可以和win32的骤一一对应。对应实现,src\core\CSimpleWnd.cpp
第一步:注册一个窗口类
ATOM CSimpleWnd::RegisterSimpleWnd( HINSTANCE hInst,LPCTSTR pszSimpleWndName )
这个函数注册一个窗口类。
这里有一个非常重要的东西wcex.lpfnWndProc = StartWindowProc; // 第一个处理函数,这里是消息处理的关键点。
第二步:StartWindowProc
LRESULT CALLBACK CSimpleWnd::StartWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
CSimpleWnd* pThis=(CSimpleWnd*)CSimpleWndHelper::GetInstance()->GetSharePtr();
pThis->m_hWnd=hWnd;
// 初始化Thunk,做了两件事:1、mov指令替换hWnd为对象指针,2、jump指令跳转到WindowProc
pThis->m_pThunk->Init((DWORD_PTR)WindowProc, pThis);
// 得到Thunk指针
WNDPROC pProc = (WNDPROC)pThis->m_pThunk->GetCodeAddress();
// 调用下面的语句后,以后消息来了,都由pProc处理
::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)pProc);
return pProc(hWnd, uMsg, wParam, lParam);
}
第三步:WindowProc
由上一步的SetWindowLongPtr之后所有的消息将由WNDPROC pProc = (WNDPROC)pThis->m_pThunk->GetCodeAddress();处理,对应函数为 WindowProc,在这个函数里第一步调用 CSimpleWnd* pThis = (CSimpleWnd*)hWnd; // 强转为对象指针
这里的转换是由 Thunk技术实现了参数替换,从而实现HWND到类指针的转换。如果想深入了解可以以关键字WTL Thunk使用搜索引擎。
第四步:ProcessWindowMessage
调用窗口对应类的ProcessWindowMessage处理消息。
最新SOUI里CSimpleWnd已经更名为 SNativeWnd其原理不变。