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

453 lines
18 KiB

#ifndef __AXHOST_H
#define __AXHOST_H
////////////////////////////////////////////////////////////////////////////////
#define FORWARD_IDOCHOSTUIHANDLER_INIT \
HRESULT hr; \
CComPtr<IDocHostUIHandler> spHost; \
\
hr = AskHostForDocHostUIHandler( spHost );
#define FORWARD_IDOCHOSTUIHANDLER( method ) \
FORWARD_IDOCHOSTUIHANDLER_INIT; \
if(SUCCEEDED(hr)) \
{ \
hr = spHost->method(); if(hr != E_NOTIMPL) return hr; \
} \
return CAxHostWindow::method();
#define FORWARD_IDOCHOSTUIHANDLER_1( method, arg1 ) \
FORWARD_IDOCHOSTUIHANDLER_INIT; \
if(SUCCEEDED(hr)) \
{ \
hr = spHost->method( arg1 ); if(hr != E_NOTIMPL) return hr; \
} \
return CAxHostWindow::method( arg1 );
#define FORWARD_IDOCHOSTUIHANDLER_2( method, arg1, arg2 ) \
FORWARD_IDOCHOSTUIHANDLER_INIT; \
if(SUCCEEDED(hr)) \
{ \
hr = spHost->method( arg1, arg2 ); if(hr != E_NOTIMPL) return hr; \
} \
return CAxHostWindow::method( arg1, arg2 );
#define FORWARD_IDOCHOSTUIHANDLER_3( method, arg1, arg2, arg3 ) \
FORWARD_IDOCHOSTUIHANDLER_INIT; \
if(SUCCEEDED(hr)) \
{ \
hr = spHost->method( arg1, arg2, arg3 ); if(hr != E_NOTIMPL) return hr; \
} \
return CAxHostWindow::method( arg1, arg2, arg3 );
#define FORWARD_IDOCHOSTUIHANDLER_4( method, arg1, arg2, arg3, arg4 ) \
FORWARD_IDOCHOSTUIHANDLER_INIT; \
if(SUCCEEDED(hr)) \
{ \
hr = spHost->method( arg1, arg2, arg3, arg4 ); if(hr != E_NOTIMPL) return hr; \
} \
return CAxHostWindow::method( arg1, arg2, arg3, arg4 );
#define FORWARD_IDOCHOSTUIHANDLER_5( method, arg1, arg2, arg3, arg4, arg5 ) \
FORWARD_IDOCHOSTUIHANDLER_INIT; \
if(SUCCEEDED(hr)) \
{ \
hr = spHost->method( arg1, arg2, arg3, arg4, arg5 ); if(hr != E_NOTIMPL) return hr; \
} \
return CAxHostWindow::method( arg1, arg2, arg3, arg4, arg5 );
////////////////////////////////////////////////////////////////////////////////
ATLAPI MarsAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd, IStream* pStream,
IUnknown** ppUnkContainer, IUnknown** ppUnkControl, REFIID iidSink, IUnknown* punkSink);
ATLAPI MarsAxCreateControl(LPCOLESTR lpszName, HWND hWnd, IStream* pStream, IUnknown** ppUnkContainer);
class CMarsPanel;
class CMarsAxHostWindow :
public CAxHostWindow,
public IOleCommandTarget
{
public:
~CMarsAxHostWindow();
BEGIN_COM_MAP(CMarsAxHostWindow)
COM_INTERFACE_ENTRY(IOleCommandTarget)
COM_INTERFACE_ENTRY_CHAIN(CAxHostWindow)
END_COM_MAP()
DECLARE_POLY_AGGREGATABLE(CMarsAxHostWindow)
BEGIN_MSG_MAP(CMarsAxHostWindow)
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging)
MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
CHAIN_MSG_MAP(CAxHostWindow);
END_MSG_MAP()
LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnWindowPosChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
// IObjectWithSite overrides
STDMETHOD(SetSite)(IUnknown* pUnkSite);
// IOleInPlaceSite overrides
STDMETHOD(OnUIActivate)();
// IOleControlSite overrides
STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, DWORD grfModifiers);
// IDispatch overrides
STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS *pdispparams, VARIANT *pvarResult,
EXCEPINFO *pexcepinfo, UINT *puArgErr);
// IDocHostUIHandler overrides
HRESULT AskHostForDocHostUIHandler( CComPtr<IDocHostUIHandler>& spHost );
STDMETHOD(ShowContextMenu)(DWORD dwID, POINT* pptPosition, IUnknown* pCommandTarget, IDispatch* pDispatchObjectHit)
{
FORWARD_IDOCHOSTUIHANDLER_4( ShowContextMenu, dwID, pptPosition, pCommandTarget, pDispatchObjectHit );
}
STDMETHOD(GetHostInfo)(DOCHOSTUIINFO* pInfo)
{
FORWARD_IDOCHOSTUIHANDLER_1( GetHostInfo, pInfo );
}
STDMETHOD(ShowUI)(DWORD dwID, IOleInPlaceActiveObject* pActiveObject, IOleCommandTarget* pCommandTarget, IOleInPlaceFrame* pFrame, IOleInPlaceUIWindow* pDoc)
{
FORWARD_IDOCHOSTUIHANDLER_5( ShowUI, dwID, pActiveObject, pCommandTarget, pFrame, pDoc );
}
STDMETHOD(HideUI)()
{
FORWARD_IDOCHOSTUIHANDLER( HideUI );
}
STDMETHOD(UpdateUI)()
{
FORWARD_IDOCHOSTUIHANDLER( UpdateUI );
}
STDMETHOD(EnableModeless)(BOOL fEnable)
{
FORWARD_IDOCHOSTUIHANDLER_1( EnableModeless, fEnable );
}
STDMETHOD(OnDocWindowActivate)(BOOL fActivate)
{
FORWARD_IDOCHOSTUIHANDLER_1( OnDocWindowActivate, fActivate );
}
STDMETHOD(OnFrameWindowActivate)(BOOL fActivate)
{
FORWARD_IDOCHOSTUIHANDLER_1( OnFrameWindowActivate, fActivate );
}
STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow* pUIWindow, BOOL fFrameWindow)
{
FORWARD_IDOCHOSTUIHANDLER_3( ResizeBorder, prcBorder, pUIWindow, fFrameWindow );
}
STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, const GUID* pguidCmdGroup, DWORD nCmdID)
{
FORWARD_IDOCHOSTUIHANDLER_3( TranslateAccelerator, lpMsg, pguidCmdGroup, nCmdID );
}
STDMETHOD(GetOptionKeyPath)(BSTR* pbstrKey, DWORD dwReserved)
{
FORWARD_IDOCHOSTUIHANDLER_2( GetOptionKeyPath, pbstrKey, dwReserved );
}
STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget, IDropTarget** ppDropTarget)
{
FORWARD_IDOCHOSTUIHANDLER_2( GetDropTarget, pDropTarget, ppDropTarget );
}
STDMETHOD(GetExternal)(IDispatch** ppDispatch)
{
FORWARD_IDOCHOSTUIHANDLER_1( GetExternal, ppDispatch );
}
STDMETHOD(TranslateUrl)(DWORD dwTranslate, OLECHAR* pchURLIn, OLECHAR** ppchURLOut)
{
FORWARD_IDOCHOSTUIHANDLER_3( TranslateUrl, dwTranslate, pchURLIn, ppchURLOut );
}
STDMETHOD(FilterDataObject)(IDataObject* pDO, IDataObject** ppDORet)
{
FORWARD_IDOCHOSTUIHANDLER_2( FilterDataObject, pDO, ppDORet );
}
////////////////////
// IOleInPlaceSite overrides
STDMETHOD(GetWindowContext)(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo);
// IOleCommandTarget methods
STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[], OLECMDTEXT *pcmdtext);
STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut);
private:
CComClassPtr<CMarsPanel> m_spMarsPanel;
};
template <class TBase = CWindow>
class CMarsAxWindowT : public TBase
{
public:
// Constructors
CMarsAxWindowT(HWND hWnd = NULL) : TBase(hWnd)
{ }
CMarsAxWindowT< TBase >& operator=(HWND hWnd)
{
m_hWnd = hWnd;
return *this;
}
// Attributes
static LPCTSTR GetWndClassName()
{
return _T("PCHAxWin");
}
// Operations
HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
DWORD dwStyle = 0, DWORD dwExStyle = 0,
UINT nID = 0, LPVOID lpCreateParam = NULL)
{
return CWindow::Create(GetWndClassName(), hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
}
HWND Create(HWND hWndParent, LPRECT lpRect = NULL, LPCTSTR szWindowName = NULL,
DWORD dwStyle = 0, DWORD dwExStyle = 0,
HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
{
return CWindow::Create(GetWndClassName(), hWndParent, lpRect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
}
HRESULT QueryHost(REFIID iid, void** ppUnk)
{
ATLASSERT(ppUnk != NULL);
HRESULT hr;
*ppUnk = NULL;
CComPtr<IUnknown> spUnk;
hr = AtlAxGetHost(m_hWnd, &spUnk);
if (SUCCEEDED(hr))
hr = spUnk->QueryInterface(iid, ppUnk);
return hr;
}
template <class Q>
HRESULT QueryHost(Q** ppUnk)
{
return QueryHost(__uuidof(Q), (void**)ppUnk);
}
HRESULT QueryControl(REFIID iid, void** ppUnk)
{
ATLASSERT(ppUnk != NULL);
HRESULT hr;
*ppUnk = NULL;
CComPtr<IUnknown> spUnk;
hr = AtlAxGetControl(m_hWnd, &spUnk);
if (SUCCEEDED(hr))
hr = spUnk->QueryInterface(iid, ppUnk);
return hr;
}
template <class Q>
HRESULT QueryControl(Q** ppUnk)
{
return QueryControl(__uuidof(Q), (void**)ppUnk);
}
HRESULT SetExternalDispatch(IDispatch* pDisp)
{
HRESULT hr;
CComPtr<IAxWinHostWindow> spHost;
hr = QueryHost(IID_IAxWinHostWindow, (void**)&spHost);
if (SUCCEEDED(hr))
hr = spHost->SetExternalDispatch(pDisp);
return hr;
}
HRESULT SetExternalUIHandler(IDocHostUIHandlerDispatch* pUIHandler)
{
HRESULT hr;
CComPtr<IAxWinHostWindow> spHost;
hr = QueryHost(IID_IAxWinHostWindow, (void**)&spHost);
if (SUCCEEDED(hr))
hr = spHost->SetExternalUIHandler(pUIHandler);
return hr;
}
};
typedef CMarsAxWindowT<CWindow> CMarsAxWindow;
static LRESULT CALLBACK MarsAxWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CREATE:
{
// create control from a PROGID in the title
// This is to make sure drag drop works
::OleInitialize(NULL);
CREATESTRUCT* lpCreate = (CREATESTRUCT*)lParam;
int nLen = ::GetWindowTextLength(hWnd);
LPTSTR lpstrName = (LPTSTR)_alloca((nLen + 1) * sizeof(TCHAR));
::GetWindowText(hWnd, lpstrName, nLen + 1);
::SetWindowText(hWnd, _T(""));
IAxWinHostWindow* pAxWindow = NULL;
int nCreateSize = 0;
if (lpCreate && lpCreate->lpCreateParams)
nCreateSize = *((WORD*)lpCreate->lpCreateParams);
CComPtr<IStream> spStream;
if (nCreateSize)
{
HGLOBAL h = GlobalAlloc(GHND, nCreateSize);
if (h)
{
BYTE* pBytes = (BYTE*) GlobalLock(h);
BYTE* pSource = ((BYTE*)(lpCreate->lpCreateParams)) + sizeof(WORD);
//Align to DWORD
//pSource += (((~((DWORD)pSource)) + 1) & 3);
memcpy(pBytes, pSource, nCreateSize);
GlobalUnlock(h);
CreateStreamOnHGlobal(h, TRUE, &spStream);
}
}
USES_CONVERSION;
CComPtr<IUnknown> spUnk;
HRESULT hRet = MarsAxCreateControl(T2COLE(lpstrName), hWnd, spStream, &spUnk);
if(FAILED(hRet))
return -1; // abort window creation
hRet = spUnk->QueryInterface(IID_IAxWinHostWindow, (void**)&pAxWindow);
if(FAILED(hRet))
return -1; // abort window creation
::SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG_PTR)pAxWindow );
// check for control parent style if control has a window
HWND hWndChild = ::GetWindow(hWnd, GW_CHILD);
if(hWndChild != NULL)
{
if(::GetWindowLong(hWndChild, GWL_EXSTYLE) & WS_EX_CONTROLPARENT)
{
DWORD dwExStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE);
dwExStyle |= WS_EX_CONTROLPARENT;
::SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle);
}
}
// continue with DefWindowProc
}
break;
case WM_NCDESTROY:
{
IAxWinHostWindow* pAxWindow = (IAxWinHostWindow*)::GetWindowLongPtr( hWnd, GWLP_USERDATA );
if(pAxWindow != NULL)
pAxWindow->Release();
OleUninitialize();
}
break;
default:
break;
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
ATLINLINE ATLAPI_(BOOL) MarsAxWinInit()
{
EnterCriticalSection(&_Module.m_csWindowCreate);
WM_ATLGETHOST = RegisterWindowMessage(_T("WM_ATLGETHOST"));
WM_ATLGETCONTROL = RegisterWindowMessage(_T("WM_ATLGETCONTROL"));
WNDCLASSEX wc;
// first check if the class is already registered
wc.cbSize = sizeof(WNDCLASSEX);
BOOL bRet = ::GetClassInfoEx(_Module.GetModuleInstance(), CMarsAxWindow::GetWndClassName(), &wc);
// register class if not
if(!bRet)
{
wc.cbSize = sizeof(WNDCLASSEX);
#ifdef _ATL_DLL_IMPL
wc.style = CS_GLOBALCLASS;
#else
wc.style = 0;
#endif
wc.lpfnWndProc = MarsAxWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = _Module.GetModuleInstance();
wc.hIcon = NULL;
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = CMarsAxWindow::GetWndClassName();
wc.hIconSm = NULL;
bRet = (BOOL)::RegisterClassEx(&wc);
}
LeaveCriticalSection(&_Module.m_csWindowCreate);
return bRet;
}
ATLINLINE ATLAPI MarsAxCreateControl(LPCOLESTR lpszName, HWND hWnd, IStream* pStream, IUnknown** ppUnkContainer)
{
return MarsAxCreateControlEx(lpszName, hWnd, pStream, ppUnkContainer, NULL, IID_NULL, NULL);
}
ATLINLINE ATLAPI MarsAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd, IStream * pStream,
IUnknown** ppUnkContainer, IUnknown** ppUnkControl, REFIID iidSink, IUnknown* punkSink)
{
MarsAxWinInit();
HRESULT hr;
CComPtr<IUnknown> spUnkContainer;
CComPtr<IUnknown> spUnkControl;
hr = CMarsAxHostWindow::_CreatorClass::CreateInstance(NULL, IID_IUnknown, (void**)&spUnkContainer);
if (SUCCEEDED(hr))
{
CComPtr<IAxWinHostWindow> pAxWindow;
spUnkContainer->QueryInterface(IID_IAxWinHostWindow, (void**)&pAxWindow);
CComBSTR bstrName(lpszName);
hr = pAxWindow->CreateControlEx(bstrName, hWnd, pStream, &spUnkControl, iidSink, punkSink);
}
if (ppUnkContainer != NULL)
{
if (SUCCEEDED(hr))
{
*ppUnkContainer = spUnkContainer.p;
spUnkContainer.p = NULL;
}
else
*ppUnkContainer = NULL;
}
if (ppUnkControl != NULL)
{
if (SUCCEEDED(hr))
{
*ppUnkControl = SUCCEEDED(hr) ? spUnkControl.p : NULL;
spUnkControl.p = NULL;
}
else
*ppUnkControl = NULL;
}
return hr;
}
HRESULT GetDoc2FromAxWindow(CMarsAxWindow *pAxWin, IHTMLDocument2 **ppDoc2);
HRESULT GetWin2FromDoc2(IHTMLDocument2 *pDoc2, IHTMLWindow2 **ppWin2);
HRESULT GetWin2FromAxWindow(CMarsAxWindow *pAxWin, IHTMLWindow2 **ppWin2);
HRESULT GetControlWindow(CMarsAxWindow *pAxWin, HWND *phwnd);
#endif