首先回顾一下CWindow中的窗口过程:
#define DECLARE_WND_CLASS(WndClassName) /
static ATL::CWndClassInfo& GetWndClassInfo() /
{ /
static ATL::CWndClassInfo wc = /
{ /
{ sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, StartWindowProc, /
0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndClassName, NULL }, /
NULL, NULL, IDC_ARROW, TRUE, 0, _T("") /
}; /
return wc; /
}
指定了窗口过程StartWindowProc.
然后通过pThis->m_thunk.Init(WindowProc, pThis); thunk机制调换了
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)中
的HWND为CContainedWindowT< TBase >* pThis = (CContainedWindowT< TBase >*)hWnd;
接下来就利用多态调用
BOOL bRet = pThis->m_pObject->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, pThis->m_dwMsgMapID);
该函数是通过宏定义
#define BEGIN_MSG_MAP(theClass) /
public: /
BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) /
{ /
BOOL bHandled = TRUE; /
(hWnd); /
(uMsg); /
(wParam); /
(lParam); /
(lResult); /
(bHandled); /
switch(dwMsgMapID) /
{ /
case 0:
若这个函数返回FALSE,则跳转到DefWindowProc
if(uMsg != WM_NCDESTROY)
lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
以上就是关于CWindow中的窗口过程调用。
接下来看一下CAxHostWindow对象是如何被创建的。在CMainWindow中:
CAxWindow m_bullseyeWin;
m_bullseyeWin.Create( m_hWnd, rect, controlName, WS_CHILD | WS_VISIBLE, 0, ID_BULLSEYE );
其中就指定了CLASSNAME GetWndClassName() = ATLAXWIN_CLASS,该宏正是"AtlAxWin80"
该窗口类在AtlAxWinInit()注册的时候,使用的是wc.lpfnWndProc = AtlAxWindowProc;
来看一下window procedure AtlAxWindowProc:
在其中调用了HRESULT hRet = AtlAxCreateControlLic(T2COLE_EX_DEF(spName), hWnd, spStream, &spUnk, NULL);
将spName传递进去,并最终调用了AtlAcCreateControlLicEx(atlHost.h LN1980)
hr = CAxHostWindow::_CreatorClass::CreateInstance(NULL, __uuidof(IUnknown), (void**)&spUnkContainer);
if (SUCCEEDED(hr))
{
CComPtr
pAxWindow;
spUnkContainer->QueryInterface(__uuidof(IAxWinHostWindow), (void**)&pAxWindow);
CComBSTR bstrName(lpszName);
hr = pAxWindow->CreateControlLicEx(bstrName, hWnd, pStream, &spUnkControl, iidSink, punkSink, bstrLic);
}
interface IAxWinHostWindow : IUnknown {
HRESULT CreateControl([in] LPCOLESTR lpTricsData, [in] HWND hWnd, [in] IStream* pStream);
HRESULT CreateControlEx([in] LPCOLESTR lpTricsData, [in] HWND hWnd, [in] IStream* pStream, [out] IUnknown** ppUnk, [in] REFIID riidAdvise, [in] IUnknown* punkAdvise);
HRESULT AttachControl([in] IUnknown* pUnkControl, [in] HWND hWnd);
HRESULT QueryControl([in] REFIID riid, [out, iid_is(riid)] void **ppvObject);
HRESULT SetExternalDispatch([in] IDispatch* pDisp); HRESULT SetExternalUIHandler( [in] IDocHostUIHandlerDispatch* pDisp); };
// TODO 复习SubclassWindow,即子类化