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