home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2000 May / MICD_2000_05.iso / CBuilder5 / INSTALL / DATA1.CAB / Program_Built_Files / Include / Atl / atlhost.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-01  |  72.8 KB  |  2,599 lines

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