如何扩展CAxHostWindow?

ATL用于COM ActiveX托pipe的标准类CAxHostWindow不支持接口IDocHostUIHandler2。 我如何扩展CAxHostWindow类为IDocHostUIHandler2支持?

Solutions Collecting From Web of "如何扩展CAxHostWindow?"

实际上,有一种方法可以自定义CAxHostWindow而不用修改它。 例如,我想要在客户端站点对象上实现IOleCommandTarget 。 棘手的部分是重写创建的主机窗口。 这是如何做到的:

 class ATL_NO_VTABLE CWebBrowserHost : public CAxHostWindow, public IOleCommandTarget { public: static CWndClassInfo& GetWndClassInfo() { static CWndClassInfo wc = { { sizeof(WNDCLASSEX), 0, StartWindowProc, 0, 0, 0, 0, 0, (HBRUSH)(COLOR_WINDOW + 1), 0, NULL, 0 }, NULL, NULL, IDC_ARROW, TRUE, 0, _T("") }; return wc; } DECLARE_PROTECT_FINAL_CONSTRUCT() DECLARE_NO_REGISTRY() DECLARE_POLY_AGGREGATABLE(CWebBrowserHost) DECLARE_GET_CONTROLLING_UNKNOWN() BEGIN_COM_MAP(CWebBrowserHost) COM_INTERFACE_ENTRY(IDocHostUIHandler) COM_INTERFACE_ENTRY(IOleCommandTarget) COM_INTERFACE_ENTRY_CHAIN(CAxHostWindow) END_COM_MAP() HWND Create( _In_opt_ HWND hWndParent, _In_ _U_RECT rect = NULL, _In_opt_z_ LPCTSTR szWindowName = NULL, _In_ DWORD dwStyle = 0, _In_ DWORD dwExStyle = 0, _In_ _U_MENUorID MenuOrID = 0U, _In_opt_ LPVOID lpCreateParam = NULL) { ATOM atom = GetWndClassInfo().Register(&m_pfnSuperWindowProc); if (!atom) return NULL; // Allocate the thunk structure here, where we can fail gracefully. BOOL result = m_thunk.Init(NULL,NULL); if (result == FALSE) { SetLastError(ERROR_OUTOFMEMORY); return NULL; } _AtlWinmodulee.AddCreateWndData(&m_thunk.cd, this); dwStyle = GetWndStyle(dwStyle); dwExStyle = GetWndExStyle(dwExStyle); // set caption if (szWindowName == NULL) szWindowName = GetWndCaption(); return CWindow::Create((LPCTSTR)atom, hWndParent, rect, szWindowName, dwStyle, dwExStyle, MenuOrID, lpCreateParam); } // IOleCommandTarget methods // ... } 

以下是如何使用它:

 CComPtr<CWebBrowserHost> m_webBrowserHost; //... // Create a child AX host window. CComObject<CWebBrowserHost>* pHost = NULL; hr = CComObject<CWebBrowserHost>::CreateInstance(&pHost); if (FAILED(hr)) return 0; m_webBrowserHost = pHost; RECT rect; GetClientRect(&rect); m_webBrowserHost->Create(m_hWnd, rect, NULL, WS_CHILD | WS_VISIBLE); if (m_webBrowserHost->m_hWnd == NULL) return 0; // Create WebBrowser control CComPtr<IUnknown> spControl; hr = pHost->CreateControlEx( OLESTR("{8856F961-340A-11D0-A96B-00C04FD705A2}"), // WebBrowser Control CLSID m_webBrowserHost->m_hWnd, NULL, &spControl, DIID_DWebBrowserEvents2, ((IUnknown*)(IDispEventImpl<1, CMainWindow, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 0xFFFF, 0xFFFF>*)this) ); if (FAILED(hr)) return 0; 

CAxHostWindow类在源代码中可用。 所以你可以:

  1. 编辑或复制类,并在那里添加接口
  2. 您可以通过COM聚合将类聚合到您自己的,这增加了对IDocHostUIHandler2支持 – 在这种情况下,您不需要源代码编辑,但源代码仍然是一个很好的指导, 或者你甚至可以从它继承。

#2解决方案更清洁,而不是触及ATL代码本身,但是你也必须解决实例化问题。 这个类不是COM可创建的,它是通过ATL创建者类创建的。 您还必须考虑到这一点,例如通过为AtlAxAttachControl函数提供备用选项。