Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

453 lines
18 KiB

  1. #ifndef __AXHOST_H
  2. #define __AXHOST_H
  3. ////////////////////////////////////////////////////////////////////////////////
  4. #define FORWARD_IDOCHOSTUIHANDLER_INIT \
  5. HRESULT hr; \
  6. CComPtr<IDocHostUIHandler> spHost; \
  7. \
  8. hr = AskHostForDocHostUIHandler( spHost );
  9. #define FORWARD_IDOCHOSTUIHANDLER( method ) \
  10. FORWARD_IDOCHOSTUIHANDLER_INIT; \
  11. if(SUCCEEDED(hr)) \
  12. { \
  13. hr = spHost->method(); if(hr != E_NOTIMPL) return hr; \
  14. } \
  15. return CAxHostWindow::method();
  16. #define FORWARD_IDOCHOSTUIHANDLER_1( method, arg1 ) \
  17. FORWARD_IDOCHOSTUIHANDLER_INIT; \
  18. if(SUCCEEDED(hr)) \
  19. { \
  20. hr = spHost->method( arg1 ); if(hr != E_NOTIMPL) return hr; \
  21. } \
  22. return CAxHostWindow::method( arg1 );
  23. #define FORWARD_IDOCHOSTUIHANDLER_2( method, arg1, arg2 ) \
  24. FORWARD_IDOCHOSTUIHANDLER_INIT; \
  25. if(SUCCEEDED(hr)) \
  26. { \
  27. hr = spHost->method( arg1, arg2 ); if(hr != E_NOTIMPL) return hr; \
  28. } \
  29. return CAxHostWindow::method( arg1, arg2 );
  30. #define FORWARD_IDOCHOSTUIHANDLER_3( method, arg1, arg2, arg3 ) \
  31. FORWARD_IDOCHOSTUIHANDLER_INIT; \
  32. if(SUCCEEDED(hr)) \
  33. { \
  34. hr = spHost->method( arg1, arg2, arg3 ); if(hr != E_NOTIMPL) return hr; \
  35. } \
  36. return CAxHostWindow::method( arg1, arg2, arg3 );
  37. #define FORWARD_IDOCHOSTUIHANDLER_4( method, arg1, arg2, arg3, arg4 ) \
  38. FORWARD_IDOCHOSTUIHANDLER_INIT; \
  39. if(SUCCEEDED(hr)) \
  40. { \
  41. hr = spHost->method( arg1, arg2, arg3, arg4 ); if(hr != E_NOTIMPL) return hr; \
  42. } \
  43. return CAxHostWindow::method( arg1, arg2, arg3, arg4 );
  44. #define FORWARD_IDOCHOSTUIHANDLER_5( method, arg1, arg2, arg3, arg4, arg5 ) \
  45. FORWARD_IDOCHOSTUIHANDLER_INIT; \
  46. if(SUCCEEDED(hr)) \
  47. { \
  48. hr = spHost->method( arg1, arg2, arg3, arg4, arg5 ); if(hr != E_NOTIMPL) return hr; \
  49. } \
  50. return CAxHostWindow::method( arg1, arg2, arg3, arg4, arg5 );
  51. ////////////////////////////////////////////////////////////////////////////////
  52. ATLAPI MarsAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd, IStream* pStream,
  53. IUnknown** ppUnkContainer, IUnknown** ppUnkControl, REFIID iidSink, IUnknown* punkSink);
  54. ATLAPI MarsAxCreateControl(LPCOLESTR lpszName, HWND hWnd, IStream* pStream, IUnknown** ppUnkContainer);
  55. class CMarsPanel;
  56. class CMarsAxHostWindow :
  57. public CAxHostWindow,
  58. public IOleCommandTarget
  59. {
  60. public:
  61. ~CMarsAxHostWindow();
  62. BEGIN_COM_MAP(CMarsAxHostWindow)
  63. COM_INTERFACE_ENTRY(IOleCommandTarget)
  64. COM_INTERFACE_ENTRY_CHAIN(CAxHostWindow)
  65. END_COM_MAP()
  66. DECLARE_POLY_AGGREGATABLE(CMarsAxHostWindow)
  67. BEGIN_MSG_MAP(CMarsAxHostWindow)
  68. MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
  69. MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging)
  70. MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
  71. MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
  72. CHAIN_MSG_MAP(CAxHostWindow);
  73. END_MSG_MAP()
  74. LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  75. LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  76. LRESULT OnWindowPosChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  77. LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  78. // IObjectWithSite overrides
  79. STDMETHOD(SetSite)(IUnknown* pUnkSite);
  80. // IOleInPlaceSite overrides
  81. STDMETHOD(OnUIActivate)();
  82. // IOleControlSite overrides
  83. STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, DWORD grfModifiers);
  84. // IDispatch overrides
  85. STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
  86. DISPPARAMS *pdispparams, VARIANT *pvarResult,
  87. EXCEPINFO *pexcepinfo, UINT *puArgErr);
  88. // IDocHostUIHandler overrides
  89. HRESULT AskHostForDocHostUIHandler( CComPtr<IDocHostUIHandler>& spHost );
  90. STDMETHOD(ShowContextMenu)(DWORD dwID, POINT* pptPosition, IUnknown* pCommandTarget, IDispatch* pDispatchObjectHit)
  91. {
  92. FORWARD_IDOCHOSTUIHANDLER_4( ShowContextMenu, dwID, pptPosition, pCommandTarget, pDispatchObjectHit );
  93. }
  94. STDMETHOD(GetHostInfo)(DOCHOSTUIINFO* pInfo)
  95. {
  96. FORWARD_IDOCHOSTUIHANDLER_1( GetHostInfo, pInfo );
  97. }
  98. STDMETHOD(ShowUI)(DWORD dwID, IOleInPlaceActiveObject* pActiveObject, IOleCommandTarget* pCommandTarget, IOleInPlaceFrame* pFrame, IOleInPlaceUIWindow* pDoc)
  99. {
  100. FORWARD_IDOCHOSTUIHANDLER_5( ShowUI, dwID, pActiveObject, pCommandTarget, pFrame, pDoc );
  101. }
  102. STDMETHOD(HideUI)()
  103. {
  104. FORWARD_IDOCHOSTUIHANDLER( HideUI );
  105. }
  106. STDMETHOD(UpdateUI)()
  107. {
  108. FORWARD_IDOCHOSTUIHANDLER( UpdateUI );
  109. }
  110. STDMETHOD(EnableModeless)(BOOL fEnable)
  111. {
  112. FORWARD_IDOCHOSTUIHANDLER_1( EnableModeless, fEnable );
  113. }
  114. STDMETHOD(OnDocWindowActivate)(BOOL fActivate)
  115. {
  116. FORWARD_IDOCHOSTUIHANDLER_1( OnDocWindowActivate, fActivate );
  117. }
  118. STDMETHOD(OnFrameWindowActivate)(BOOL fActivate)
  119. {
  120. FORWARD_IDOCHOSTUIHANDLER_1( OnFrameWindowActivate, fActivate );
  121. }
  122. STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow* pUIWindow, BOOL fFrameWindow)
  123. {
  124. FORWARD_IDOCHOSTUIHANDLER_3( ResizeBorder, prcBorder, pUIWindow, fFrameWindow );
  125. }
  126. STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, const GUID* pguidCmdGroup, DWORD nCmdID)
  127. {
  128. FORWARD_IDOCHOSTUIHANDLER_3( TranslateAccelerator, lpMsg, pguidCmdGroup, nCmdID );
  129. }
  130. STDMETHOD(GetOptionKeyPath)(BSTR* pbstrKey, DWORD dwReserved)
  131. {
  132. FORWARD_IDOCHOSTUIHANDLER_2( GetOptionKeyPath, pbstrKey, dwReserved );
  133. }
  134. STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget, IDropTarget** ppDropTarget)
  135. {
  136. FORWARD_IDOCHOSTUIHANDLER_2( GetDropTarget, pDropTarget, ppDropTarget );
  137. }
  138. STDMETHOD(GetExternal)(IDispatch** ppDispatch)
  139. {
  140. FORWARD_IDOCHOSTUIHANDLER_1( GetExternal, ppDispatch );
  141. }
  142. STDMETHOD(TranslateUrl)(DWORD dwTranslate, OLECHAR* pchURLIn, OLECHAR** ppchURLOut)
  143. {
  144. FORWARD_IDOCHOSTUIHANDLER_3( TranslateUrl, dwTranslate, pchURLIn, ppchURLOut );
  145. }
  146. STDMETHOD(FilterDataObject)(IDataObject* pDO, IDataObject** ppDORet)
  147. {
  148. FORWARD_IDOCHOSTUIHANDLER_2( FilterDataObject, pDO, ppDORet );
  149. }
  150. ////////////////////
  151. // IOleInPlaceSite overrides
  152. STDMETHOD(GetWindowContext)(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo);
  153. // IOleCommandTarget methods
  154. STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[], OLECMDTEXT *pcmdtext);
  155. STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut);
  156. private:
  157. CComClassPtr<CMarsPanel> m_spMarsPanel;
  158. };
  159. template <class TBase = CWindow>
  160. class CMarsAxWindowT : public TBase
  161. {
  162. public:
  163. // Constructors
  164. CMarsAxWindowT(HWND hWnd = NULL) : TBase(hWnd)
  165. { }
  166. CMarsAxWindowT< TBase >& operator=(HWND hWnd)
  167. {
  168. m_hWnd = hWnd;
  169. return *this;
  170. }
  171. // Attributes
  172. static LPCTSTR GetWndClassName()
  173. {
  174. return _T("PCHAxWin");
  175. }
  176. // Operations
  177. HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  178. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  179. UINT nID = 0, LPVOID lpCreateParam = NULL)
  180. {
  181. return CWindow::Create(GetWndClassName(), hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
  182. }
  183. HWND Create(HWND hWndParent, LPRECT lpRect = NULL, LPCTSTR szWindowName = NULL,
  184. DWORD dwStyle = 0, DWORD dwExStyle = 0,
  185. HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
  186. {
  187. return CWindow::Create(GetWndClassName(), hWndParent, lpRect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
  188. }
  189. HRESULT QueryHost(REFIID iid, void** ppUnk)
  190. {
  191. ATLASSERT(ppUnk != NULL);
  192. HRESULT hr;
  193. *ppUnk = NULL;
  194. CComPtr<IUnknown> spUnk;
  195. hr = AtlAxGetHost(m_hWnd, &spUnk);
  196. if (SUCCEEDED(hr))
  197. hr = spUnk->QueryInterface(iid, ppUnk);
  198. return hr;
  199. }
  200. template <class Q>
  201. HRESULT QueryHost(Q** ppUnk)
  202. {
  203. return QueryHost(__uuidof(Q), (void**)ppUnk);
  204. }
  205. HRESULT QueryControl(REFIID iid, void** ppUnk)
  206. {
  207. ATLASSERT(ppUnk != NULL);
  208. HRESULT hr;
  209. *ppUnk = NULL;
  210. CComPtr<IUnknown> spUnk;
  211. hr = AtlAxGetControl(m_hWnd, &spUnk);
  212. if (SUCCEEDED(hr))
  213. hr = spUnk->QueryInterface(iid, ppUnk);
  214. return hr;
  215. }
  216. template <class Q>
  217. HRESULT QueryControl(Q** ppUnk)
  218. {
  219. return QueryControl(__uuidof(Q), (void**)ppUnk);
  220. }
  221. HRESULT SetExternalDispatch(IDispatch* pDisp)
  222. {
  223. HRESULT hr;
  224. CComPtr<IAxWinHostWindow> spHost;
  225. hr = QueryHost(IID_IAxWinHostWindow, (void**)&spHost);
  226. if (SUCCEEDED(hr))
  227. hr = spHost->SetExternalDispatch(pDisp);
  228. return hr;
  229. }
  230. HRESULT SetExternalUIHandler(IDocHostUIHandlerDispatch* pUIHandler)
  231. {
  232. HRESULT hr;
  233. CComPtr<IAxWinHostWindow> spHost;
  234. hr = QueryHost(IID_IAxWinHostWindow, (void**)&spHost);
  235. if (SUCCEEDED(hr))
  236. hr = spHost->SetExternalUIHandler(pUIHandler);
  237. return hr;
  238. }
  239. };
  240. typedef CMarsAxWindowT<CWindow> CMarsAxWindow;
  241. static LRESULT CALLBACK MarsAxWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  242. {
  243. switch(uMsg)
  244. {
  245. case WM_CREATE:
  246. {
  247. // create control from a PROGID in the title
  248. // This is to make sure drag drop works
  249. ::OleInitialize(NULL);
  250. CREATESTRUCT* lpCreate = (CREATESTRUCT*)lParam;
  251. int nLen = ::GetWindowTextLength(hWnd);
  252. LPTSTR lpstrName = (LPTSTR)_alloca((nLen + 1) * sizeof(TCHAR));
  253. ::GetWindowText(hWnd, lpstrName, nLen + 1);
  254. ::SetWindowText(hWnd, _T(""));
  255. IAxWinHostWindow* pAxWindow = NULL;
  256. int nCreateSize = 0;
  257. if (lpCreate && lpCreate->lpCreateParams)
  258. nCreateSize = *((WORD*)lpCreate->lpCreateParams);
  259. CComPtr<IStream> spStream;
  260. if (nCreateSize)
  261. {
  262. HGLOBAL h = GlobalAlloc(GHND, nCreateSize);
  263. if (h)
  264. {
  265. BYTE* pBytes = (BYTE*) GlobalLock(h);
  266. BYTE* pSource = ((BYTE*)(lpCreate->lpCreateParams)) + sizeof(WORD);
  267. //Align to DWORD
  268. //pSource += (((~((DWORD)pSource)) + 1) & 3);
  269. memcpy(pBytes, pSource, nCreateSize);
  270. GlobalUnlock(h);
  271. CreateStreamOnHGlobal(h, TRUE, &spStream);
  272. }
  273. }
  274. USES_CONVERSION;
  275. CComPtr<IUnknown> spUnk;
  276. HRESULT hRet = MarsAxCreateControl(T2COLE(lpstrName), hWnd, spStream, &spUnk);
  277. if(FAILED(hRet))
  278. return -1; // abort window creation
  279. hRet = spUnk->QueryInterface(IID_IAxWinHostWindow, (void**)&pAxWindow);
  280. if(FAILED(hRet))
  281. return -1; // abort window creation
  282. ::SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG_PTR)pAxWindow );
  283. // check for control parent style if control has a window
  284. HWND hWndChild = ::GetWindow(hWnd, GW_CHILD);
  285. if(hWndChild != NULL)
  286. {
  287. if(::GetWindowLong(hWndChild, GWL_EXSTYLE) & WS_EX_CONTROLPARENT)
  288. {
  289. DWORD dwExStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE);
  290. dwExStyle |= WS_EX_CONTROLPARENT;
  291. ::SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle);
  292. }
  293. }
  294. // continue with DefWindowProc
  295. }
  296. break;
  297. case WM_NCDESTROY:
  298. {
  299. IAxWinHostWindow* pAxWindow = (IAxWinHostWindow*)::GetWindowLongPtr( hWnd, GWLP_USERDATA );
  300. if(pAxWindow != NULL)
  301. pAxWindow->Release();
  302. OleUninitialize();
  303. }
  304. break;
  305. default:
  306. break;
  307. }
  308. return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
  309. }
  310. ATLINLINE ATLAPI_(BOOL) MarsAxWinInit()
  311. {
  312. EnterCriticalSection(&_Module.m_csWindowCreate);
  313. WM_ATLGETHOST = RegisterWindowMessage(_T("WM_ATLGETHOST"));
  314. WM_ATLGETCONTROL = RegisterWindowMessage(_T("WM_ATLGETCONTROL"));
  315. WNDCLASSEX wc;
  316. // first check if the class is already registered
  317. wc.cbSize = sizeof(WNDCLASSEX);
  318. BOOL bRet = ::GetClassInfoEx(_Module.GetModuleInstance(), CMarsAxWindow::GetWndClassName(), &wc);
  319. // register class if not
  320. if(!bRet)
  321. {
  322. wc.cbSize = sizeof(WNDCLASSEX);
  323. #ifdef _ATL_DLL_IMPL
  324. wc.style = CS_GLOBALCLASS;
  325. #else
  326. wc.style = 0;
  327. #endif
  328. wc.lpfnWndProc = MarsAxWindowProc;
  329. wc.cbClsExtra = 0;
  330. wc.cbWndExtra = 0;
  331. wc.hInstance = _Module.GetModuleInstance();
  332. wc.hIcon = NULL;
  333. wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
  334. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  335. wc.lpszMenuName = NULL;
  336. wc.lpszClassName = CMarsAxWindow::GetWndClassName();
  337. wc.hIconSm = NULL;
  338. bRet = (BOOL)::RegisterClassEx(&wc);
  339. }
  340. LeaveCriticalSection(&_Module.m_csWindowCreate);
  341. return bRet;
  342. }
  343. ATLINLINE ATLAPI MarsAxCreateControl(LPCOLESTR lpszName, HWND hWnd, IStream* pStream, IUnknown** ppUnkContainer)
  344. {
  345. return MarsAxCreateControlEx(lpszName, hWnd, pStream, ppUnkContainer, NULL, IID_NULL, NULL);
  346. }
  347. ATLINLINE ATLAPI MarsAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd, IStream * pStream,
  348. IUnknown** ppUnkContainer, IUnknown** ppUnkControl, REFIID iidSink, IUnknown* punkSink)
  349. {
  350. MarsAxWinInit();
  351. HRESULT hr;
  352. CComPtr<IUnknown> spUnkContainer;
  353. CComPtr<IUnknown> spUnkControl;
  354. hr = CMarsAxHostWindow::_CreatorClass::CreateInstance(NULL, IID_IUnknown, (void**)&spUnkContainer);
  355. if (SUCCEEDED(hr))
  356. {
  357. CComPtr<IAxWinHostWindow> pAxWindow;
  358. spUnkContainer->QueryInterface(IID_IAxWinHostWindow, (void**)&pAxWindow);
  359. CComBSTR bstrName(lpszName);
  360. hr = pAxWindow->CreateControlEx(bstrName, hWnd, pStream, &spUnkControl, iidSink, punkSink);
  361. }
  362. if (ppUnkContainer != NULL)
  363. {
  364. if (SUCCEEDED(hr))
  365. {
  366. *ppUnkContainer = spUnkContainer.p;
  367. spUnkContainer.p = NULL;
  368. }
  369. else
  370. *ppUnkContainer = NULL;
  371. }
  372. if (ppUnkControl != NULL)
  373. {
  374. if (SUCCEEDED(hr))
  375. {
  376. *ppUnkControl = SUCCEEDED(hr) ? spUnkControl.p : NULL;
  377. spUnkControl.p = NULL;
  378. }
  379. else
  380. *ppUnkControl = NULL;
  381. }
  382. return hr;
  383. }
  384. HRESULT GetDoc2FromAxWindow(CMarsAxWindow *pAxWin, IHTMLDocument2 **ppDoc2);
  385. HRESULT GetWin2FromDoc2(IHTMLDocument2 *pDoc2, IHTMLWindow2 **ppWin2);
  386. HRESULT GetWin2FromAxWindow(CMarsAxWindow *pAxWin, IHTMLWindow2 **ppWin2);
  387. HRESULT GetControlWindow(CMarsAxWindow *pAxWin, HWND *phwnd);
  388. #endif