Source code of Windows XP (NT5)
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.

2635 lines
72 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-2001 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. #ifndef __ATLHOST_H__
  11. #define __ATLHOST_H__
  12. #pragma once
  13. #ifndef _ATL_NO_PRAGMA_WARNINGS
  14. #pragma warning (push)
  15. #pragma warning(disable: 4702) // unreachable code
  16. #endif //!_ATL_NO_PRAGMA_WARNINGS
  17. #include <urlmon.h>
  18. #include <mshtml.h>
  19. #include <mshtmhst.h>
  20. #include <exdisp.h>
  21. #ifndef _ATL_AXHOST
  22. #define _ATL_AXHOST
  23. #endif //_ATL_AXHOST
  24. #include <atlwin.h>
  25. #include <atlcom.h>
  26. #ifndef __cplusplus
  27. #error ATL requires C++ compilation (use a .cpp suffix)
  28. #endif
  29. #ifdef _ATL_NO_HOSTING
  30. #error atlhost.h requires Hosting support (_ATL_NO_HOSTING is defined)
  31. #endif //_ATL_NO_HOSTING
  32. namespace ATL
  33. {
  34. //AtlAxWinTerm is not exported
  35. inline BOOL AtlAxWinTerm()
  36. {
  37. #ifndef _ATL_DLL //don't unregister DLL's version
  38. UnregisterClass(CAxWindow::GetWndClassName(), _AtlBaseModule.GetModuleInstance());
  39. UnregisterClass(CAxWindow2::GetWndClassName(), _AtlBaseModule.GetModuleInstance());
  40. #endif
  41. return TRUE;
  42. }
  43. // Define this to host SHDOCVW rather than MSHTML
  44. #define SHDOCVW
  45. UINT __declspec(selectany) WM_ATLGETHOST = 0;
  46. UINT __declspec(selectany) WM_ATLGETCONTROL = 0;
  47. typedef HRESULT (__stdcall *typeMkParseDisplayName)(IBindCtx*, LPCWSTR , ULONG*, LPMONIKER*);
  48. static HRESULT CreateNormalizedObject(LPCOLESTR lpszTricsData, REFIID riid, void** ppvObj, bool& bWasHTML, BSTR bstrLicKey)
  49. {
  50. ATLASSERT(ppvObj);
  51. if (ppvObj == NULL)
  52. return E_POINTER;
  53. *ppvObj = NULL;
  54. CLSID clsid;
  55. HRESULT hr = E_FAIL;
  56. bWasHTML = false;
  57. if (lpszTricsData == NULL || lpszTricsData[0] == 0)
  58. return S_OK;
  59. // Is it HTML ?
  60. USES_CONVERSION;
  61. if ((lpszTricsData[0] == OLECHAR('M') || lpszTricsData[0] == OLECHAR('m')) &&
  62. (lpszTricsData[1] == OLECHAR('S') || lpszTricsData[1] == OLECHAR('s')) &&
  63. (lpszTricsData[2] == OLECHAR('H') || lpszTricsData[2] == OLECHAR('h')) &&
  64. (lpszTricsData[3] == OLECHAR('T') || lpszTricsData[3] == OLECHAR('t')) &&
  65. (lpszTricsData[4] == OLECHAR('M') || lpszTricsData[4] == OLECHAR('m')) &&
  66. (lpszTricsData[5] == OLECHAR('L') || lpszTricsData[5] == OLECHAR('l')) &&
  67. (lpszTricsData[6] == OLECHAR(':')))
  68. {
  69. // It's HTML, so let's create mshtml
  70. hr = CoCreateInstance(__uuidof(HTMLDocument), NULL, CLSCTX_INPROC_SERVER, riid, ppvObj);
  71. bWasHTML = true;
  72. }
  73. // Is it a URL?
  74. else if (CAtlModule::FindOneOf(OLE2CT(lpszTricsData), _T(":")))
  75. {
  76. // URL so let's create shdocvw
  77. hr = CoCreateInstance(__uuidof(WebBrowser), NULL, CLSCTX_INPROC_SERVER, riid, ppvObj);
  78. bWasHTML = true;
  79. }
  80. // assume ProgID or CLSID
  81. else
  82. {
  83. // Can't be clsid, or progid if length is greater than 255
  84. if (ocslen(lpszTricsData) < 255)
  85. {
  86. if (lpszTricsData[0] == '{') // Is it a CLSID?
  87. hr = CLSIDFromString((LPOLESTR)lpszTricsData, &clsid);
  88. else
  89. hr = CLSIDFromProgID((LPOLESTR)lpszTricsData, &clsid); // How about a ProgID?
  90. }
  91. if (SUCCEEDED(hr))
  92. {
  93. // If the license key is present
  94. // Create using IClassFactory2.
  95. if (bstrLicKey != NULL)
  96. {
  97. CComPtr<IClassFactory2> spClassFactory;
  98. hr = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER, NULL, __uuidof(IClassFactory2), (void**)&spClassFactory);
  99. if (SUCCEEDED(hr))
  100. hr = spClassFactory->CreateInstanceLic(NULL, NULL, riid, bstrLicKey, ppvObj);
  101. }
  102. else
  103. hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppvObj);
  104. }
  105. }
  106. return hr;
  107. }
  108. class ATL_NO_VTABLE CAxFrameWindow :
  109. public CComObjectRootEx<CComObjectThreadModel>,
  110. public CWindowImpl<CAxFrameWindow>,
  111. public IOleInPlaceFrame
  112. {
  113. public:
  114. CAxFrameWindow()
  115. {
  116. }
  117. void FinalRelease()
  118. {
  119. m_spActiveObject.Release();
  120. if (m_hWnd)
  121. DestroyWindow();
  122. }
  123. DECLARE_POLY_AGGREGATABLE(CAxFrameWindow)
  124. BEGIN_COM_MAP(CAxFrameWindow)
  125. COM_INTERFACE_ENTRY(IOleInPlaceFrame)
  126. COM_INTERFACE_ENTRY(IOleInPlaceUIWindow)
  127. COM_INTERFACE_ENTRY(IOleWindow)
  128. END_COM_MAP()
  129. DECLARE_EMPTY_MSG_MAP()
  130. // IOleWindow
  131. STDMETHOD(GetWindow)(HWND* phwnd)
  132. {
  133. if (m_hWnd == NULL)
  134. Create(NULL, NULL, _T("AXWIN Frame Window"), WS_OVERLAPPEDWINDOW, 0, (UINT)NULL);
  135. *phwnd = m_hWnd;
  136. return S_OK;
  137. }
  138. STDMETHOD(ContextSensitiveHelp)(BOOL /*fEnterMode*/)
  139. {
  140. return S_OK;
  141. }
  142. // IOleInPlaceUIWindow
  143. STDMETHOD(GetBorder)(LPRECT /*lprectBorder*/)
  144. {
  145. return S_OK;
  146. }
  147. STDMETHOD(RequestBorderSpace)(LPCBORDERWIDTHS /*pborderwidths*/)
  148. {
  149. return INPLACE_E_NOTOOLSPACE;
  150. }
  151. STDMETHOD(SetBorderSpace)(LPCBORDERWIDTHS /*pborderwidths*/)
  152. {
  153. return S_OK;
  154. }
  155. STDMETHOD(SetActiveObject)(IOleInPlaceActiveObject* pActiveObject, LPCOLESTR /*pszObjName*/)
  156. {
  157. m_spActiveObject = pActiveObject;
  158. return S_OK;
  159. }
  160. // IOleInPlaceFrameWindow
  161. STDMETHOD(InsertMenus)(HMENU /*hmenuShared*/, LPOLEMENUGROUPWIDTHS /*lpMenuWidths*/)
  162. {
  163. return S_OK;
  164. }
  165. STDMETHOD(SetMenu)(HMENU /*hmenuShared*/, HOLEMENU /*holemenu*/, HWND /*hwndActiveObject*/)
  166. {
  167. return S_OK;
  168. }
  169. STDMETHOD(RemoveMenus)(HMENU /*hmenuShared*/)
  170. {
  171. return S_OK;
  172. }
  173. STDMETHOD(SetStatusText)(LPCOLESTR /*pszStatusText*/)
  174. {
  175. return S_OK;
  176. }
  177. STDMETHOD(EnableModeless)(BOOL /*fEnable*/)
  178. {
  179. return S_OK;
  180. }
  181. STDMETHOD(TranslateAccelerator)(LPMSG /*lpMsg*/, WORD /*wID*/)
  182. {
  183. return S_FALSE;
  184. }
  185. CComPtr<IOleInPlaceActiveObject> m_spActiveObject;
  186. };
  187. class ATL_NO_VTABLE CAxUIWindow :
  188. public CComObjectRootEx<CComObjectThreadModel>,
  189. public CWindowImpl<CAxUIWindow>,
  190. public IOleInPlaceUIWindow
  191. {
  192. public:
  193. CAxUIWindow()
  194. {
  195. }
  196. void FinalRelease()
  197. {
  198. m_spActiveObject.Release();
  199. if (m_hWnd)
  200. DestroyWindow();
  201. }
  202. DECLARE_POLY_AGGREGATABLE(CAxUIWindow)
  203. BEGIN_COM_MAP(CAxUIWindow)
  204. COM_INTERFACE_ENTRY(IOleInPlaceUIWindow)
  205. COM_INTERFACE_ENTRY(IOleWindow)
  206. END_COM_MAP()
  207. DECLARE_EMPTY_MSG_MAP()
  208. // IOleWindow
  209. STDMETHOD(GetWindow)(HWND* phwnd)
  210. {
  211. if (m_hWnd == NULL)
  212. Create(NULL, NULL, _T("AXWIN UI Window"), WS_OVERLAPPEDWINDOW, 0, (UINT)NULL);
  213. *phwnd = m_hWnd;
  214. return S_OK;
  215. }
  216. STDMETHOD(ContextSensitiveHelp)(BOOL /*fEnterMode*/)
  217. {
  218. return S_OK;
  219. }
  220. // IOleInPlaceUIWindow
  221. STDMETHOD(GetBorder)(LPRECT /*lprectBorder*/)
  222. {
  223. return S_OK;
  224. }
  225. STDMETHOD(RequestBorderSpace)(LPCBORDERWIDTHS /*pborderwidths*/)
  226. {
  227. return INPLACE_E_NOTOOLSPACE;
  228. }
  229. STDMETHOD(SetBorderSpace)(LPCBORDERWIDTHS /*pborderwidths*/)
  230. {
  231. return S_OK;
  232. }
  233. STDMETHOD(SetActiveObject)(IOleInPlaceActiveObject* pActiveObject, LPCOLESTR /*pszObjName*/)
  234. {
  235. m_spActiveObject = pActiveObject;
  236. return S_OK;
  237. }
  238. CComPtr<IOleInPlaceActiveObject> m_spActiveObject;
  239. };
  240. /////////////////////////////////////////////////////////////////////////////
  241. // CAxHostWindow
  242. // This class is not cocreateable
  243. class ATL_NO_VTABLE CAxHostWindow :
  244. public CComCoClass<CAxHostWindow , &CLSID_NULL>,
  245. public CComObjectRootEx<CComSingleThreadModel>,
  246. public CWindowImpl<CAxHostWindow>,
  247. public IAxWinHostWindowLic,
  248. public IOleClientSite,
  249. public IOleInPlaceSiteWindowless,
  250. public IOleControlSite,
  251. public IOleContainer,
  252. public IObjectWithSiteImpl<CAxHostWindow>,
  253. public IServiceProvider,
  254. public IAdviseSink,
  255. #ifndef _ATL_NO_DOCHOSTUIHANDLER
  256. public IDocHostUIHandler,
  257. #endif
  258. public IDispatchImpl<IAxWinAmbientDispatchEx, &__uuidof(IAxWinAmbientDispatchEx), &LIBID_ATLLib>
  259. {
  260. public:
  261. // ctor/dtor
  262. CAxHostWindow()
  263. {
  264. m_bInPlaceActive = FALSE;
  265. m_bUIActive = FALSE;
  266. m_bMDIApp = FALSE;
  267. m_bWindowless = FALSE;
  268. m_bCapture = FALSE;
  269. m_bHaveFocus = FALSE;
  270. // Initialize ambient properties
  271. m_bCanWindowlessActivate = TRUE;
  272. m_bUserMode = TRUE;
  273. m_bDisplayAsDefault = FALSE;
  274. m_clrBackground = NULL;
  275. m_clrForeground = GetSysColor(COLOR_WINDOWTEXT);
  276. m_lcidLocaleID = LOCALE_USER_DEFAULT;
  277. m_bMessageReflect = true;
  278. m_bReleaseAll = FALSE;
  279. m_bSubclassed = FALSE;
  280. m_dwAdviseSink = 0xCDCDCDCD;
  281. m_dwDocHostFlags = DOCHOSTUIFLAG_NO3DBORDER;
  282. m_dwDocHostDoubleClickFlags = DOCHOSTUIDBLCLK_DEFAULT;
  283. m_bAllowContextMenu = true;
  284. m_bAllowShowUI = false;
  285. m_hDCScreen = NULL;
  286. m_bDCReleased = true;
  287. m_hAccel = NULL;
  288. }
  289. ~CAxHostWindow()
  290. {
  291. }
  292. void FinalRelease()
  293. {
  294. ReleaseAll();
  295. }
  296. virtual void OnFinalMessage(HWND /*hWnd*/)
  297. {
  298. GetControllingUnknown()->Release();
  299. }
  300. DECLARE_NO_REGISTRY()
  301. DECLARE_POLY_AGGREGATABLE(CAxHostWindow)
  302. DECLARE_GET_CONTROLLING_UNKNOWN()
  303. BEGIN_COM_MAP(CAxHostWindow)
  304. COM_INTERFACE_ENTRY2(IDispatch, IAxWinAmbientDispatchEx)
  305. COM_INTERFACE_ENTRY(IAxWinHostWindow)
  306. COM_INTERFACE_ENTRY(IAxWinHostWindowLic)
  307. COM_INTERFACE_ENTRY(IOleClientSite)
  308. COM_INTERFACE_ENTRY(IOleInPlaceSiteWindowless)
  309. COM_INTERFACE_ENTRY(IOleInPlaceSiteEx)
  310. COM_INTERFACE_ENTRY(IOleInPlaceSite)
  311. COM_INTERFACE_ENTRY(IOleWindow)
  312. COM_INTERFACE_ENTRY(IOleControlSite)
  313. COM_INTERFACE_ENTRY(IOleContainer)
  314. COM_INTERFACE_ENTRY(IObjectWithSite)
  315. COM_INTERFACE_ENTRY(IServiceProvider)
  316. COM_INTERFACE_ENTRY(IAxWinAmbientDispatchEx)
  317. COM_INTERFACE_ENTRY(IAxWinAmbientDispatch)
  318. #ifndef _ATL_NO_DOCHOSTUIHANDLER
  319. COM_INTERFACE_ENTRY(IDocHostUIHandler)
  320. #endif
  321. COM_INTERFACE_ENTRY(IAdviseSink)
  322. END_COM_MAP()
  323. static CWndClassInfo& GetWndClassInfo()
  324. {
  325. static CWndClassInfo wc =
  326. {
  327. { sizeof(WNDCLASSEX), 0, StartWindowProc,
  328. 0, 0, 0, 0, 0, (HBRUSH)(COLOR_WINDOW + 1), 0, _T(ATLAXWIN_CLASS), 0 },
  329. NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
  330. };
  331. return wc;
  332. }
  333. BEGIN_MSG_MAP(CAxHostWindow)
  334. MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
  335. MESSAGE_HANDLER(WM_PAINT, OnPaint)
  336. MESSAGE_HANDLER(WM_SIZE, OnSize)
  337. MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
  338. MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
  339. MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
  340. if (m_bWindowless)
  341. {
  342. // Mouse messages handled when a windowless control has captured the cursor
  343. // or if the cursor is over the control
  344. DWORD dwHitResult = m_bCapture ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  345. if (dwHitResult == HITRESULT_OUTSIDE && m_spViewObject != NULL)
  346. {
  347. POINT ptMouse = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
  348. m_spViewObject->QueryHitPoint(DVASPECT_CONTENT, &m_rcPos, ptMouse, 0, &dwHitResult);
  349. }
  350. if (dwHitResult == HITRESULT_HIT)
  351. {
  352. MESSAGE_HANDLER(WM_MOUSEMOVE, OnWindowlessMouseMessage)
  353. MESSAGE_HANDLER(WM_SETCURSOR, OnWindowlessMouseMessage)
  354. MESSAGE_HANDLER(WM_LBUTTONUP, OnWindowlessMouseMessage)
  355. MESSAGE_HANDLER(WM_RBUTTONUP, OnWindowlessMouseMessage)
  356. MESSAGE_HANDLER(WM_MBUTTONUP, OnWindowlessMouseMessage)
  357. MESSAGE_HANDLER(WM_LBUTTONDOWN, OnWindowlessMouseMessage)
  358. MESSAGE_HANDLER(WM_RBUTTONDOWN, OnWindowlessMouseMessage)
  359. MESSAGE_HANDLER(WM_MBUTTONDOWN, OnWindowlessMouseMessage)
  360. MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnWindowlessMouseMessage)
  361. MESSAGE_HANDLER(WM_RBUTTONDBLCLK, OnWindowlessMouseMessage)
  362. MESSAGE_HANDLER(WM_MBUTTONDBLCLK, OnWindowlessMouseMessage)
  363. }
  364. }
  365. if (m_bWindowless & m_bHaveFocus)
  366. {
  367. // Keyboard messages handled only when a windowless control has the focus
  368. MESSAGE_HANDLER(WM_KEYDOWN, OnWindowMessage)
  369. MESSAGE_HANDLER(WM_KEYUP, OnWindowMessage)
  370. MESSAGE_HANDLER(WM_CHAR, OnWindowMessage)
  371. MESSAGE_HANDLER(WM_DEADCHAR, OnWindowMessage)
  372. MESSAGE_HANDLER(WM_SYSKEYDOWN, OnWindowMessage)
  373. MESSAGE_HANDLER(WM_SYSKEYUP, OnWindowMessage)
  374. MESSAGE_HANDLER(WM_SYSDEADCHAR, OnWindowMessage)
  375. MESSAGE_HANDLER(WM_HELP, OnWindowMessage)
  376. MESSAGE_HANDLER(WM_CANCELMODE, OnWindowMessage)
  377. MESSAGE_HANDLER(WM_IME_CHAR, OnWindowMessage)
  378. MESSAGE_HANDLER(WM_MBUTTONDBLCLK, OnWindowMessage)
  379. MESSAGE_RANGE_HANDLER(WM_IME_SETCONTEXT, WM_IME_KEYUP, OnWindowMessage)
  380. }
  381. MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
  382. if (m_bMessageReflect)
  383. {
  384. bHandled = TRUE;
  385. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled);
  386. if(bHandled)
  387. return TRUE;
  388. }
  389. MESSAGE_HANDLER(WM_ATLGETHOST, OnGetUnknown)
  390. MESSAGE_HANDLER(WM_ATLGETCONTROL, OnGetControl)
  391. MESSAGE_HANDLER(WM_FORWARDMSG, OnForwardMsg)
  392. END_MSG_MAP()
  393. LRESULT OnForwardMsg(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
  394. {
  395. ATLASSERT(lParam != 0);
  396. LPMSG lpMsg = (LPMSG)lParam;
  397. CComQIPtr<IOleInPlaceActiveObject, &__uuidof(IOleInPlaceActiveObject)> spInPlaceActiveObject(m_spUnknown);
  398. if(spInPlaceActiveObject)
  399. {
  400. if(spInPlaceActiveObject->TranslateAccelerator(lpMsg) == S_OK)
  401. return 1;
  402. }
  403. return 0;
  404. }
  405. LRESULT OnGetUnknown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  406. {
  407. IUnknown* pUnk = GetControllingUnknown();
  408. pUnk->AddRef();
  409. return (LRESULT)pUnk;
  410. }
  411. LRESULT OnGetControl(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  412. {
  413. IUnknown* pUnk = m_spUnknown;
  414. if (pUnk)
  415. pUnk->AddRef();
  416. return (LRESULT)pUnk;
  417. }
  418. void ReleaseAll()
  419. {
  420. if (m_bReleaseAll)
  421. return;
  422. m_bReleaseAll = TRUE;
  423. if (m_spViewObject != NULL)
  424. m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, NULL);
  425. if(m_dwAdviseSink != 0xCDCDCDCD)
  426. {
  427. AtlUnadvise(m_spUnknown, m_iidSink, m_dwAdviseSink);
  428. m_dwAdviseSink = 0xCDCDCDCD;
  429. }
  430. if (m_spOleObject)
  431. {
  432. m_spOleObject->Unadvise(m_dwOleObject);
  433. m_spOleObject->Close(OLECLOSE_NOSAVE);
  434. m_spOleObject->SetClientSite(NULL);
  435. }
  436. if (m_spUnknown != NULL)
  437. {
  438. CComPtr<IObjectWithSite> spSite;
  439. m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);
  440. if (spSite != NULL)
  441. spSite->SetSite(NULL);
  442. }
  443. m_spViewObject.Release();
  444. m_dwViewObjectType = 0;
  445. m_spInPlaceObjectWindowless.Release();
  446. m_spOleObject.Release();
  447. m_spUnknown.Release();
  448. m_spInPlaceUIWindow.Release();
  449. m_spInPlaceFrame.Release();
  450. m_bInPlaceActive = FALSE;
  451. m_bWindowless = FALSE;
  452. m_bInPlaceActive = FALSE;
  453. m_bUIActive = FALSE;
  454. m_bCapture = FALSE;
  455. m_bReleaseAll = FALSE;
  456. if (m_hAccel != NULL)
  457. {
  458. DestroyAcceleratorTable(m_hAccel);
  459. m_hAccel = NULL;
  460. }
  461. }
  462. // window message handlers
  463. LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  464. {
  465. if (m_spViewObject == NULL)
  466. bHandled = false;
  467. return 1;
  468. }
  469. LRESULT OnMouseActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  470. {
  471. bHandled = FALSE;
  472. if (m_dwMiscStatus & OLEMISC_NOUIACTIVATE)
  473. {
  474. if (m_spOleObject != NULL && !m_bInPlaceActive)
  475. {
  476. CComPtr<IOleClientSite> spClientSite;
  477. GetControllingUnknown()->QueryInterface(__uuidof(IOleClientSite), (void**)&spClientSite);
  478. if (spClientSite != NULL)
  479. m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, m_hWnd, &m_rcPos);
  480. }
  481. }
  482. else
  483. {
  484. BOOL b;
  485. OnSetFocus(0, 0, 0, b);
  486. }
  487. return 0;
  488. }
  489. LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  490. {
  491. m_bHaveFocus = TRUE;
  492. if (!m_bReleaseAll)
  493. {
  494. if (m_spOleObject != NULL && !m_bUIActive)
  495. {
  496. CComPtr<IOleClientSite> spClientSite;
  497. GetControllingUnknown()->QueryInterface(__uuidof(IOleClientSite), (void**)&spClientSite);
  498. if (spClientSite != NULL)
  499. m_spOleObject->DoVerb(OLEIVERB_UIACTIVATE, NULL, spClientSite, 0, m_hWnd, &m_rcPos);
  500. }
  501. if (m_bWindowless)
  502. ::SetFocus(m_hWnd);
  503. else if(!IsChild(::GetFocus()))
  504. ::SetFocus(::GetWindow(m_hWnd, GW_CHILD));
  505. }
  506. bHandled = FALSE;
  507. return 0;
  508. }
  509. LRESULT OnKillFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  510. {
  511. m_bHaveFocus = FALSE;
  512. bHandled = FALSE;
  513. return 0;
  514. }
  515. LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
  516. {
  517. int nWidth = GET_X_LPARAM(lParam); // width of client area
  518. int nHeight = GET_Y_LPARAM(lParam); // height of client area
  519. m_rcPos.right = m_rcPos.left + nWidth;
  520. m_rcPos.bottom = m_rcPos.top + nHeight;
  521. m_pxSize.cx = m_rcPos.right - m_rcPos.left;
  522. m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;
  523. AtlPixelToHiMetric(&m_pxSize, &m_hmSize);
  524. if (m_spOleObject)
  525. m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);
  526. if (m_spInPlaceObjectWindowless)
  527. m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);
  528. if (m_bWindowless)
  529. InvalidateRect(NULL, TRUE);
  530. bHandled = FALSE;
  531. return 0;
  532. }
  533. LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  534. {
  535. GetControllingUnknown()->AddRef();
  536. DefWindowProc(uMsg, wParam, lParam);
  537. ReleaseAll();
  538. bHandled = FALSE;
  539. return 0;
  540. }
  541. LRESULT OnWindowMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  542. {
  543. LRESULT lRes = 0;
  544. HRESULT hr = S_FALSE;
  545. if (m_bInPlaceActive && m_bWindowless && m_spInPlaceObjectWindowless)
  546. hr = m_spInPlaceObjectWindowless->OnWindowMessage(uMsg, wParam, lParam, &lRes);
  547. if (hr == S_FALSE)
  548. bHandled = FALSE;
  549. return lRes;
  550. }
  551. LRESULT OnWindowlessMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  552. {
  553. LRESULT lRes = 0;
  554. if (m_bInPlaceActive && m_bWindowless && m_spInPlaceObjectWindowless)
  555. m_spInPlaceObjectWindowless->OnWindowMessage(uMsg, wParam, lParam, &lRes);
  556. bHandled = FALSE;
  557. return lRes;
  558. }
  559. LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  560. {
  561. if (m_spViewObject == NULL)
  562. {
  563. PAINTSTRUCT ps;
  564. HDC hdc = ::BeginPaint(m_hWnd, &ps);
  565. if (hdc == NULL)
  566. return 0;
  567. RECT rcClient;
  568. GetClientRect(&rcClient);
  569. HBRUSH hbrBack = CreateSolidBrush(m_clrBackground);
  570. if (hbrBack != NULL)
  571. {
  572. FillRect(hdc, &rcClient, hbrBack);
  573. DeleteObject(hbrBack);
  574. }
  575. ::EndPaint(m_hWnd, &ps);
  576. return 1;
  577. }
  578. if (m_spViewObject && m_bWindowless)
  579. {
  580. PAINTSTRUCT ps;
  581. HDC hdc = ::BeginPaint(m_hWnd, &ps);
  582. if (hdc == NULL)
  583. return 0;
  584. RECT rcClient;
  585. GetClientRect(&rcClient);
  586. HBITMAP hBitmap = CreateCompatibleBitmap(hdc, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
  587. if (hBitmap != NULL)
  588. {
  589. HDC hdcCompatible = ::CreateCompatibleDC(hdc);
  590. if (hdcCompatible != NULL)
  591. {
  592. HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcCompatible, hBitmap);
  593. if (hBitmapOld != NULL)
  594. {
  595. HBRUSH hbrBack = CreateSolidBrush(m_clrBackground);
  596. if (hbrBack != NULL)
  597. {
  598. FillRect(hdcCompatible, &rcClient, hbrBack);
  599. DeleteObject(hbrBack);
  600. m_spViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcCompatible, (RECTL*)&m_rcPos, (RECTL*)&m_rcPos, NULL, NULL);
  601. ::BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcCompatible, 0, 0, SRCCOPY);
  602. }
  603. ::SelectObject(hdcCompatible, hBitmapOld);
  604. }
  605. ::DeleteDC(hdcCompatible);
  606. }
  607. ::DeleteObject(hBitmap);
  608. }
  609. ::EndPaint(m_hWnd, &ps);
  610. }
  611. else
  612. {
  613. bHandled = FALSE;
  614. return 0;
  615. }
  616. return 1;
  617. }
  618. // IAxWinHostWindow
  619. STDMETHOD(CreateControl)(LPCOLESTR lpTricsData, HWND hWnd, IStream* pStream)
  620. {
  621. CComPtr<IUnknown> p;
  622. return CreateControlLicEx(lpTricsData, hWnd, pStream, &p, IID_NULL, NULL, NULL);
  623. }
  624. STDMETHOD(CreateControlEx)(LPCOLESTR lpszTricsData, HWND hWnd, IStream* pStream, IUnknown** ppUnk, REFIID iidAdvise, IUnknown* punkSink)
  625. {
  626. return CreateControlLicEx(lpszTricsData, hWnd, pStream, ppUnk, iidAdvise, punkSink, NULL);
  627. }
  628. STDMETHOD(AttachControl)(IUnknown* pUnkControl, HWND hWnd)
  629. {
  630. HRESULT hr = S_FALSE;
  631. ReleaseAll();
  632. bool bReleaseWindowOnFailure = false; // Used to keep track of whether we subclass the window
  633. if ((m_hWnd != NULL) && (m_hWnd != hWnd)) // Don't release the window if it's the same as the one we already subclass/own
  634. {
  635. RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
  636. ReleaseWindow();
  637. }
  638. if (::IsWindow(hWnd))
  639. {
  640. if (m_hWnd != hWnd) // Don't need to subclass the window if we already own it
  641. {
  642. SubclassWindow(hWnd);
  643. bReleaseWindowOnFailure = true;
  644. }
  645. hr = ActivateAx(pUnkControl, true, NULL);
  646. if (FAILED(hr))
  647. {
  648. ReleaseAll();
  649. if (m_hWnd != NULL)
  650. {
  651. RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
  652. if (bReleaseWindowOnFailure) // We subclassed the window in an attempt to create this control, so we unsubclass on failure
  653. ReleaseWindow();
  654. }
  655. }
  656. }
  657. return hr;
  658. }
  659. STDMETHOD(QueryControl)(REFIID riid, void** ppvObject)
  660. {
  661. HRESULT hr = E_POINTER;
  662. if (ppvObject)
  663. {
  664. if (m_spUnknown)
  665. {
  666. hr = m_spUnknown->QueryInterface(riid, ppvObject);
  667. }
  668. else
  669. {
  670. *ppvObject = NULL;
  671. hr = OLE_E_NOCONNECTION;
  672. }
  673. }
  674. return hr;
  675. }
  676. STDMETHOD(SetExternalDispatch)(IDispatch* pDisp)
  677. {
  678. m_spExternalDispatch = pDisp;
  679. return S_OK;
  680. }
  681. STDMETHOD(SetExternalUIHandler)(IDocHostUIHandlerDispatch* pUIHandler)
  682. {
  683. #ifndef _ATL_NO_DOCHOSTUIHANDLER
  684. m_spIDocHostUIHandlerDispatch = pUIHandler;
  685. #endif
  686. return S_OK;
  687. }
  688. STDMETHOD(CreateControlLic)(LPCOLESTR lpTricsData, HWND hWnd, IStream* pStream, BSTR bstrLic)
  689. {
  690. CComPtr<IUnknown> p;
  691. return CreateControlLicEx(lpTricsData, hWnd, pStream, &p, IID_NULL, NULL, bstrLic);
  692. }
  693. STDMETHOD(CreateControlLicEx)(LPCOLESTR lpszTricsData, HWND hWnd, IStream* pStream, IUnknown** ppUnk, REFIID iidAdvise, IUnknown* punkSink, BSTR bstrLic)
  694. {
  695. ATLASSERT(ppUnk != NULL);
  696. if (ppUnk == NULL)
  697. return E_POINTER;
  698. *ppUnk = NULL;
  699. HRESULT hr = S_FALSE;
  700. bool bReleaseWindowOnFailure = false; // Used to keep track of whether we subclass the window
  701. ReleaseAll();
  702. if ((m_hWnd != NULL) && (m_hWnd != hWnd)) // Don't release the window if it's the same as the one we already subclass/own
  703. {
  704. RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
  705. ReleaseWindow();
  706. }
  707. if (::IsWindow(hWnd))
  708. {
  709. USES_CONVERSION;
  710. if (m_hWnd != hWnd) // Don't need to subclass the window if we already own it
  711. {
  712. SubclassWindow(hWnd);
  713. bReleaseWindowOnFailure = true;
  714. }
  715. if (m_clrBackground == NULL)
  716. {
  717. if (IsParentDialog())
  718. m_clrBackground = GetSysColor(COLOR_BTNFACE);
  719. else
  720. m_clrBackground = GetSysColor(COLOR_WINDOW);
  721. }
  722. bool bWasHTML = false;
  723. hr = CreateNormalizedObject(lpszTricsData, __uuidof(IUnknown), (void**)ppUnk, bWasHTML, bstrLic);
  724. if (SUCCEEDED(hr))
  725. hr = ActivateAx(*ppUnk, false, pStream);
  726. // Try to hook up any sink the user might have given us.
  727. m_iidSink = iidAdvise;
  728. if(SUCCEEDED(hr) && *ppUnk && punkSink)
  729. AtlAdvise(*ppUnk, punkSink, m_iidSink, &m_dwAdviseSink);
  730. if (SUCCEEDED(hr) && bWasHTML && *ppUnk != NULL)
  731. {
  732. if ((GetStyle() & (WS_VSCROLL | WS_HSCROLL)) == 0)
  733. m_dwDocHostFlags |= DOCHOSTUIFLAG_SCROLL_NO;
  734. else
  735. {
  736. DWORD dwStyle = GetStyle();
  737. SetWindowLong(GWL_STYLE, dwStyle & ~(WS_VSCROLL | WS_HSCROLL));
  738. SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_DRAWFRAME);
  739. }
  740. CComPtr<IUnknown> spUnk(*ppUnk);
  741. // Is it just plain HTML?
  742. USES_CONVERSION;
  743. if ((lpszTricsData[0] == OLECHAR('M') || lpszTricsData[0] == OLECHAR('m')) &&
  744. (lpszTricsData[1] == OLECHAR('S') || lpszTricsData[1] == OLECHAR('s')) &&
  745. (lpszTricsData[2] == OLECHAR('H') || lpszTricsData[2] == OLECHAR('h')) &&
  746. (lpszTricsData[3] == OLECHAR('T') || lpszTricsData[3] == OLECHAR('t')) &&
  747. (lpszTricsData[4] == OLECHAR('M') || lpszTricsData[4] == OLECHAR('m')) &&
  748. (lpszTricsData[5] == OLECHAR('L') || lpszTricsData[5] == OLECHAR('l')) &&
  749. (lpszTricsData[6] == OLECHAR(':')))
  750. {
  751. // Just HTML: load the HTML data into the document
  752. UINT nCreateSize = (ocslen(lpszTricsData) - 7) * sizeof(OLECHAR);
  753. HGLOBAL hGlobal = GlobalAlloc(GHND, nCreateSize);
  754. if (hGlobal)
  755. {
  756. CComPtr<IStream> spStream;
  757. BYTE* pBytes = (BYTE*) GlobalLock(hGlobal);
  758. memcpy(pBytes, lpszTricsData + 7, nCreateSize);
  759. GlobalUnlock(hGlobal);
  760. hr = CreateStreamOnHGlobal(hGlobal, TRUE, &spStream);
  761. if (SUCCEEDED(hr))
  762. {
  763. CComPtr<IPersistStreamInit> spPSI;
  764. hr = spUnk->QueryInterface(__uuidof(IPersistStreamInit), (void**)&spPSI);
  765. if (SUCCEEDED(hr))
  766. hr = spPSI->Load(spStream);
  767. }
  768. }
  769. else
  770. hr = E_OUTOFMEMORY;
  771. }
  772. else
  773. {
  774. CComPtr<IWebBrowser2> spBrowser;
  775. spUnk->QueryInterface(__uuidof(IWebBrowser2), (void**)&spBrowser);
  776. if (spBrowser)
  777. {
  778. CComVariant ve;
  779. CComVariant vurl(lpszTricsData);
  780. spBrowser->put_Visible(ATL_VARIANT_TRUE);
  781. spBrowser->Navigate2(&vurl, &ve, &ve, &ve, &ve);
  782. }
  783. }
  784. }
  785. if (FAILED(hr) || m_spUnknown == NULL)
  786. {
  787. // We don't have a control or something failed so release
  788. ReleaseAll();
  789. if (m_hWnd != NULL)
  790. {
  791. RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
  792. if (FAILED(hr) && bReleaseWindowOnFailure) // We subclassed the window in an attempt to create this control, so we unsubclass on failure
  793. ReleaseWindow();
  794. }
  795. }
  796. }
  797. return hr;
  798. }
  799. #ifndef _ATL_NO_DOCHOSTUIHANDLER
  800. // IDocHostUIHandler
  801. // MSHTML requests to display its context menu
  802. STDMETHOD(ShowContextMenu)(DWORD dwID, POINT* pptPosition, IUnknown* pCommandTarget, IDispatch* pDispatchObjectHit)
  803. {
  804. HRESULT hr = m_bAllowContextMenu ? S_FALSE : S_OK;
  805. if (m_spIDocHostUIHandlerDispatch != NULL)
  806. m_spIDocHostUIHandlerDispatch->ShowContextMenu(
  807. dwID,
  808. pptPosition->x,
  809. pptPosition->y,
  810. pCommandTarget,
  811. pDispatchObjectHit,
  812. &hr);
  813. return hr;
  814. }
  815. // Called at initialisation to find UI styles from container
  816. STDMETHOD(GetHostInfo)(DOCHOSTUIINFO* pInfo)
  817. {
  818. if (pInfo == NULL)
  819. return E_POINTER;
  820. if (m_spIDocHostUIHandlerDispatch != NULL)
  821. return m_spIDocHostUIHandlerDispatch->GetHostInfo(&pInfo->dwFlags, &pInfo->dwDoubleClick);
  822. pInfo->dwFlags = m_dwDocHostFlags;
  823. pInfo->dwDoubleClick = m_dwDocHostDoubleClickFlags;
  824. return S_OK;
  825. }
  826. // Allows the host to replace the IE4/MSHTML menus and toolbars.
  827. STDMETHOD(ShowUI)(DWORD dwID, IOleInPlaceActiveObject* pActiveObject, IOleCommandTarget* pCommandTarget, IOleInPlaceFrame* pFrame, IOleInPlaceUIWindow* pDoc)
  828. {
  829. HRESULT hr = m_bAllowShowUI ? S_FALSE : S_OK;
  830. if (m_spIDocHostUIHandlerDispatch != NULL)
  831. m_spIDocHostUIHandlerDispatch->ShowUI(
  832. dwID,
  833. pActiveObject,
  834. pCommandTarget,
  835. pFrame,
  836. pDoc,
  837. &hr);
  838. return hr;
  839. }
  840. // Called when IE4/MSHTML removes its menus and toolbars.
  841. STDMETHOD(HideUI)()
  842. {
  843. HRESULT hr = S_OK;
  844. if (m_spIDocHostUIHandlerDispatch != NULL)
  845. hr = m_spIDocHostUIHandlerDispatch->HideUI();
  846. return hr;
  847. }
  848. // Notifies the host that the command state has changed.
  849. STDMETHOD(UpdateUI)()
  850. {
  851. HRESULT hr = S_OK;
  852. if (m_spIDocHostUIHandlerDispatch != NULL)
  853. hr = m_spIDocHostUIHandlerDispatch->UpdateUI();
  854. return hr;
  855. }
  856. // Called from the IE4/MSHTML implementation of IOleInPlaceActiveObject::EnableModeless
  857. STDMETHOD(EnableModeless)(BOOL fEnable)
  858. {
  859. HRESULT hr = S_OK;
  860. if (m_spIDocHostUIHandlerDispatch != NULL)
  861. hr = m_spIDocHostUIHandlerDispatch->EnableModeless(fEnable ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE);
  862. return hr;
  863. }
  864. // Called from the IE4/MSHTML implementation of IOleInPlaceActiveObject::OnDocWindowActivate
  865. STDMETHOD(OnDocWindowActivate)(BOOL fActivate)
  866. {
  867. HRESULT hr = S_OK;
  868. if (m_spIDocHostUIHandlerDispatch != NULL)
  869. hr = m_spIDocHostUIHandlerDispatch->OnDocWindowActivate(fActivate ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE);
  870. return hr;
  871. }
  872. // Called from the IE4/MSHTML implementation of IOleInPlaceActiveObject::OnFrameWindowActivate.
  873. STDMETHOD(OnFrameWindowActivate)(BOOL fActivate)
  874. {
  875. HRESULT hr = S_OK;
  876. if (m_spIDocHostUIHandlerDispatch != NULL)
  877. hr = m_spIDocHostUIHandlerDispatch->OnFrameWindowActivate(fActivate ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE);
  878. return hr;
  879. }
  880. // Called from the IE4/MSHTML implementation of IOleInPlaceActiveObject::ResizeBorder.
  881. STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow* pUIWindow, BOOL fFrameWindow)
  882. {
  883. HRESULT hr = S_OK;
  884. if (m_spIDocHostUIHandlerDispatch != NULL)
  885. hr = m_spIDocHostUIHandlerDispatch->ResizeBorder(
  886. prcBorder->left,
  887. prcBorder->top,
  888. prcBorder->right,
  889. prcBorder->bottom,
  890. pUIWindow,
  891. fFrameWindow ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE);
  892. return hr;
  893. }
  894. // Called by IE4/MSHTML when IOleInPlaceActiveObject::TranslateAccelerator or IOleControlSite::TranslateAccelerator is called.
  895. STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, const GUID* pguidCmdGroup, DWORD nCmdID)
  896. {
  897. HRESULT hr = S_FALSE;
  898. if (m_spIDocHostUIHandlerDispatch != NULL)
  899. m_spIDocHostUIHandlerDispatch->TranslateAccelerator(
  900. (DWORD_PTR) lpMsg->hwnd,
  901. lpMsg->message,
  902. lpMsg->wParam,
  903. lpMsg->lParam,
  904. CComBSTR(*pguidCmdGroup),
  905. nCmdID,
  906. &hr);
  907. return hr;
  908. }
  909. // Returns the registry key under which IE4/MSHTML stores user preferences.
  910. // Returns S_OK if successful, or S_FALSE otherwise. If S_FALSE, IE4/MSHTML will default to its own user options.
  911. STDMETHOD(GetOptionKeyPath)(LPOLESTR* pchKey, DWORD dwReserved)
  912. {
  913. HRESULT hr = S_FALSE;
  914. if (pchKey == NULL)
  915. return E_POINTER;
  916. *pchKey = NULL;
  917. if (m_spIDocHostUIHandlerDispatch != NULL)
  918. {
  919. hr = m_spIDocHostUIHandlerDispatch->GetOptionKeyPath(pchKey, dwReserved);
  920. if (FAILED(hr) || *pchKey == NULL)
  921. hr = S_FALSE;
  922. }
  923. else
  924. {
  925. if (m_bstrOptionKeyPath.m_str != NULL)
  926. {
  927. UINT nByteLength = m_bstrOptionKeyPath.ByteLength();
  928. LPOLESTR pStr = (LPOLESTR)CoTaskMemAlloc(nByteLength + sizeof(OLECHAR));
  929. if (pStr == NULL)
  930. return E_OUTOFMEMORY;
  931. ocscpy(pStr, m_bstrOptionKeyPath.m_str);
  932. *pchKey = pStr;
  933. hr = S_OK;
  934. }
  935. }
  936. return hr;
  937. }
  938. // Called by IE4/MSHTML when it is being used as a drop target to allow the host to supply an alternative IDropTarget
  939. STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget, IDropTarget** ppDropTarget)
  940. {
  941. ATLASSERT(ppDropTarget != NULL);
  942. if (ppDropTarget == NULL)
  943. return E_POINTER;
  944. *ppDropTarget = NULL;
  945. HRESULT hr = E_NOTIMPL;
  946. if (m_spIDocHostUIHandlerDispatch != NULL)
  947. {
  948. CComPtr<IUnknown> spUnk;
  949. hr = m_spIDocHostUIHandlerDispatch->GetDropTarget(pDropTarget, &spUnk);
  950. if (spUnk)
  951. hr = spUnk->QueryInterface(__uuidof(IDropTarget), (void**)ppDropTarget);
  952. if (FAILED(hr) || *ppDropTarget == NULL)
  953. hr = S_FALSE;
  954. }
  955. return hr;
  956. }
  957. // Called by IE4/MSHTML to obtain the host's IDispatch interface
  958. STDMETHOD(GetExternal)(IDispatch** ppDispatch)
  959. {
  960. ATLASSERT(ppDispatch != NULL);
  961. if (ppDispatch == NULL)
  962. return E_POINTER;
  963. *ppDispatch = NULL;
  964. HRESULT hr = E_NOINTERFACE;
  965. if (m_spIDocHostUIHandlerDispatch != NULL)
  966. {
  967. hr = m_spIDocHostUIHandlerDispatch->GetExternal(ppDispatch);
  968. if (FAILED(hr) || *ppDispatch == NULL)
  969. hr = E_NOINTERFACE;
  970. }
  971. else
  972. {
  973. // return the IDispatch we have for extending the object Model
  974. if (ppDispatch != NULL)
  975. {
  976. m_spExternalDispatch.CopyTo(ppDispatch);
  977. hr = S_OK;
  978. }
  979. else
  980. hr = E_POINTER;
  981. }
  982. return hr;
  983. }
  984. // Called by IE4/MSHTML to allow the host an opportunity to modify the URL to be loaded
  985. STDMETHOD(TranslateUrl)(DWORD dwTranslate, OLECHAR* pchURLIn, OLECHAR** ppchURLOut)
  986. {
  987. ATLASSERT(ppchURLOut != NULL);
  988. if (ppchURLOut == NULL)
  989. return E_POINTER;
  990. *ppchURLOut = NULL;
  991. HRESULT hr = S_FALSE;
  992. if (m_spIDocHostUIHandlerDispatch != NULL)
  993. {
  994. CComBSTR bstrURLOut;
  995. hr = m_spIDocHostUIHandlerDispatch->TranslateUrl(dwTranslate, CComBSTR(pchURLIn), &bstrURLOut);
  996. if (SUCCEEDED(hr) && bstrURLOut.m_str != NULL)
  997. {
  998. UINT nLen = (bstrURLOut.Length() + 1) * 2;
  999. *ppchURLOut = (OLECHAR*) CoTaskMemAlloc(nLen);
  1000. if (*ppchURLOut == NULL)
  1001. return E_OUTOFMEMORY;
  1002. memcpy(*ppchURLOut, bstrURLOut.m_str, nLen);
  1003. }
  1004. else
  1005. hr = S_FALSE;
  1006. }
  1007. return hr;
  1008. }
  1009. // Called on the host by IE4/MSHTML to allow the host to replace IE4/MSHTML's data object.
  1010. // This allows the host to block certain clipboard formats or support additional clipboard formats.
  1011. STDMETHOD(FilterDataObject)(IDataObject* pDO, IDataObject** ppDORet)
  1012. {
  1013. ATLASSERT(ppDORet != NULL);
  1014. if (ppDORet == NULL)
  1015. return E_POINTER;
  1016. *ppDORet = NULL;
  1017. HRESULT hr = S_FALSE;
  1018. if (m_spIDocHostUIHandlerDispatch != NULL)
  1019. {
  1020. CComPtr<IUnknown> spUnk;
  1021. hr = m_spIDocHostUIHandlerDispatch->FilterDataObject(pDO, &spUnk);
  1022. if (spUnk)
  1023. hr = QueryInterface(__uuidof(IDataObject), (void**)ppDORet);
  1024. if (FAILED(hr) || *ppDORet == NULL)
  1025. hr = S_FALSE;
  1026. }
  1027. return hr;
  1028. }
  1029. #endif
  1030. HRESULT FireAmbientPropertyChange(DISPID dispChanged)
  1031. {
  1032. HRESULT hr = S_OK;
  1033. CComQIPtr<IOleControl, &__uuidof(IOleControl)> spOleControl(m_spUnknown);
  1034. if (spOleControl != NULL)
  1035. hr = spOleControl->OnAmbientPropertyChange(dispChanged);
  1036. return hr;
  1037. }
  1038. // IAxWinAmbientDispatch
  1039. CComPtr<IDispatch> m_spAmbientDispatch;
  1040. STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
  1041. VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
  1042. {
  1043. HRESULT hr = IDispatchImpl<IAxWinAmbientDispatchEx, &__uuidof(IAxWinAmbientDispatchEx), &LIBID_ATLLib>::Invoke
  1044. (dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
  1045. if ((hr == DISP_E_MEMBERNOTFOUND || hr == TYPE_E_ELEMENTNOTFOUND) && m_spAmbientDispatch != NULL)
  1046. {
  1047. hr = m_spAmbientDispatch->Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
  1048. if (SUCCEEDED(hr) && (wFlags & DISPATCH_PROPERTYPUT) != 0)
  1049. {
  1050. hr = FireAmbientPropertyChange(dispIdMember);
  1051. }
  1052. }
  1053. return hr;
  1054. }
  1055. STDMETHOD(put_AllowWindowlessActivation)(VARIANT_BOOL bAllowWindowless)
  1056. {
  1057. m_bCanWindowlessActivate = bAllowWindowless;
  1058. return S_OK;
  1059. }
  1060. STDMETHOD(get_AllowWindowlessActivation)(VARIANT_BOOL* pbAllowWindowless)
  1061. {
  1062. ATLASSERT(pbAllowWindowless != NULL);
  1063. if (pbAllowWindowless == NULL)
  1064. return E_POINTER;
  1065. *pbAllowWindowless = m_bCanWindowlessActivate ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
  1066. return S_OK;
  1067. }
  1068. STDMETHOD(put_BackColor)(OLE_COLOR clrBackground)
  1069. {
  1070. m_clrBackground = clrBackground;
  1071. FireAmbientPropertyChange(DISPID_AMBIENT_BACKCOLOR);
  1072. InvalidateRect(0, FALSE);
  1073. return S_OK;
  1074. }
  1075. STDMETHOD(get_BackColor)(OLE_COLOR* pclrBackground)
  1076. {
  1077. ATLASSERT(pclrBackground != NULL);
  1078. if (pclrBackground == NULL)
  1079. return E_POINTER;
  1080. *pclrBackground = m_clrBackground;
  1081. return S_OK;
  1082. }
  1083. STDMETHOD(put_ForeColor)(OLE_COLOR clrForeground)
  1084. {
  1085. m_clrForeground = clrForeground;
  1086. FireAmbientPropertyChange(DISPID_AMBIENT_FORECOLOR);
  1087. return S_OK;
  1088. }
  1089. STDMETHOD(get_ForeColor)(OLE_COLOR* pclrForeground)
  1090. {
  1091. ATLASSERT(pclrForeground != NULL);
  1092. if (pclrForeground == NULL)
  1093. return E_POINTER;
  1094. *pclrForeground = m_clrForeground;
  1095. return S_OK;
  1096. }
  1097. STDMETHOD(put_LocaleID)(LCID lcidLocaleID)
  1098. {
  1099. m_lcidLocaleID = lcidLocaleID;
  1100. FireAmbientPropertyChange(DISPID_AMBIENT_LOCALEID);
  1101. return S_OK;
  1102. }
  1103. STDMETHOD(get_LocaleID)(LCID* plcidLocaleID)
  1104. {
  1105. ATLASSERT(plcidLocaleID != NULL);
  1106. if (plcidLocaleID == NULL)
  1107. return E_POINTER;
  1108. *plcidLocaleID = m_lcidLocaleID;
  1109. return S_OK;
  1110. }
  1111. STDMETHOD(put_UserMode)(VARIANT_BOOL bUserMode)
  1112. {
  1113. m_bUserMode = bUserMode;
  1114. FireAmbientPropertyChange(DISPID_AMBIENT_USERMODE);
  1115. return S_OK;
  1116. }
  1117. STDMETHOD(get_UserMode)(VARIANT_BOOL* pbUserMode)
  1118. {
  1119. ATLASSERT(pbUserMode != NULL);
  1120. if (pbUserMode == NULL)
  1121. return E_POINTER;
  1122. *pbUserMode = m_bUserMode ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
  1123. return S_OK;
  1124. }
  1125. STDMETHOD(put_DisplayAsDefault)(VARIANT_BOOL bDisplayAsDefault)
  1126. {
  1127. m_bDisplayAsDefault = bDisplayAsDefault;
  1128. FireAmbientPropertyChange(DISPID_AMBIENT_DISPLAYASDEFAULT);
  1129. return S_OK;
  1130. }
  1131. STDMETHOD(get_DisplayAsDefault)(VARIANT_BOOL* pbDisplayAsDefault)
  1132. {
  1133. ATLASSERT(pbDisplayAsDefault != NULL);
  1134. if (pbDisplayAsDefault == NULL)
  1135. return E_POINTER;
  1136. *pbDisplayAsDefault = m_bDisplayAsDefault ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
  1137. return S_OK;
  1138. }
  1139. STDMETHOD(put_Font)(IFontDisp* pFont)
  1140. {
  1141. m_spFont = pFont;
  1142. FireAmbientPropertyChange(DISPID_AMBIENT_FONT);
  1143. return S_OK;
  1144. }
  1145. STDMETHOD(get_Font)(IFontDisp** pFont)
  1146. {
  1147. ATLASSERT(pFont != NULL);
  1148. if (pFont == NULL)
  1149. return E_POINTER;
  1150. *pFont = NULL;
  1151. if (m_spFont == NULL)
  1152. {
  1153. USES_CONVERSION;
  1154. HFONT hSystemFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
  1155. if (hSystemFont == NULL)
  1156. hSystemFont = (HFONT) GetStockObject(SYSTEM_FONT);
  1157. if (hSystemFont == NULL)
  1158. return AtlHresultFromLastError();
  1159. LOGFONT logfont;
  1160. GetObject(hSystemFont, sizeof(logfont), &logfont);
  1161. FONTDESC fd;
  1162. fd.cbSizeofstruct = sizeof(FONTDESC);
  1163. fd.lpstrName = T2OLE(logfont.lfFaceName);
  1164. fd.sWeight = (short)logfont.lfWeight;
  1165. fd.sCharset = logfont.lfCharSet;
  1166. fd.fItalic = logfont.lfItalic;
  1167. fd.fUnderline = logfont.lfUnderline;
  1168. fd.fStrikethrough = logfont.lfStrikeOut;
  1169. long lfHeight = logfont.lfHeight;
  1170. if (lfHeight < 0)
  1171. lfHeight = -lfHeight;
  1172. int ppi;
  1173. HDC hdc;
  1174. if (m_hWnd)
  1175. {
  1176. hdc = ::GetDC(m_hWnd);
  1177. if (hdc == NULL)
  1178. return AtlHresultFromLastError();
  1179. ppi = GetDeviceCaps(hdc, LOGPIXELSY);
  1180. ::ReleaseDC(m_hWnd, hdc);
  1181. }
  1182. else
  1183. {
  1184. hdc = ::GetDC(GetDesktopWindow());
  1185. if (hdc == NULL)
  1186. return AtlHresultFromLastError();
  1187. ppi = GetDeviceCaps(hdc, LOGPIXELSY);
  1188. ::ReleaseDC(GetDesktopWindow(), hdc);
  1189. }
  1190. fd.cySize.Lo = lfHeight * 720000 / ppi;
  1191. fd.cySize.Hi = 0;
  1192. OleCreateFontIndirect(&fd, __uuidof(IFontDisp), (void**) &m_spFont);
  1193. }
  1194. return m_spFont.CopyTo(pFont);
  1195. }
  1196. STDMETHOD(put_MessageReflect)(VARIANT_BOOL bMessageReflect)
  1197. {
  1198. m_bMessageReflect = bMessageReflect;
  1199. FireAmbientPropertyChange(DISPID_AMBIENT_MESSAGEREFLECT);
  1200. return S_OK;
  1201. }
  1202. STDMETHOD(get_MessageReflect)(VARIANT_BOOL* pbMessageReflect)
  1203. {
  1204. ATLASSERT(pbMessageReflect != NULL);
  1205. if (pbMessageReflect == NULL)
  1206. return E_POINTER;
  1207. *pbMessageReflect = m_bMessageReflect ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
  1208. return S_OK;
  1209. }
  1210. STDMETHOD(get_ShowGrabHandles)(VARIANT_BOOL* pbShowGrabHandles)
  1211. {
  1212. *pbShowGrabHandles = ATL_VARIANT_FALSE;
  1213. return S_OK;
  1214. }
  1215. STDMETHOD(get_ShowHatching)(VARIANT_BOOL* pbShowHatching)
  1216. {
  1217. ATLASSERT(pbShowHatching != NULL);
  1218. if (pbShowHatching == NULL)
  1219. return E_POINTER;
  1220. *pbShowHatching = ATL_VARIANT_FALSE;
  1221. return S_OK;
  1222. }
  1223. STDMETHOD(put_DocHostFlags)(DWORD dwDocHostFlags)
  1224. {
  1225. m_dwDocHostFlags = dwDocHostFlags;
  1226. FireAmbientPropertyChange(DISPID_UNKNOWN);
  1227. return S_OK;
  1228. }
  1229. STDMETHOD(get_DocHostFlags)(DWORD* pdwDocHostFlags)
  1230. {
  1231. ATLASSERT(pdwDocHostFlags != NULL);
  1232. if (pdwDocHostFlags == NULL)
  1233. return E_POINTER;
  1234. *pdwDocHostFlags = m_dwDocHostFlags;
  1235. return S_OK;
  1236. }
  1237. STDMETHOD(put_DocHostDoubleClickFlags)(DWORD dwDocHostDoubleClickFlags)
  1238. {
  1239. m_dwDocHostDoubleClickFlags = dwDocHostDoubleClickFlags;
  1240. return S_OK;
  1241. }
  1242. STDMETHOD(get_DocHostDoubleClickFlags)(DWORD* pdwDocHostDoubleClickFlags)
  1243. {
  1244. ATLASSERT(pdwDocHostDoubleClickFlags != NULL);
  1245. if (pdwDocHostDoubleClickFlags == NULL)
  1246. return E_POINTER;
  1247. *pdwDocHostDoubleClickFlags = m_dwDocHostDoubleClickFlags;
  1248. return S_OK;
  1249. }
  1250. STDMETHOD(put_AllowContextMenu)(VARIANT_BOOL bAllowContextMenu)
  1251. {
  1252. m_bAllowContextMenu = bAllowContextMenu;
  1253. return S_OK;
  1254. }
  1255. STDMETHOD(get_AllowContextMenu)(VARIANT_BOOL* pbAllowContextMenu)
  1256. {
  1257. ATLASSERT(pbAllowContextMenu != NULL);
  1258. if (pbAllowContextMenu == NULL)
  1259. return E_POINTER;
  1260. *pbAllowContextMenu = m_bAllowContextMenu ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
  1261. return S_OK;
  1262. }
  1263. STDMETHOD(put_AllowShowUI)(VARIANT_BOOL bAllowShowUI)
  1264. {
  1265. m_bAllowShowUI = bAllowShowUI;
  1266. return S_OK;
  1267. }
  1268. STDMETHOD(get_AllowShowUI)(VARIANT_BOOL* pbAllowShowUI)
  1269. {
  1270. ATLASSERT(pbAllowShowUI != NULL);
  1271. if (pbAllowShowUI == NULL)
  1272. return E_POINTER;
  1273. *pbAllowShowUI = m_bAllowShowUI ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
  1274. return S_OK;
  1275. }
  1276. STDMETHOD(put_OptionKeyPath)(BSTR bstrOptionKeyPath)
  1277. {
  1278. m_bstrOptionKeyPath = bstrOptionKeyPath;;
  1279. return S_OK;
  1280. }
  1281. STDMETHOD(get_OptionKeyPath)(BSTR* pbstrOptionKeyPath)
  1282. {
  1283. ATLASSERT(pbstrOptionKeyPath != NULL);
  1284. if (pbstrOptionKeyPath == NULL)
  1285. return E_POINTER;
  1286. *pbstrOptionKeyPath = m_bstrOptionKeyPath;
  1287. return S_OK;
  1288. }
  1289. STDMETHOD(SetAmbientDispatch)(IDispatch* pDispatch)
  1290. {
  1291. m_spAmbientDispatch = pDispatch;
  1292. return S_OK;
  1293. }
  1294. // IObjectWithSite
  1295. STDMETHOD(SetSite)(IUnknown* pUnkSite)
  1296. {
  1297. HRESULT hr = IObjectWithSiteImpl<CAxHostWindow>::SetSite(pUnkSite);
  1298. if (SUCCEEDED(hr) && m_spUnkSite)
  1299. {
  1300. // Look for "outer" IServiceProvider
  1301. hr = m_spUnkSite->QueryInterface(__uuidof(IServiceProvider), (void**)&m_spServices);
  1302. ATLASSERT( !hr && "No ServiceProvider!" );
  1303. }
  1304. if (pUnkSite == NULL)
  1305. m_spServices.Release();
  1306. return hr;
  1307. }
  1308. // IOleClientSite
  1309. STDMETHOD(SaveObject)()
  1310. {
  1311. ATLTRACENOTIMPL(_T("IOleClientSite::SaveObject"));
  1312. }
  1313. STDMETHOD(GetMoniker)(DWORD /*dwAssign*/, DWORD /*dwWhichMoniker*/, IMoniker** /*ppmk*/)
  1314. {
  1315. ATLTRACENOTIMPL(_T("IOleClientSite::GetMoniker"));
  1316. }
  1317. STDMETHOD(GetContainer)(IOleContainer** ppContainer)
  1318. {
  1319. ATLTRACE(atlTraceHosting, 2, _T("IOleClientSite::GetContainer\n"));
  1320. ATLASSERT(ppContainer != NULL);
  1321. HRESULT hr = E_POINTER;
  1322. if (ppContainer)
  1323. {
  1324. hr = E_NOTIMPL;
  1325. (*ppContainer) = NULL;
  1326. if (m_spUnkSite)
  1327. hr = m_spUnkSite->QueryInterface(__uuidof(IOleContainer), (void**)ppContainer);
  1328. if (FAILED(hr))
  1329. hr = QueryInterface(__uuidof(IOleContainer), (void**)ppContainer);
  1330. }
  1331. return hr;
  1332. }
  1333. STDMETHOD(ShowObject)()
  1334. {
  1335. ATLTRACE(atlTraceHosting, 2, _T("IOleClientSite::ShowObject\r\n"));
  1336. HDC hdc = CWindowImpl<CAxHostWindow>::GetDC();
  1337. if (hdc == NULL)
  1338. return E_FAIL;
  1339. if (m_spViewObject)
  1340. m_spViewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdc, (RECTL*)&m_rcPos, (RECTL*)&m_rcPos, NULL, NULL);
  1341. CWindowImpl<CAxHostWindow>::ReleaseDC(hdc);
  1342. return S_OK;
  1343. }
  1344. STDMETHOD(OnShowWindow)(BOOL /*fShow*/)
  1345. {
  1346. ATLTRACENOTIMPL(_T("IOleClientSite::OnShowWindow"));
  1347. }
  1348. STDMETHOD(RequestNewObjectLayout)()
  1349. {
  1350. ATLTRACENOTIMPL(_T("IOleClientSite::RequestNewObjectLayout"));
  1351. }
  1352. // IOleInPlaceSite
  1353. STDMETHOD(GetWindow)(HWND* phwnd)
  1354. {
  1355. *phwnd = m_hWnd;
  1356. return S_OK;
  1357. }
  1358. STDMETHOD(ContextSensitiveHelp)(BOOL /*fEnterMode*/)
  1359. {
  1360. ATLTRACENOTIMPL(_T("IOleInPlaceSite::ContextSensitiveHelp"));
  1361. }
  1362. STDMETHOD(CanInPlaceActivate)()
  1363. {
  1364. return S_OK;
  1365. }
  1366. STDMETHOD(OnInPlaceActivate)()
  1367. {
  1368. m_bInPlaceActive = TRUE;
  1369. OleLockRunning(m_spOleObject, TRUE, FALSE);
  1370. m_bWindowless = FALSE;
  1371. m_spOleObject->QueryInterface(__uuidof(IOleInPlaceObject), (void**) &m_spInPlaceObjectWindowless);
  1372. return S_OK;
  1373. }
  1374. STDMETHOD(OnUIActivate)()
  1375. {
  1376. ATLTRACE(atlTraceHosting, 2, _T("IOleInPlaceSite::OnUIActivate\n"));
  1377. m_bUIActive = TRUE;
  1378. return S_OK;
  1379. }
  1380. STDMETHOD(GetWindowContext)(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo)
  1381. {
  1382. if (ppFrame != NULL)
  1383. *ppFrame = NULL;
  1384. if (ppDoc != NULL)
  1385. *ppDoc = NULL;
  1386. if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || lprcClipRect == NULL)
  1387. {
  1388. ATLASSERT(false);
  1389. return E_POINTER;
  1390. }
  1391. if (!m_spInPlaceFrame)
  1392. {
  1393. CComObject<CAxFrameWindow>* pFrameWindow;
  1394. CComObject<CAxFrameWindow>::CreateInstance(&pFrameWindow);
  1395. pFrameWindow->QueryInterface(__uuidof(IOleInPlaceFrame), (void**) &m_spInPlaceFrame);
  1396. ATLASSERT(m_spInPlaceFrame);
  1397. }
  1398. if (!m_spInPlaceUIWindow)
  1399. {
  1400. CComObject<CAxUIWindow>* pUIWindow;
  1401. CComObject<CAxUIWindow>::CreateInstance(&pUIWindow);
  1402. pUIWindow->QueryInterface(__uuidof(IOleInPlaceUIWindow), (void**) &m_spInPlaceUIWindow);
  1403. ATLASSERT(m_spInPlaceUIWindow);
  1404. }
  1405. m_spInPlaceFrame.CopyTo(ppFrame);
  1406. m_spInPlaceUIWindow.CopyTo(ppDoc);
  1407. GetClientRect(lprcPosRect);
  1408. GetClientRect(lprcClipRect);
  1409. if (m_hAccel == NULL)
  1410. {
  1411. ACCEL ac = { 0,0,0 };
  1412. m_hAccel = CreateAcceleratorTable(&ac, 1);
  1413. }
  1414. pFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
  1415. pFrameInfo->fMDIApp = m_bMDIApp;
  1416. pFrameInfo->hwndFrame = GetParent();
  1417. pFrameInfo->haccel = m_hAccel;
  1418. pFrameInfo->cAccelEntries = (m_hAccel != NULL) ? 1 : 0;
  1419. return S_OK;
  1420. }
  1421. STDMETHOD(Scroll)(SIZE /*scrollExtant*/)
  1422. {
  1423. ATLTRACENOTIMPL(_T("IOleInPlaceSite::Scroll"));
  1424. }
  1425. STDMETHOD(OnUIDeactivate)(BOOL /*fUndoable*/)
  1426. {
  1427. ATLTRACE(atlTraceHosting, 2, _T("IOleInPlaceSite::OnUIDeactivate\n"));
  1428. m_bUIActive = FALSE;
  1429. return S_OK;
  1430. }
  1431. STDMETHOD(OnInPlaceDeactivate)()
  1432. {
  1433. m_bInPlaceActive = FALSE;
  1434. m_spInPlaceObjectWindowless.Release();
  1435. return S_OK;
  1436. }
  1437. STDMETHOD(DiscardUndoState)()
  1438. {
  1439. ATLTRACENOTIMPL(_T("IOleInPlaceSite::DiscardUndoState"));
  1440. }
  1441. STDMETHOD(DeactivateAndUndo)()
  1442. {
  1443. ATLTRACENOTIMPL(_T("IOleInPlaceSite::DeactivateAndUndo"));
  1444. }
  1445. STDMETHOD(OnPosRectChange)(LPCRECT /*lprcPosRect*/)
  1446. {
  1447. ATLTRACENOTIMPL(_T("IOleInPlaceSite::OnPosRectChange"));
  1448. }
  1449. // IOleInPlaceSiteEx
  1450. STDMETHOD(OnInPlaceActivateEx)(BOOL* /*pfNoRedraw*/, DWORD dwFlags)
  1451. {
  1452. m_bInPlaceActive = TRUE;
  1453. OleLockRunning(m_spOleObject, TRUE, FALSE);
  1454. HRESULT hr = E_FAIL;
  1455. if (dwFlags & ACTIVATE_WINDOWLESS)
  1456. {
  1457. m_bWindowless = TRUE;
  1458. hr = m_spOleObject->QueryInterface(__uuidof(IOleInPlaceObjectWindowless), (void**) &m_spInPlaceObjectWindowless);
  1459. }
  1460. if (FAILED(hr))
  1461. {
  1462. m_bWindowless = FALSE;
  1463. hr = m_spOleObject->QueryInterface(__uuidof(IOleInPlaceObject), (void**) &m_spInPlaceObjectWindowless);
  1464. }
  1465. if (m_spInPlaceObjectWindowless)
  1466. m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);
  1467. return S_OK;
  1468. }
  1469. STDMETHOD(OnInPlaceDeactivateEx)(BOOL /*fNoRedraw*/)
  1470. {
  1471. return S_OK;
  1472. }
  1473. STDMETHOD(RequestUIActivate)()
  1474. {
  1475. return S_OK;
  1476. }
  1477. // IOleInPlaceSiteWindowless
  1478. HDC m_hDCScreen;
  1479. bool m_bDCReleased;
  1480. STDMETHOD(CanWindowlessActivate)()
  1481. {
  1482. return m_bCanWindowlessActivate ? S_OK : S_FALSE;
  1483. }
  1484. STDMETHOD(GetCapture)()
  1485. {
  1486. return m_bCapture ? S_OK : S_FALSE;
  1487. }
  1488. STDMETHOD(SetCapture)(BOOL fCapture)
  1489. {
  1490. if (fCapture)
  1491. {
  1492. CWindow::SetCapture();
  1493. m_bCapture = TRUE;
  1494. }
  1495. else
  1496. {
  1497. ReleaseCapture();
  1498. m_bCapture = FALSE;
  1499. }
  1500. return S_OK;
  1501. }
  1502. STDMETHOD(GetFocus)()
  1503. {
  1504. return m_bHaveFocus ? S_OK : S_FALSE;
  1505. }
  1506. STDMETHOD(SetFocus)(BOOL fGotFocus)
  1507. {
  1508. m_bHaveFocus = fGotFocus;
  1509. return S_OK;
  1510. }
  1511. STDMETHOD(GetDC)(LPCRECT /*pRect*/, DWORD grfFlags, HDC* phDC)
  1512. {
  1513. if (phDC == NULL)
  1514. return E_POINTER;
  1515. if (!m_bDCReleased)
  1516. return E_FAIL;
  1517. *phDC = CWindowImpl<CAxHostWindow>::GetDC();
  1518. if (*phDC == NULL)
  1519. return E_FAIL;
  1520. m_bDCReleased = false;
  1521. if (grfFlags & OLEDC_NODRAW)
  1522. return S_OK;
  1523. RECT rect;
  1524. GetClientRect(&rect);
  1525. if (grfFlags & OLEDC_OFFSCREEN)
  1526. {
  1527. HDC hDCOffscreen = CreateCompatibleDC(*phDC);
  1528. if (hDCOffscreen != NULL)
  1529. {
  1530. HBITMAP hBitmap = CreateCompatibleBitmap(*phDC, rect.right - rect.left, rect.bottom - rect.top);
  1531. if (hBitmap == NULL)
  1532. DeleteDC(hDCOffscreen);
  1533. else
  1534. {
  1535. HGDIOBJ hOldBitmap = SelectObject(hDCOffscreen, hBitmap);
  1536. if (hOldBitmap == NULL)
  1537. {
  1538. DeleteObject(hBitmap);
  1539. DeleteDC(hDCOffscreen);
  1540. }
  1541. else
  1542. {
  1543. DeleteObject(hOldBitmap);
  1544. m_hDCScreen = *phDC;
  1545. *phDC = hDCOffscreen;
  1546. }
  1547. }
  1548. }
  1549. }
  1550. if (grfFlags & OLEDC_PAINTBKGND)
  1551. ::FillRect(*phDC, &rect, (HBRUSH) (COLOR_WINDOW+1));
  1552. return S_OK;
  1553. }
  1554. STDMETHOD(ReleaseDC)(HDC hDC)
  1555. {
  1556. m_bDCReleased = true;
  1557. if (m_hDCScreen != NULL)
  1558. {
  1559. RECT rect;
  1560. GetClientRect(&rect);
  1561. // Offscreen DC has to be copied to screen DC before releasing the screen dc;
  1562. BitBlt(m_hDCScreen, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hDC, 0, 0, SRCCOPY);
  1563. DeleteDC(hDC);
  1564. hDC = m_hDCScreen;
  1565. }
  1566. CWindowImpl<CAxHostWindow>::ReleaseDC(hDC);
  1567. return S_OK;
  1568. }
  1569. STDMETHOD(InvalidateRect)(LPCRECT pRect, BOOL fErase)
  1570. {
  1571. CWindowImpl<CAxHostWindow>::InvalidateRect(pRect, fErase);
  1572. return S_OK;
  1573. }
  1574. STDMETHOD(InvalidateRgn)(HRGN hRGN, BOOL fErase)
  1575. {
  1576. CWindowImpl<CAxHostWindow>::InvalidateRgn(hRGN, fErase);
  1577. return S_OK;
  1578. }
  1579. STDMETHOD(ScrollRect)(INT /*dx*/, INT /*dy*/, LPCRECT /*pRectScroll*/, LPCRECT /*pRectClip*/)
  1580. {
  1581. return S_OK;
  1582. }
  1583. STDMETHOD(AdjustRect)(LPRECT /*prc*/)
  1584. {
  1585. return S_OK;
  1586. }
  1587. STDMETHOD(OnDefWindowMessage)(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult)
  1588. {
  1589. *plResult = DefWindowProc(msg, wParam, lParam);
  1590. return S_OK;
  1591. }
  1592. // IOleControlSite
  1593. STDMETHOD(OnControlInfoChanged)()
  1594. {
  1595. return S_OK;
  1596. }
  1597. STDMETHOD(LockInPlaceActive)(BOOL /*fLock*/)
  1598. {
  1599. return S_OK;
  1600. }
  1601. STDMETHOD(GetExtendedControl)(IDispatch** ppDisp)
  1602. {
  1603. if (ppDisp == NULL)
  1604. return E_POINTER;
  1605. return m_spOleObject.QueryInterface(ppDisp);
  1606. }
  1607. STDMETHOD(TransformCoords)(POINTL* /*pPtlHimetric*/, POINTF* /*pPtfContainer*/, DWORD /*dwFlags*/)
  1608. {
  1609. ATLTRACENOTIMPL(_T("CAxHostWindow::TransformCoords"));
  1610. }
  1611. STDMETHOD(TranslateAccelerator)(LPMSG /*lpMsg*/, DWORD /*grfModifiers*/)
  1612. {
  1613. return S_FALSE;
  1614. }
  1615. STDMETHOD(OnFocus)(BOOL fGotFocus)
  1616. {
  1617. m_bHaveFocus = fGotFocus;
  1618. return S_OK;
  1619. }
  1620. STDMETHOD(ShowPropertyFrame)()
  1621. {
  1622. ATLTRACENOTIMPL(_T("CAxHostWindow::ShowPropertyFrame"));
  1623. }
  1624. // IAdviseSink
  1625. STDMETHOD_(void, OnDataChange)(FORMATETC* /*pFormatetc*/, STGMEDIUM* /*pStgmed*/)
  1626. {
  1627. }
  1628. STDMETHOD_(void, OnViewChange)(DWORD /*dwAspect*/, LONG /*lindex*/)
  1629. {
  1630. }
  1631. STDMETHOD_(void, OnRename)(IMoniker* /*pmk*/)
  1632. {
  1633. }
  1634. STDMETHOD_(void, OnSave)()
  1635. {
  1636. }
  1637. STDMETHOD_(void, OnClose)()
  1638. {
  1639. }
  1640. // IOleContainer
  1641. STDMETHOD(ParseDisplayName)(IBindCtx* /*pbc*/, LPOLESTR /*pszDisplayName*/, ULONG* /*pchEaten*/, IMoniker** /*ppmkOut*/)
  1642. {
  1643. ATLTRACENOTIMPL(_T("CAxHostWindow::ParseDisplayName"));
  1644. }
  1645. STDMETHOD(EnumObjects)(DWORD /*grfFlags*/, IEnumUnknown** ppenum)
  1646. {
  1647. if (ppenum == NULL)
  1648. return E_POINTER;
  1649. *ppenum = NULL;
  1650. typedef CComObject<CComEnum<IEnumUnknown, &__uuidof(IEnumUnknown), IUnknown*, _CopyInterface<IUnknown> > > enumunk;
  1651. enumunk* p = NULL;
  1652. ATLTRY(p = new enumunk);
  1653. if(p == NULL)
  1654. return E_OUTOFMEMORY;
  1655. IUnknown* pTemp = m_spUnknown;
  1656. // There is always only one object.
  1657. HRESULT hRes = p->Init(reinterpret_cast<IUnknown**>(&pTemp), reinterpret_cast<IUnknown**>(&pTemp + 1), GetControllingUnknown(), AtlFlagCopy);
  1658. if (SUCCEEDED(hRes))
  1659. hRes = p->QueryInterface(__uuidof(IEnumUnknown), (void**)ppenum);
  1660. if (FAILED(hRes))
  1661. delete p;
  1662. return hRes;
  1663. }
  1664. STDMETHOD(LockContainer)(BOOL fLock)
  1665. {
  1666. m_bLocked = fLock;
  1667. return S_OK;
  1668. }
  1669. HRESULT ActivateAx(IUnknown* pUnkControl, bool bInited, IStream* pStream)
  1670. {
  1671. if (pUnkControl == NULL)
  1672. return S_OK;
  1673. m_spUnknown = pUnkControl;
  1674. HRESULT hr = S_OK;
  1675. pUnkControl->QueryInterface(__uuidof(IOleObject), (void**)&m_spOleObject);
  1676. if (m_spOleObject)
  1677. {
  1678. m_spOleObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus);
  1679. if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
  1680. {
  1681. CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());
  1682. m_spOleObject->SetClientSite(spClientSite);
  1683. }
  1684. if (!bInited) // If user hasn't initialized the control, initialize/load using IPersistStreamInit or IPersistStream
  1685. {
  1686. CComQIPtr<IPersistStreamInit> spPSI(m_spOleObject);
  1687. if (spPSI)
  1688. {
  1689. if (pStream)
  1690. hr = spPSI->Load(pStream);
  1691. else
  1692. hr = spPSI->InitNew();
  1693. }
  1694. else if (pStream)
  1695. {
  1696. CComQIPtr<IPersistStream> spPS(m_spOleObject);
  1697. if (spPS)
  1698. hr = spPS->Load(pStream);
  1699. }
  1700. if (FAILED(hr)) // If the initialization of the control failed...
  1701. {
  1702. // Clean up and return
  1703. if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
  1704. m_spOleObject->SetClientSite(NULL);
  1705. m_dwMiscStatus = 0;
  1706. m_spOleObject.Release();
  1707. m_spUnknown.Release();
  1708. return hr;
  1709. }
  1710. }
  1711. if (0 == (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
  1712. {
  1713. CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());
  1714. m_spOleObject->SetClientSite(spClientSite);
  1715. }
  1716. m_dwViewObjectType = 0;
  1717. hr = m_spOleObject->QueryInterface(__uuidof(IViewObjectEx), (void**) &m_spViewObject);
  1718. if (FAILED(hr))
  1719. {
  1720. hr = m_spOleObject->QueryInterface(__uuidof(IViewObject2), (void**) &m_spViewObject);
  1721. if (SUCCEEDED(hr))
  1722. m_dwViewObjectType = 3;
  1723. } else
  1724. m_dwViewObjectType = 7;
  1725. if (FAILED(hr))
  1726. {
  1727. hr = m_spOleObject->QueryInterface(__uuidof(IViewObject), (void**) &m_spViewObject);
  1728. if (SUCCEEDED(hr))
  1729. m_dwViewObjectType = 1;
  1730. }
  1731. CComQIPtr<IAdviseSink> spAdviseSink(GetControllingUnknown());
  1732. m_spOleObject->Advise(spAdviseSink, &m_dwOleObject);
  1733. if (m_spViewObject)
  1734. m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, spAdviseSink);
  1735. m_spOleObject->SetHostNames(OLESTR("AXWIN"), NULL);
  1736. if ((m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME) == 0)
  1737. {
  1738. GetClientRect(&m_rcPos);
  1739. m_pxSize.cx = m_rcPos.right - m_rcPos.left;
  1740. m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;
  1741. AtlPixelToHiMetric(&m_pxSize, &m_hmSize);
  1742. m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);
  1743. m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize);
  1744. AtlHiMetricToPixel(&m_hmSize, &m_pxSize);
  1745. m_rcPos.right = m_rcPos.left + m_pxSize.cx;
  1746. m_rcPos.bottom = m_rcPos.top + m_pxSize.cy;
  1747. CComQIPtr<IOleClientSite> spClientSite(GetControllingUnknown());
  1748. hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, m_hWnd, &m_rcPos);
  1749. RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
  1750. }
  1751. }
  1752. CComPtr<IObjectWithSite> spSite;
  1753. pUnkControl->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite);
  1754. if (spSite != NULL)
  1755. spSite->SetSite(GetControllingUnknown());
  1756. return hr;
  1757. }
  1758. // pointers
  1759. CComPtr<IUnknown> m_spUnknown;
  1760. CComPtr<IOleObject> m_spOleObject;
  1761. CComPtr<IOleInPlaceFrame> m_spInPlaceFrame;
  1762. CComPtr<IOleInPlaceUIWindow> m_spInPlaceUIWindow;
  1763. CComPtr<IViewObjectEx> m_spViewObject;
  1764. CComPtr<IOleInPlaceObjectWindowless> m_spInPlaceObjectWindowless;
  1765. CComPtr<IDispatch> m_spExternalDispatch;
  1766. #ifndef _ATL_NO_DOCHOSTUIHANDLER
  1767. CComPtr<IDocHostUIHandlerDispatch> m_spIDocHostUIHandlerDispatch;
  1768. #endif
  1769. IID m_iidSink;
  1770. DWORD m_dwViewObjectType;
  1771. DWORD m_dwAdviseSink;
  1772. // state
  1773. unsigned long m_bInPlaceActive:1;
  1774. unsigned long m_bUIActive:1;
  1775. unsigned long m_bMDIApp:1;
  1776. unsigned long m_bWindowless:1;
  1777. unsigned long m_bCapture:1;
  1778. unsigned long m_bHaveFocus:1;
  1779. unsigned long m_bReleaseAll:1;
  1780. unsigned long m_bLocked:1;
  1781. DWORD m_dwOleObject;
  1782. DWORD m_dwMiscStatus;
  1783. SIZEL m_hmSize;
  1784. SIZEL m_pxSize;
  1785. RECT m_rcPos;
  1786. // Accelerator table
  1787. HACCEL m_hAccel;
  1788. // Ambient property storage
  1789. unsigned long m_bCanWindowlessActivate:1;
  1790. unsigned long m_bUserMode:1;
  1791. unsigned long m_bDisplayAsDefault:1;
  1792. unsigned long m_bMessageReflect:1;
  1793. unsigned long m_bSubclassed:1;
  1794. unsigned long m_bAllowContextMenu:1;
  1795. unsigned long m_bAllowShowUI:1;
  1796. OLE_COLOR m_clrBackground;
  1797. OLE_COLOR m_clrForeground;
  1798. LCID m_lcidLocaleID;
  1799. CComPtr<IFontDisp> m_spFont;
  1800. CComPtr<IServiceProvider> m_spServices;
  1801. DWORD m_dwDocHostFlags;
  1802. DWORD m_dwDocHostDoubleClickFlags;
  1803. CComBSTR m_bstrOptionKeyPath;
  1804. void SubclassWindow(HWND hWnd)
  1805. {
  1806. m_bSubclassed = CWindowImpl<CAxHostWindow>::SubclassWindow(hWnd);
  1807. }
  1808. void ReleaseWindow()
  1809. {
  1810. if (m_bSubclassed)
  1811. {
  1812. if(UnsubclassWindow(TRUE) != NULL)
  1813. m_bSubclassed = FALSE;
  1814. }
  1815. else
  1816. DestroyWindow();
  1817. }
  1818. // Reflection
  1819. LRESULT ReflectNotifications(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  1820. {
  1821. HWND hWndChild = NULL;
  1822. switch(uMsg)
  1823. {
  1824. case WM_COMMAND:
  1825. if(lParam != NULL) // not from a menu
  1826. hWndChild = (HWND)lParam;
  1827. break;
  1828. case WM_NOTIFY:
  1829. hWndChild = ((LPNMHDR)lParam)->hwndFrom;
  1830. break;
  1831. case WM_PARENTNOTIFY:
  1832. DefWindowProc();
  1833. switch(LOWORD(wParam))
  1834. {
  1835. case WM_CREATE:
  1836. case WM_DESTROY:
  1837. hWndChild = (HWND)lParam;
  1838. break;
  1839. default:
  1840. hWndChild = GetDlgItem(HIWORD(wParam));
  1841. break;
  1842. }
  1843. break;
  1844. case WM_DRAWITEM:
  1845. {
  1846. DRAWITEMSTRUCT* pdis = ((LPDRAWITEMSTRUCT)lParam);
  1847. if (pdis->CtlType != ODT_MENU) // not from a menu
  1848. hWndChild = pdis->hwndItem;
  1849. else // Status bar control sends this message with type set to ODT_MENU
  1850. if (::IsWindow(pdis->hwndItem))
  1851. hWndChild = pdis->hwndItem;
  1852. }
  1853. break;
  1854. case WM_MEASUREITEM:
  1855. {
  1856. MEASUREITEMSTRUCT* pmis = ((LPMEASUREITEMSTRUCT)lParam);
  1857. if(pmis->CtlType != ODT_MENU) // not from a menu
  1858. hWndChild = GetDlgItem(pmis->CtlID);
  1859. }
  1860. break;
  1861. case WM_COMPAREITEM:
  1862. // Sent only by combo or list box
  1863. hWndChild = GetDlgItem(((LPCOMPAREITEMSTRUCT)lParam)->CtlID);
  1864. break;
  1865. case WM_DELETEITEM:
  1866. // Sent only by combo or list box
  1867. hWndChild = GetDlgItem(((LPDELETEITEMSTRUCT)lParam)->CtlID);
  1868. break;
  1869. case WM_VKEYTOITEM:
  1870. case WM_CHARTOITEM:
  1871. case WM_HSCROLL:
  1872. case WM_VSCROLL:
  1873. hWndChild = (HWND)lParam;
  1874. break;
  1875. case WM_CTLCOLORBTN:
  1876. case WM_CTLCOLORDLG:
  1877. case WM_CTLCOLOREDIT:
  1878. case WM_CTLCOLORLISTBOX:
  1879. case WM_CTLCOLORMSGBOX:
  1880. case WM_CTLCOLORSCROLLBAR:
  1881. case WM_CTLCOLORSTATIC:
  1882. hWndChild = (HWND)lParam;
  1883. break;
  1884. default:
  1885. break;
  1886. }
  1887. if(hWndChild == NULL)
  1888. {
  1889. bHandled = FALSE;
  1890. return 1;
  1891. }
  1892. if (m_bWindowless)
  1893. {
  1894. LRESULT lRes = 0;
  1895. if (m_bInPlaceActive && m_spInPlaceObjectWindowless)
  1896. m_spInPlaceObjectWindowless->OnWindowMessage(OCM__BASE + uMsg, wParam, lParam, &lRes);
  1897. return lRes;
  1898. }
  1899. ATLASSERT(::IsWindow(hWndChild));
  1900. return ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
  1901. }
  1902. STDMETHOD(QueryService)( REFGUID rsid, REFIID riid, void** ppvObj)
  1903. {
  1904. ATLASSERT(ppvObj != NULL);
  1905. if (ppvObj == NULL)
  1906. return E_POINTER;
  1907. *ppvObj = NULL;
  1908. HRESULT hr = E_NOINTERFACE;
  1909. // Try for service on this object
  1910. // No services currently
  1911. // If that failed try to find the service on the outer object
  1912. if (FAILED(hr) && m_spServices)
  1913. hr = m_spServices->QueryService(rsid, riid, ppvObj);
  1914. return hr;
  1915. }
  1916. };
  1917. static LRESULT CALLBACK AtlAxWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1918. {
  1919. switch(uMsg)
  1920. {
  1921. case WM_CREATE:
  1922. {
  1923. // create control from a PROGID in the title
  1924. // This is to make sure drag drop works
  1925. ::OleInitialize(NULL);
  1926. CREATESTRUCT* lpCreate = (CREATESTRUCT*)lParam;
  1927. int nLen = ::GetWindowTextLength(hWnd);
  1928. LPTSTR lpstrName = (LPTSTR)_alloca((nLen + 1) * sizeof(TCHAR));
  1929. ::GetWindowText(hWnd, lpstrName, nLen + 1);
  1930. ::SetWindowText(hWnd, _T(""));
  1931. IAxWinHostWindow* pAxWindow = NULL;
  1932. int nCreateSize = 0;
  1933. if (lpCreate && lpCreate->lpCreateParams)
  1934. nCreateSize = *((WORD*)lpCreate->lpCreateParams);
  1935. HGLOBAL h = GlobalAlloc(GHND, nCreateSize);
  1936. CComPtr<IStream> spStream;
  1937. if (h && nCreateSize)
  1938. {
  1939. BYTE* pBytes = (BYTE*) GlobalLock(h);
  1940. BYTE* pSource = ((BYTE*)(lpCreate->lpCreateParams)) + sizeof(WORD);
  1941. //Align to DWORD
  1942. //pSource += (((~((DWORD)pSource)) + 1) & 3);
  1943. memcpy(pBytes, pSource, nCreateSize);
  1944. GlobalUnlock(h);
  1945. CreateStreamOnHGlobal(h, TRUE, &spStream);
  1946. }
  1947. USES_CONVERSION;
  1948. CComPtr<IUnknown> spUnk;
  1949. HRESULT hRet = AtlAxCreateControlLic(T2COLE(lpstrName), hWnd, spStream, &spUnk, NULL);
  1950. if(FAILED(hRet))
  1951. {
  1952. #ifdef _DEBUG
  1953. LPTSTR pszMsg = NULL;
  1954. ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, hRet, 0, (LPTSTR)&pszMsg, 0, NULL);
  1955. ATLTRACE(atlTraceControls, 0, _T("Control creation failed for '%s'\n"), lpstrName);
  1956. ATLTRACE(atlTraceControls, 0, _T("Error code: 0x%x - %s"), hRet, pszMsg);
  1957. ::LocalFree(pszMsg);
  1958. #endif
  1959. return -1; // abort window creation
  1960. }
  1961. hRet = spUnk->QueryInterface(__uuidof(IAxWinHostWindow), (void**)&pAxWindow);
  1962. if(FAILED(hRet))
  1963. return -1; // abort window creation
  1964. ::SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD_PTR)pAxWindow);
  1965. // Set the control parent style for the AxWindow
  1966. ::SetWindowLong(hWnd, GWL_EXSTYLE, ::GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_CONTROLPARENT);
  1967. // check for control parent style if control has a window
  1968. HWND hWndChild = ::GetWindow(hWnd, GW_CHILD);
  1969. if(hWndChild != NULL)
  1970. {
  1971. DWORD dwExStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE);
  1972. if((dwExStyle & WS_EX_CONTROLPARENT) == 0)
  1973. {
  1974. dwExStyle |= WS_EX_CONTROLPARENT;
  1975. ::SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle);
  1976. }
  1977. }
  1978. // continue with DefWindowProc
  1979. }
  1980. break;
  1981. case WM_NCDESTROY:
  1982. {
  1983. IAxWinHostWindow* pAxWindow = (IAxWinHostWindow*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
  1984. if(pAxWindow != NULL)
  1985. pAxWindow->Release();
  1986. OleUninitialize();
  1987. }
  1988. break;
  1989. default:
  1990. break;
  1991. }
  1992. return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
  1993. }
  1994. static LRESULT CALLBACK AtlAxWindowProc2(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1995. {
  1996. switch(uMsg)
  1997. {
  1998. case WM_CREATE:
  1999. {
  2000. // create control from a PROGID in the title
  2001. // This is to make sure drag drop works
  2002. ::OleInitialize(NULL);
  2003. CREATESTRUCT* lpCreate = (CREATESTRUCT*)lParam;
  2004. int nLen = ::GetWindowTextLength(hWnd);
  2005. LPTSTR lpstrName = (LPTSTR)_alloca((nLen + 1) * sizeof(TCHAR));
  2006. ::GetWindowText(hWnd, lpstrName, nLen + 1);
  2007. ::SetWindowText(hWnd, _T(""));
  2008. IAxWinHostWindowLic* pAxWindow = NULL;
  2009. int nCreateSize = 0;
  2010. if (lpCreate && lpCreate->lpCreateParams)
  2011. nCreateSize = *((WORD*)lpCreate->lpCreateParams);
  2012. // Format of data in lpCreateParams
  2013. // int nCreateSize; // size of Create data in bytes
  2014. // WORD nMsg; //constant used to indicate type of DLGINIT data. See _DialogSplitHelper for values.
  2015. // DWORD dwLen; // Length of data strored for control in DLGINIT format in bytes.
  2016. // DWORD cchLicKey; // Length of licence key in OLECHAR's
  2017. // OLECHAR *szLicKey; // This will be present only if cchLicKey is greater than 0. This is of variable length and will contain cchLicKey OLECHAR's that represent the licence key.
  2018. // The following two fields will be present only if nMsg is WM_OCC_LOADFROMSTREAM_EX or WM_OCC_LOADFROMSTORAGE_EX. If present this information will be ignored since databinding is not supported.
  2019. // ULONG cbDataBinding; // Lenght of databinding information in bytes.
  2020. // BYTE *pbDataBindingInfo // cbDataBinding bytes that contain databinding information
  2021. // BYTE *pbControlData; // Actual control data persisted by the control.
  2022. HGLOBAL h = GlobalAlloc(GHND, nCreateSize);
  2023. CComPtr<IStream> spStream;
  2024. if (h && nCreateSize)
  2025. {
  2026. BYTE* pBytes = (BYTE*) GlobalLock(h);
  2027. BYTE* pSource = ((BYTE*)(lpCreate->lpCreateParams)) + sizeof(WORD);
  2028. //Align to DWORD
  2029. //pSource += (((~((DWORD)pSource)) + 1) & 3);
  2030. memcpy(pBytes, pSource, nCreateSize);
  2031. GlobalUnlock(h);
  2032. CreateStreamOnHGlobal(h, TRUE, &spStream);
  2033. }
  2034. CComBSTR bstrLicKey;
  2035. HRESULT hRet = _DialogSplitHelper::ParseInitData(spStream, &bstrLicKey.m_str);
  2036. if (FAILED(hRet))
  2037. return -1;
  2038. USES_CONVERSION;
  2039. CComPtr<IUnknown> spUnk;
  2040. hRet = AtlAxCreateControlLic(T2COLE(lpstrName), hWnd, spStream, &spUnk, bstrLicKey);
  2041. if(FAILED(hRet))
  2042. {
  2043. #ifdef _DEBUG
  2044. LPTSTR pszMsg = NULL;
  2045. ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, hRet, 0, (LPTSTR)&pszMsg, 0, NULL);
  2046. ATLTRACE(atlTraceControls, 0, _T("Control creation failed for '%s'\n"), lpstrName);
  2047. ATLTRACE(atlTraceControls, 0, _T("Error code: 0x%x - %s"), hRet, pszMsg);
  2048. ::LocalFree(pszMsg);
  2049. #endif
  2050. return -1; // abort window creation
  2051. }
  2052. hRet = spUnk->QueryInterface(__uuidof(IAxWinHostWindowLic), (void**)&pAxWindow);
  2053. if(FAILED(hRet))
  2054. return -1; // abort window creation
  2055. ::SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD_PTR)pAxWindow);
  2056. // Set the control parent style for the AxWindow
  2057. ::SetWindowLong(hWnd, GWL_EXSTYLE, ::GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_CONTROLPARENT);
  2058. // check for control parent style if control has a window
  2059. HWND hWndChild = ::GetWindow(hWnd, GW_CHILD);
  2060. if(hWndChild != NULL)
  2061. {
  2062. DWORD dwExStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE);
  2063. if((dwExStyle & WS_EX_CONTROLPARENT) == 0)
  2064. {
  2065. dwExStyle |= WS_EX_CONTROLPARENT;
  2066. ::SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle);
  2067. }
  2068. }
  2069. // continue with DefWindowProc
  2070. }
  2071. break;
  2072. case WM_NCDESTROY:
  2073. {
  2074. IAxWinHostWindowLic* pAxWindow = (IAxWinHostWindowLic*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
  2075. if(pAxWindow != NULL)
  2076. pAxWindow->Release();
  2077. OleUninitialize();
  2078. }
  2079. break;
  2080. default:
  2081. break;
  2082. }
  2083. return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
  2084. }
  2085. }; //namespace ATL
  2086. #ifndef _ATL_DLL_IMPL
  2087. #ifndef _ATL_DLL
  2088. #define _ATLHOST_IMPL
  2089. #endif
  2090. #endif
  2091. #ifdef _ATLHOST_IMPL
  2092. //#ifndef _ATL_DLL_IMPL
  2093. namespace ATL
  2094. {
  2095. //#endif
  2096. //All exports go here
  2097. inline HRSRC AtlFindResource(HMODULE hModule, LPCSTR lpName, LPCSTR lpType)
  2098. {
  2099. return ::FindResourceA(hModule, lpName, lpType);
  2100. }
  2101. inline HRSRC AtlFindResource(HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType)
  2102. {
  2103. return ::FindResourceW(hModule, lpName, lpType);
  2104. }
  2105. class _AtlDialogBoxIndirectParamHelper
  2106. {
  2107. public :
  2108. typedef INT_PTR ReturnType;
  2109. static ReturnType GetInvalidValue()
  2110. {
  2111. return -1;
  2112. }
  2113. static bool IsValidReturnVal(ReturnType nRet)
  2114. {
  2115. return (nRet != 0 && nRet != -1);
  2116. }
  2117. };
  2118. class _AtlCreateDialogIndirectParamHelper
  2119. {
  2120. public :
  2121. typedef HWND ReturnType;
  2122. static ReturnType GetInvalidValue()
  2123. {
  2124. return NULL;
  2125. }
  2126. static bool IsValidReturnVal(ReturnType nRet)
  2127. {
  2128. return (nRet != 0);
  2129. }
  2130. };
  2131. template <class StringType, class Helper, Helper::ReturnType (WINAPI *pFunc)(HINSTANCE, LPCDLGTEMPLATE, HWND,DLGPROC, LPARAM)>
  2132. Helper::ReturnType AtlAxDialogCreateT(HINSTANCE hInstance, StringType lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, LPARAM dwInitParam)
  2133. {
  2134. AtlAxWinInit();
  2135. Helper::ReturnType nRet = Helper::GetInvalidValue();
  2136. HRSRC hDlg = AtlFindResource(hInstance, lpTemplateName, (StringType)RT_DIALOG);
  2137. if (hDlg != NULL)
  2138. {
  2139. HRSRC hDlgInit = AtlFindResource(hInstance, lpTemplateName, (StringType)_ATL_RT_DLGINIT);
  2140. HGLOBAL hData = NULL;
  2141. BYTE* pInitData = NULL;
  2142. if (hDlgInit)
  2143. {
  2144. hData = ::LoadResource(hInstance, hDlgInit);
  2145. pInitData = (BYTE*) ::LockResource(hData);
  2146. }
  2147. DWORD dwLastError = 0;
  2148. HGLOBAL hResource = LoadResource(hInstance, hDlg);
  2149. if (hResource != NULL)
  2150. {
  2151. DLGTEMPLATE* pDlg = (DLGTEMPLATE*) LockResource(hResource);
  2152. if (pDlg != NULL)
  2153. {
  2154. LPCDLGTEMPLATE lpDialogTemplate;
  2155. lpDialogTemplate = _DialogSplitHelper::SplitDialogTemplate(pDlg, pInitData);
  2156. nRet = (*pFunc)(hInstance, lpDialogTemplate, hWndParent, lpDialogProc, dwInitParam);
  2157. if (!Helper::IsValidReturnVal(nRet))
  2158. {
  2159. dwLastError = ::GetLastError();
  2160. }
  2161. if (lpDialogTemplate != pDlg)
  2162. GlobalFree(GlobalHandle(lpDialogTemplate));
  2163. }
  2164. else
  2165. dwLastError = ::GetLastError();
  2166. }
  2167. else
  2168. dwLastError = ::GetLastError();
  2169. if (dwLastError != 0)
  2170. SetLastError(dwLastError);
  2171. }
  2172. return nRet;
  2173. }
  2174. // fix this once compiler is fixed
  2175. //ATLINLINE ATLAPI_(INT_PTR) AtlAxDialogBoxW(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, LPARAM dwInitParam)
  2176. ATLINLINE INT_PTR __stdcall AtlAxDialogBoxW(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, LPARAM dwInitParam)
  2177. {
  2178. return AtlAxDialogCreateT<LPCWSTR, _AtlDialogBoxIndirectParamHelper, ::DialogBoxIndirectParamW>(
  2179. hInstance, lpTemplateName, hWndParent, lpDialogProc, dwInitParam);
  2180. }
  2181. // fix this once compiler is fixed
  2182. //ATLINLINE ATLAPI_(INT_PTR) AtlAxDialogBoxA(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, LPARAM dwInitParam)
  2183. ATLINLINE INT_PTR __stdcall AtlAxDialogBoxA(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, LPARAM dwInitParam)
  2184. {
  2185. return AtlAxDialogCreateT<LPCSTR, _AtlDialogBoxIndirectParamHelper, ::DialogBoxIndirectParamA>(
  2186. hInstance, lpTemplateName, hWndParent, lpDialogProc, dwInitParam);
  2187. }
  2188. // fix this once compiler is fixed
  2189. //ATLINLINE ATLAPI_(HWND) AtlAxCreateDialogW(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, LPARAM dwInitParam)
  2190. ATLINLINE HWND __stdcall AtlAxCreateDialogW(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, LPARAM dwInitParam)
  2191. {
  2192. return AtlAxDialogCreateT<LPCWSTR, _AtlCreateDialogIndirectParamHelper, CreateDialogIndirectParamW>(
  2193. hInstance, lpTemplateName, hWndParent, lpDialogProc, dwInitParam);
  2194. }
  2195. // fix this once compiler is fixed
  2196. //ATLINLINE ATLAPI_(HWND) AtlAxCreateDialogA(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, LPARAM dwInitParam)
  2197. ATLINLINE HWND __stdcall AtlAxCreateDialogA(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogProc, LPARAM dwInitParam)
  2198. {
  2199. return AtlAxDialogCreateT<LPCSTR, _AtlCreateDialogIndirectParamHelper, CreateDialogIndirectParamA>(
  2200. hInstance, lpTemplateName, hWndParent, lpDialogProc, dwInitParam);
  2201. }
  2202. ATLINLINE ATLAPI AtlAxCreateControl(LPCOLESTR lpszName, HWND hWnd, IStream* pStream, IUnknown** ppUnkContainer)
  2203. {
  2204. return AtlAxCreateControlEx(lpszName, hWnd, pStream, ppUnkContainer, NULL, IID_NULL, NULL);
  2205. }
  2206. ATLINLINE ATLAPI AtlAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd, IStream* pStream,
  2207. IUnknown** ppUnkContainer, IUnknown** ppUnkControl, REFIID iidSink, IUnknown* punkSink)
  2208. {
  2209. return AtlAxCreateControlLicEx(lpszName, hWnd, pStream, ppUnkContainer, ppUnkControl, iidSink, punkSink, NULL);
  2210. }
  2211. ATLINLINE ATLAPI AtlAxCreateControlLic(LPCOLESTR lpszName, HWND hWnd, IStream* pStream, IUnknown** ppUnkContainer, BSTR bstrLic)
  2212. {
  2213. return AtlAxCreateControlLicEx(lpszName, hWnd, pStream, ppUnkContainer, NULL, IID_NULL, NULL, bstrLic);
  2214. }
  2215. ATLINLINE ATLAPI AtlAxCreateControlLicEx(LPCOLESTR lpszName, HWND hWnd, IStream* pStream,
  2216. IUnknown** ppUnkContainer, IUnknown** ppUnkControl, REFIID iidSink, IUnknown* punkSink, BSTR bstrLic)
  2217. {
  2218. AtlAxWinInit();
  2219. HRESULT hr;
  2220. CComPtr<IUnknown> spUnkContainer;
  2221. CComPtr<IUnknown> spUnkControl;
  2222. hr = CAxHostWindow::_CreatorClass::CreateInstance(NULL, __uuidof(IUnknown), (void**)&spUnkContainer);
  2223. if (SUCCEEDED(hr))
  2224. {
  2225. CComPtr<IAxWinHostWindowLic> pAxWindow;
  2226. spUnkContainer->QueryInterface(__uuidof(IAxWinHostWindow), (void**)&pAxWindow);
  2227. CComBSTR bstrName(lpszName);
  2228. hr = pAxWindow->CreateControlLicEx(bstrName, hWnd, pStream, &spUnkControl, iidSink, punkSink, bstrLic);
  2229. }
  2230. if (ppUnkContainer != NULL)
  2231. {
  2232. if (SUCCEEDED(hr))
  2233. {
  2234. *ppUnkContainer = spUnkContainer.p;
  2235. spUnkContainer.p = NULL;
  2236. }
  2237. else
  2238. *ppUnkContainer = NULL;
  2239. }
  2240. if (ppUnkControl != NULL)
  2241. {
  2242. if (SUCCEEDED(hr))
  2243. {
  2244. *ppUnkControl = SUCCEEDED(hr) ? spUnkControl.p : NULL;
  2245. spUnkControl.p = NULL;
  2246. }
  2247. else
  2248. *ppUnkControl = NULL;
  2249. }
  2250. return hr;
  2251. }
  2252. ATLINLINE ATLAPI AtlAxAttachControl(IUnknown* pControl, HWND hWnd, IUnknown** ppUnkContainer)
  2253. {
  2254. AtlAxWinInit();
  2255. if (pControl == NULL)
  2256. return E_INVALIDARG;
  2257. CComPtr<IUnknown> spUnkContainer;
  2258. HRESULT hr = CAxHostWindow::_CreatorClass::CreateInstance(NULL, __uuidof(IUnknown), (void**)&spUnkContainer);
  2259. if (SUCCEEDED(hr))
  2260. {
  2261. CComPtr<IAxWinHostWindow> spAxWindow;
  2262. hr = spUnkContainer->QueryInterface(&spAxWindow);
  2263. if (SUCCEEDED(hr))
  2264. hr = spAxWindow->AttachControl(pControl, hWnd);
  2265. }
  2266. if (ppUnkContainer != NULL)
  2267. {
  2268. *ppUnkContainer = SUCCEEDED(hr) ? spUnkContainer.Detach() : NULL;
  2269. }
  2270. return hr;
  2271. }
  2272. #ifdef _ATL_DLL_IMPL
  2273. // global variable in ATL.DLL to keep track if AtlAxWin window class has been registered in ATL.DLL
  2274. bool __declspec(selectany) bAtlAxWinInitialized;
  2275. #endif
  2276. //This either registers a global class (if AtlAxWinInit is in ATL.DLL)
  2277. // or it registers a local class
  2278. ATLINLINE ATLAPI_(BOOL) AtlAxWinInit()
  2279. {
  2280. CComCritSecLock<CComCriticalSection> lock(_ATLWINMODULE.m_csWindowCreate, false);
  2281. if (FAILED(lock.Lock()))
  2282. {
  2283. ATLTRACE(atlTraceHosting, 0, _T("ERROR : Unable to lock critical section in AtlAxWinInit\n"));
  2284. ATLASSERT(0);
  2285. return FALSE;
  2286. }
  2287. WM_ATLGETHOST = RegisterWindowMessage(_T("WM_ATLGETHOST"));
  2288. WM_ATLGETCONTROL = RegisterWindowMessage(_T("WM_ATLGETCONTROL"));
  2289. WNDCLASSEX wc;
  2290. // first check if the class is already registered
  2291. wc.cbSize = sizeof(WNDCLASSEX);
  2292. BOOL bRet = ::GetClassInfoEx(_AtlBaseModule.GetModuleInstance(), CAxWindow::GetWndClassName(), &wc);
  2293. // register class if not
  2294. if(!bRet)
  2295. {
  2296. wc.cbSize = sizeof(WNDCLASSEX);
  2297. #ifdef _ATL_DLL_IMPL
  2298. wc.style = CS_GLOBALCLASS | CS_DBLCLKS;
  2299. bAtlAxWinInitialized = true;
  2300. #else
  2301. wc.style = CS_DBLCLKS;
  2302. #endif
  2303. wc.lpfnWndProc = AtlAxWindowProc;
  2304. wc.cbClsExtra = 0;
  2305. wc.cbWndExtra = 0;
  2306. wc.hInstance = _AtlBaseModule.GetModuleInstance();
  2307. wc.hIcon = NULL;
  2308. wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
  2309. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  2310. wc.lpszMenuName = NULL;
  2311. wc.lpszClassName = CAxWindow::GetWndClassName();
  2312. wc.hIconSm = NULL;
  2313. bRet = (BOOL)::RegisterClassEx(&wc);
  2314. }
  2315. if (bRet)
  2316. {
  2317. // first check if the class is already registered
  2318. memset(&wc, 0, sizeof(WNDCLASSEX));
  2319. wc.cbSize = sizeof(WNDCLASSEX);
  2320. bRet = ::GetClassInfoEx(_AtlBaseModule.GetModuleInstance(), CAxWindow2::GetWndClassName(), &wc);
  2321. // register class if not
  2322. if(!bRet)
  2323. {
  2324. wc.cbSize = sizeof(WNDCLASSEX);
  2325. #ifdef _ATL_DLL_IMPL
  2326. wc.style = CS_GLOBALCLASS | CS_DBLCLKS;
  2327. #else
  2328. wc.style = CS_DBLCLKS;
  2329. #endif
  2330. wc.lpfnWndProc = AtlAxWindowProc2;
  2331. wc.cbClsExtra = 0;
  2332. wc.cbWndExtra = 0;
  2333. wc.hInstance = _AtlBaseModule.GetModuleInstance();
  2334. wc.hIcon = NULL;
  2335. wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
  2336. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  2337. wc.lpszMenuName = NULL;
  2338. wc.lpszClassName = CAxWindow2::GetWndClassName();
  2339. wc.hIconSm = NULL;
  2340. bRet = (BOOL)::RegisterClassEx(&wc);
  2341. }
  2342. }
  2343. return bRet;
  2344. }
  2345. ATLINLINE ATLAPI AtlAxGetControl(HWND h, IUnknown** pp)
  2346. {
  2347. ATLASSERT(WM_ATLGETCONTROL != 0);
  2348. if (pp == NULL)
  2349. return E_POINTER;
  2350. *pp = (IUnknown*)SendMessage(h, WM_ATLGETCONTROL, 0, 0);
  2351. return (*pp) ? S_OK : E_FAIL;
  2352. }
  2353. ATLINLINE ATLAPI AtlAxGetHost(HWND h, IUnknown** pp)
  2354. {
  2355. ATLASSERT(WM_ATLGETHOST != 0);
  2356. if (pp == NULL)
  2357. return E_POINTER;
  2358. *pp = (IUnknown*)SendMessage(h, WM_ATLGETHOST, 0, 0);
  2359. return (*pp) ? S_OK : E_FAIL;
  2360. }
  2361. //#ifndef _ATL_DLL_IMPL
  2362. }; //namespace ATL
  2363. //#endif
  2364. //Prevent pulling in second time
  2365. #undef _ATLHOST_IMPL
  2366. #endif // _ATLHOST_IMPL
  2367. #ifndef _ATL_NO_PRAGMA_WARNINGS
  2368. #pragma warning (pop)
  2369. #endif //!_ATL_NO_PRAGMA_WARNINGS
  2370. // Review : Temp
  2371. #ifdef _ATL_NO_AUTOMATIC_NAMESPACE
  2372. using ATL::AtlAxWinInit;
  2373. #endif
  2374. #endif // __ATLHOST_H__