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.

2598 lines
70 KiB

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