最近一直都在研究关于有界面的组件如何做为主框架的子view显示出来, 终于有一些心得,在此把它贴出来供高人指点.并分享成果,难免有错误之处,因为我的水平只有这么多.
任何组件都会存在唯一的CLSID,此组件也一样存在这个ID,在工程目录下面找到和类名相同的HTM文件,运行它就是发现就是组件的界面,功能也是组件里写的功能.HTML文件里是可以写脚本的,所以也可以把组件的事件同时抛出来,就可以使用WebBrowser2封装的容器显示此页面.由于组件在系统里也会以HTML页面的形式呈现出来,并在WebBrowser2里显示,其实也就没有必要使用ATL做界面了,只需要使用HTML+脚本写出一个界面,使用此容器就可以在VC的框架里正确的运行,从而实现VC和脚本的相互调用.(有关脚本和VC的相互调用参考其它文档)
容器的代码如下:
IDL
import
"
oaidl.idl
"
;
import " ocidl.idl " ;
import " atliface.idl " ;
#include " olectl.h "
[
object ,
uuid(0BB8B6DB - 52F9 - 4C2A - BB04 - 5150B8FE5841),
dual,
helpstring( " IATLOpener Interface " ),
pointer_default(unique)
]
interface IATLOpener : IDispatch // 对外的接口
... {
[id(1), helpstring("method OpenURL")] HRESULT OpenURL(BSTR bstrURL);
[id(2), helpstring("method OpenHTML")] HRESULT OpenHTML(BSTR bstrURL);
} ;
[
object , dual,
uuid(8F1C3679 - 9EED - 419A - 9D42 - C1B7C60E2F5B),
helpstring( " IATLOpenerUI Interface " ),
pointer_default(unique)
]
interface IATLOpenerUI : IDocHostUIHandlerDispatch // 容器有滚动条,对脚本的接口
... {
// Example method that will be called by the HTML
[id(1), helpstring("method OnClick")] HRESULT OnClick([in]IDispatch* pdispBody, [in]VARIANT varColor);
[id(2), helpstring("method fireEvent")] HRESULT fireEvent(BSTR bstrID, BSTR bstrValue);
} ;
[
uuid(370F70AC - 6AAA - 41E9 - 980F - 14431FECBDB1),
version( 1.0 ),
helpstring( " ATLMaskWrapper 1.0 Type Library " )
]
library ATLMASKWRAPPERLib
... {
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[
uuid(0E0D5320-125B-4078-B002-544CC536CEF5),
helpstring("_IATLOpenerEvents Interface")
]
dispinterface _IATLOpenerEvents
...{
properties:
methods:
[id(1), helpstring("method OnEvent")] HRESULT OnEvent(BSTR bstrID,BSTR bstrValue);
[id(2), helpstring("method OnEvent2")] HRESULT OnEvent2(BSTR bstrID,BSTR bstrValue1,BSTR bstrValue2);
[id(3), helpstring("method OnEvent3")] HRESULT OnEvent3(BSTR bstrID,BSTR bstrValue1,BSTR bstrValue2,BSTR bstrValue3);
[id(4), helpstring("method OnSetFrameTitle")] HRESULT OnSetFrameTitle(BSTR bstrFrameTitle);
};
[
uuid(4B9529DA-1FE1-49AC-AD51-9EAA66C97351),
helpstring("ATLOpener Class")
]
coclass ATLOpener
...{
[default] interface IATLOpener;
[default, source] dispinterface _IATLOpenerEvents;
interface IATLOpenerUI;
};
} ;
import " ocidl.idl " ;
import " atliface.idl " ;
#include " olectl.h "
[
object ,
uuid(0BB8B6DB - 52F9 - 4C2A - BB04 - 5150B8FE5841),
dual,
helpstring( " IATLOpener Interface " ),
pointer_default(unique)
]
interface IATLOpener : IDispatch // 对外的接口
... {
[id(1), helpstring("method OpenURL")] HRESULT OpenURL(BSTR bstrURL);
[id(2), helpstring("method OpenHTML")] HRESULT OpenHTML(BSTR bstrURL);
} ;
[
object , dual,
uuid(8F1C3679 - 9EED - 419A - 9D42 - C1B7C60E2F5B),
helpstring( " IATLOpenerUI Interface " ),
pointer_default(unique)
]
interface IATLOpenerUI : IDocHostUIHandlerDispatch // 容器有滚动条,对脚本的接口
... {
// Example method that will be called by the HTML
[id(1), helpstring("method OnClick")] HRESULT OnClick([in]IDispatch* pdispBody, [in]VARIANT varColor);
[id(2), helpstring("method fireEvent")] HRESULT fireEvent(BSTR bstrID, BSTR bstrValue);
} ;
[
uuid(370F70AC - 6AAA - 41E9 - 980F - 14431FECBDB1),
version( 1.0 ),
helpstring( " ATLMaskWrapper 1.0 Type Library " )
]
library ATLMASKWRAPPERLib
... {
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[
uuid(0E0D5320-125B-4078-B002-544CC536CEF5),
helpstring("_IATLOpenerEvents Interface")
]
dispinterface _IATLOpenerEvents
...{
properties:
methods:
[id(1), helpstring("method OnEvent")] HRESULT OnEvent(BSTR bstrID,BSTR bstrValue);
[id(2), helpstring("method OnEvent2")] HRESULT OnEvent2(BSTR bstrID,BSTR bstrValue1,BSTR bstrValue2);
[id(3), helpstring("method OnEvent3")] HRESULT OnEvent3(BSTR bstrID,BSTR bstrValue1,BSTR bstrValue2,BSTR bstrValue3);
[id(4), helpstring("method OnSetFrameTitle")] HRESULT OnSetFrameTitle(BSTR bstrFrameTitle);
};
[
uuid(4B9529DA-1FE1-49AC-AD51-9EAA66C97351),
helpstring("ATLOpener Class")
]
coclass ATLOpener
...{
[default] interface IATLOpener;
[default, source] dispinterface _IATLOpenerEvents;
interface IATLOpenerUI;
};
} ;
头文件
#ifndef __ATLOPENER_H_
#define __ATLOPENER_H_
#include " resource.h " // main symbols
#include < atlctl.h >
#include < MSHTMCID.H >
#include < MSHTMHST.h >
#include " ATLMaskWrapperCP.h "
/**/ /////
// CATLOpener
class ATL_NO_VTABLE CATLOpener :
public CComObjectRootEx < CComSingleThreadModel > ,
public IDispatchImpl < IATLOpener, & IID_IATLOpener, & LIBID_ATLMASKWRAPPERLib > ,
public IDispatchImpl < IATLOpenerUI, & IID_IATLOpenerUI, & LIBID_ATLMASKWRAPPERLib > ,
public CComControl < CATLOpener > ,
public IPersistStreamInitImpl < CATLOpener > ,
public IOleControlImpl < CATLOpener > ,
public IOleObjectImpl < CATLOpener > ,
public IOleInPlaceActiveObjectImpl < CATLOpener > ,
public IViewObjectExImpl < CATLOpener > ,
public IOleInPlaceObjectWindowlessImpl < CATLOpener > ,
public ISupportErrorInfo,
public IConnectionPointContainerImpl < CATLOpener > ,
public CComCoClass < CATLOpener, & CLSID_ATLOpener > ,
public IProvideClassInfo2Impl <& CLSID_ATLOpener, & DIID__IATLOpenerEvents, & LIBID_ATLMASKWRAPPERLib > ,
public CProxy_IATLOpenerEvents < CATLOpener > ,
public IObjectSafetyImpl < CATLOpener, INTERFACESAFE_FOR_UNTRUSTED_CALLER >
... {
public:
CATLOpener()
...{
m_bWindowOnly = TRUE;
HRESULT hr =CoInitialize(NULL);
}
~CATLOpener()
...{
CoUninitialize();
}
BEGIN_CATEGORY_MAP(CATLOpener)
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
END_CATEGORY_MAP()
DECLARE_REGISTRY_RESOURCEID(IDR_ATLOPENER)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CATLOpener)
COM_INTERFACE_ENTRY(IATLOpener)
COM_INTERFACE_ENTRY(IATLOpenerUI)
COM_INTERFACE_ENTRY2(IDispatch, IATLOpener)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObject)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()
BEGIN_PROP_MAP(CATLOpener)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
// Example entries
// PROP_ENTRY("Property Description", dispid, clsid)
// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()
BEGIN_CONNECTION_POINT_MAP(CATLOpener)
CONNECTION_POINT_ENTRY(DIID__IATLOpenerEvents)
END_CONNECTION_POINT_MAP()
BEGIN_MSG_MAP(CATLOpener)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
CHAIN_MSG_MAP(CComControl<CATLOpener>)
END_MSG_MAP()
// Handler prototypes:
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
...{
static const IID* arr[] =
...{
&IID_IATLOpener,
};
for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
...{
if (InlineIsEqualGUID(*arr[i], riid))
return S_OK;
}
return S_FALSE;
}
// IViewObjectEx
DECLARE_VIEW_STATUS(0)
// IDispatch 一定要重载,否则脚本找不到接口
public:
STDMETHOD (GetIDsOfNames) (REFIID riid,
LPOLESTR* rgszNames,
UINT cNames,
LCID lcid,
DISPID* rgdispid);
STDMETHOD (Invoke) (DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pdispparams,
VARIANT* pvarResult,
EXCEPINFO* pexcepinfo,
UINT* puArgErr);
// IATLOpener
public:
STDMETHOD(OpenURL)(BSTR bstrURL);
// IATLOpenerUI
public:
// Example method called by the HTML to change the <BODY> background color
STDMETHOD(OnClick)(IDispatch* pdispBody, VARIANT varColor);
public:
LRESULT OnCreate(UINT /**//*uMsg*/, WPARAM /**//*wParam*/, LPARAM /**//*lParam*/, BOOL& /**//*bHandled*/);
public:
STDMETHOD(fireEvent)(BSTR bstrID, BSTR bstrValue);
CComPtr<IWebBrowser2> m_spBrowser;
// IDocHostUIHandlerDispatch
public:
STDMETHOD(OpenHTML)(BSTR bstrURL);
STDMETHOD (ShowContextMenu) (
/**//* [in] */ DWORD dwID,
/**//* [in] */ DWORD x,
/**//* [in] */ DWORD y,
/**//* [in] */ IUnknown *pcmdTarget,
/**//* [in] */ IDispatch *pdispReserved,
/**//* [retval][out] */ HRESULT *dwRetVal)
...{
#define IDR_BROWSE_CONTEXT_MENU 24641
#define IDM_REFRESH2 6042
#define IDM_SAVEASDESKTOPITEM 2278
#define IDM_SEPARATOR 0
#define IDM_SEPARATOR2 6047
HRESULT hr;
HINSTANCE hinstSHDOCLC;
HWND hwnd;
HMENU hMenuParent, hMenu;
CComPtr<IOleCommandTarget> spCT;
CComPtr<IOleWindow> spWnd;
MENUITEMINFO mii = ...{0};
CComVariant var, var1, var2;
hr = pcmdTarget->QueryInterface(IID_IOleCommandTarget, reinterpret_cast< void ** > (&spCT));
hr = spCT->QueryInterface(IID_IOleWindow, reinterpret_cast< void ** > (&spWnd));
hr = spWnd->GetWindow(&hwnd);
hinstSHDOCLC = LoadLibrary(TEXT("SHDOCLC.DLL"));
if (hinstSHDOCLC == NULL)
...{
// Error loading module -- fail as securely as possible
return S_FALSE;
}
hMenuParent = LoadMenu(hinstSHDOCLC,
MAKEINTRESOURCE(IDR_BROWSE_CONTEXT_MENU));
if (dwID == 5) //anchor
hMenu = GetSubMenu(hMenuParent, static_cast< int > (0));
else
hMenu = GetSubMenu(hMenuParent, static_cast< int > (dwID));
// Remove View Source
DeleteMenu(hMenu, IDM_REGISTRYREFRESH, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_REFRESH, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_REFRESH2, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_PROPERTIES, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_ADDFAVORITES, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_CREATESHORTCUT, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_VIEWSOURCE, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_LANGUAGE, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_GOBACKWARD, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_GOFORWARD, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_SAVEBACKGROUND, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_SETWALLPAPER, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_COPYBACKGROUND, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_SAVEASDESKTOPITEM, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_PRINT, MF_BYCOMMAND);
int iItemCount = GetMenuItemCount(hMenu)-1;
for(int i=iItemCount; i>=0; i--)
...{
if(GetMenuItemID(hMenu,i) == IDM_SEPARATOR || GetMenuItemID(hMenu,i) == IDM_SEPARATOR2)
...{
if(i==0)
DeleteMenu(hMenu, i, MF_BYPOSITION);
else if(GetMenuItemID(hMenu,i-1) == IDM_SEPARATOR || GetMenuItemID(hMenu,i-1) == IDM_SEPARATOR2)
DeleteMenu(hMenu, i, MF_BYPOSITION);
}
}
iItemCount = GetMenuItemCount(hMenu)-1;
if(GetMenuItemID(hMenu,iItemCount) == IDM_SEPARATOR || GetMenuItemID(hMenu,iItemCount) == IDM_SEPARATOR2)
DeleteMenu(hMenu, iItemCount, MF_BYPOSITION);
// Show shortcut menu
int iSelection = ::TrackPopupMenu(hMenu,
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON,
x,
y,
0,
hwnd,
(RECT*)NULL);
// Send selected shortcut menu item command to shell
LRESULT lr = ::SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(LOWORD(iSelection), 0x0), 0);
::DestroyMenu( hMenuParent );
FreeLibrary(hinstSHDOCLC);
if (iSelection != 31) //if not select all
...{
SetFocus();
}
//--------
*dwRetVal = S_OK;
return S_OK;
}
STDMETHOD (GetHostInfo) (
/**//* [out][in] */ DWORD *pdwFlags,
/**//* [out][in] */ DWORD *pdwDoubleClick)
...{
return E_NOTIMPL;
}
STDMETHOD (ShowUI) (
/**//* [in] */ DWORD dwID,
/**//* [in] */ IUnknown *pActiveObject,
/**//* [in] */ IUnknown *pCommandTarget,
/**//* [in] */ IUnknown *pFrame,
/**//* [in] */ IUnknown *pDoc,
/**//* [retval][out] */ HRESULT *dwRetVal)
...{
return E_NOTIMPL;
}
STDMETHOD (HideUI) (void)
...{
return E_NOTIMPL;
}
STDMETHOD (UpdateUI) (void)
...{
return E_NOTIMPL;
}
STDMETHOD (EnableModeless) (
/**//* [in] */ VARIANT_BOOL fEnable)
...{
return E_NOTIMPL;
}
STDMETHOD (OnDocWindowActivate) (
/**//* [in] */ VARIANT_BOOL fActivate)
...{
return E_NOTIMPL;
}
STDMETHOD (OnFrameWindowActivate) (
/**//* [in] */ VARIANT_BOOL fActivate)
...{
return E_NOTIMPL;
}
STDMETHOD (ResizeBorder) (
/**//* [in] */ long left,
/**//* [in] */ long top,
/**//* [in] */ long right,
/**//* [in] */ long bottom,
/**//* [in] */ IUnknown *pUIWindow,
/**//* [in] */ VARIANT_BOOL fFrameWindow)
...{
return E_NOTIMPL;
}
STDMETHOD (TranslateAccelerator) (
/**//* [in] */ DWORD hWnd,
/**//* [in] */ DWORD nMessage,
/**//* [in] */ DWORD wParam,
/**//* [in] */ DWORD lParam,
/**//* [in] */ BSTR bstrGuidCmdGroup,
/**//* [in] */ DWORD nCmdID,
/**//* [retval][out] */ HRESULT *dwRetVal)
...{
return E_NOTIMPL;
}
STDMETHOD (GetOptionKeyPath) (
/**//* [out] */ BSTR *pbstrKey,
/**//* [in] */ DWORD dw)
...{
return E_NOTIMPL;
}
STDMETHOD (GetDropTarget) (
/**//* [in] */ IUnknown *pDropTarget,
/**//* [out] */ IUnknown **ppDropTarget)
...{
return E_NOTIMPL;
}
STDMETHOD (GetExternal) (
/**//* [out] */ IDispatch **ppDispatch)
...{
//return E_NOTIMPL;
return QueryInterface(IID_IATLOpenerUI,(void**)ppDispatch);
}
STDMETHOD (TranslateUrl) (
/**//* [in] */ DWORD dwTranslate,
/**//* [in] */ BSTR bstrURLIn,
/**//* [out] */ BSTR *pbstrURLOut)
...{
return E_NOTIMPL;
}
STDMETHOD (FilterDataObject) (
/**//* [in] */ IUnknown *pDO,
/**//* [out] */ IUnknown **ppDORet)
...{
return E_NOTIMPL;
}
} ;
#endif // __ATLOPENER_H_
#define __ATLOPENER_H_
#include " resource.h " // main symbols
#include < atlctl.h >
#include < MSHTMCID.H >
#include < MSHTMHST.h >
#include " ATLMaskWrapperCP.h "
/**/ /////
// CATLOpener
class ATL_NO_VTABLE CATLOpener :
public CComObjectRootEx < CComSingleThreadModel > ,
public IDispatchImpl < IATLOpener, & IID_IATLOpener, & LIBID_ATLMASKWRAPPERLib > ,
public IDispatchImpl < IATLOpenerUI, & IID_IATLOpenerUI, & LIBID_ATLMASKWRAPPERLib > ,
public CComControl < CATLOpener > ,
public IPersistStreamInitImpl < CATLOpener > ,
public IOleControlImpl < CATLOpener > ,
public IOleObjectImpl < CATLOpener > ,
public IOleInPlaceActiveObjectImpl < CATLOpener > ,
public IViewObjectExImpl < CATLOpener > ,
public IOleInPlaceObjectWindowlessImpl < CATLOpener > ,
public ISupportErrorInfo,
public IConnectionPointContainerImpl < CATLOpener > ,
public CComCoClass < CATLOpener, & CLSID_ATLOpener > ,
public IProvideClassInfo2Impl <& CLSID_ATLOpener, & DIID__IATLOpenerEvents, & LIBID_ATLMASKWRAPPERLib > ,
public CProxy_IATLOpenerEvents < CATLOpener > ,
public IObjectSafetyImpl < CATLOpener, INTERFACESAFE_FOR_UNTRUSTED_CALLER >
... {
public:
CATLOpener()
...{
m_bWindowOnly = TRUE;
HRESULT hr =CoInitialize(NULL);
}
~CATLOpener()
...{
CoUninitialize();
}
BEGIN_CATEGORY_MAP(CATLOpener)
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
END_CATEGORY_MAP()
DECLARE_REGISTRY_RESOURCEID(IDR_ATLOPENER)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CATLOpener)
COM_INTERFACE_ENTRY(IATLOpener)
COM_INTERFACE_ENTRY(IATLOpenerUI)
COM_INTERFACE_ENTRY2(IDispatch, IATLOpener)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObject)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()
BEGIN_PROP_MAP(CATLOpener)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
// Example entries
// PROP_ENTRY("Property Description", dispid, clsid)
// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()
BEGIN_CONNECTION_POINT_MAP(CATLOpener)
CONNECTION_POINT_ENTRY(DIID__IATLOpenerEvents)
END_CONNECTION_POINT_MAP()
BEGIN_MSG_MAP(CATLOpener)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
CHAIN_MSG_MAP(CComControl<CATLOpener>)
END_MSG_MAP()
// Handler prototypes:
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
...{
static const IID* arr[] =
...{
&IID_IATLOpener,
};
for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
...{
if (InlineIsEqualGUID(*arr[i], riid))
return S_OK;
}
return S_FALSE;
}
// IViewObjectEx
DECLARE_VIEW_STATUS(0)
// IDispatch 一定要重载,否则脚本找不到接口
public:
STDMETHOD (GetIDsOfNames) (REFIID riid,
LPOLESTR* rgszNames,
UINT cNames,
LCID lcid,
DISPID* rgdispid);
STDMETHOD (Invoke) (DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pdispparams,
VARIANT* pvarResult,
EXCEPINFO* pexcepinfo,
UINT* puArgErr);
// IATLOpener
public:
STDMETHOD(OpenURL)(BSTR bstrURL);
// IATLOpenerUI
public:
// Example method called by the HTML to change the <BODY> background color
STDMETHOD(OnClick)(IDispatch* pdispBody, VARIANT varColor);
public:
LRESULT OnCreate(UINT /**//*uMsg*/, WPARAM /**//*wParam*/, LPARAM /**//*lParam*/, BOOL& /**//*bHandled*/);
public:
STDMETHOD(fireEvent)(BSTR bstrID, BSTR bstrValue);
CComPtr<IWebBrowser2> m_spBrowser;
// IDocHostUIHandlerDispatch
public:
STDMETHOD(OpenHTML)(BSTR bstrURL);
STDMETHOD (ShowContextMenu) (
/**//* [in] */ DWORD dwID,
/**//* [in] */ DWORD x,
/**//* [in] */ DWORD y,
/**//* [in] */ IUnknown *pcmdTarget,
/**//* [in] */ IDispatch *pdispReserved,
/**//* [retval][out] */ HRESULT *dwRetVal)
...{
#define IDR_BROWSE_CONTEXT_MENU 24641
#define IDM_REFRESH2 6042
#define IDM_SAVEASDESKTOPITEM 2278
#define IDM_SEPARATOR 0
#define IDM_SEPARATOR2 6047
HRESULT hr;
HINSTANCE hinstSHDOCLC;
HWND hwnd;
HMENU hMenuParent, hMenu;
CComPtr<IOleCommandTarget> spCT;
CComPtr<IOleWindow> spWnd;
MENUITEMINFO mii = ...{0};
CComVariant var, var1, var2;
hr = pcmdTarget->QueryInterface(IID_IOleCommandTarget, reinterpret_cast< void ** > (&spCT));
hr = spCT->QueryInterface(IID_IOleWindow, reinterpret_cast< void ** > (&spWnd));
hr = spWnd->GetWindow(&hwnd);
hinstSHDOCLC = LoadLibrary(TEXT("SHDOCLC.DLL"));
if (hinstSHDOCLC == NULL)
...{
// Error loading module -- fail as securely as possible
return S_FALSE;
}
hMenuParent = LoadMenu(hinstSHDOCLC,
MAKEINTRESOURCE(IDR_BROWSE_CONTEXT_MENU));
if (dwID == 5) //anchor
hMenu = GetSubMenu(hMenuParent, static_cast< int > (0));
else
hMenu = GetSubMenu(hMenuParent, static_cast< int > (dwID));
// Remove View Source
DeleteMenu(hMenu, IDM_REGISTRYREFRESH, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_REFRESH, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_REFRESH2, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_PROPERTIES, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_ADDFAVORITES, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_CREATESHORTCUT, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_VIEWSOURCE, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_LANGUAGE, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_GOBACKWARD, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_GOFORWARD, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_SAVEBACKGROUND, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_SETWALLPAPER, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_COPYBACKGROUND, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_SAVEASDESKTOPITEM, MF_BYCOMMAND);
DeleteMenu(hMenu, IDM_PRINT, MF_BYCOMMAND);
int iItemCount = GetMenuItemCount(hMenu)-1;
for(int i=iItemCount; i>=0; i--)
...{
if(GetMenuItemID(hMenu,i) == IDM_SEPARATOR || GetMenuItemID(hMenu,i) == IDM_SEPARATOR2)
...{
if(i==0)
DeleteMenu(hMenu, i, MF_BYPOSITION);
else if(GetMenuItemID(hMenu,i-1) == IDM_SEPARATOR || GetMenuItemID(hMenu,i-1) == IDM_SEPARATOR2)
DeleteMenu(hMenu, i, MF_BYPOSITION);
}
}
iItemCount = GetMenuItemCount(hMenu)-1;
if(GetMenuItemID(hMenu,iItemCount) == IDM_SEPARATOR || GetMenuItemID(hMenu,iItemCount) == IDM_SEPARATOR2)
DeleteMenu(hMenu, iItemCount, MF_BYPOSITION);
// Show shortcut menu
int iSelection = ::TrackPopupMenu(hMenu,
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON,
x,
y,
0,
hwnd,
(RECT*)NULL);
// Send selected shortcut menu item command to shell
LRESULT lr = ::SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(LOWORD(iSelection), 0x0), 0);
::DestroyMenu( hMenuParent );
FreeLibrary(hinstSHDOCLC);
if (iSelection != 31) //if not select all
...{
SetFocus();
}
//--------
*dwRetVal = S_OK;
return S_OK;
}
STDMETHOD (GetHostInfo) (
/**//* [out][in] */ DWORD *pdwFlags,
/**//* [out][in] */ DWORD *pdwDoubleClick)
...{
return E_NOTIMPL;
}
STDMETHOD (ShowUI) (
/**//* [in] */ DWORD dwID,
/**//* [in] */ IUnknown *pActiveObject,
/**//* [in] */ IUnknown *pCommandTarget,
/**//* [in] */ IUnknown *pFrame,
/**//* [in] */ IUnknown *pDoc,
/**//* [retval][out] */ HRESULT *dwRetVal)
...{
return E_NOTIMPL;
}
STDMETHOD (HideUI) (void)
...{
return E_NOTIMPL;
}
STDMETHOD (UpdateUI) (void)
...{
return E_NOTIMPL;
}
STDMETHOD (EnableModeless) (
/**//* [in] */ VARIANT_BOOL fEnable)
...{
return E_NOTIMPL;
}
STDMETHOD (OnDocWindowActivate) (
/**//* [in] */ VARIANT_BOOL fActivate)
...{
return E_NOTIMPL;
}
STDMETHOD (OnFrameWindowActivate) (
/**//* [in] */ VARIANT_BOOL fActivate)
...{
return E_NOTIMPL;
}
STDMETHOD (ResizeBorder) (
/**//* [in] */ long left,
/**//* [in] */ long top,
/**//* [in] */ long right,
/**//* [in] */ long bottom,
/**//* [in] */ IUnknown *pUIWindow,
/**//* [in] */ VARIANT_BOOL fFrameWindow)
...{
return E_NOTIMPL;
}
STDMETHOD (TranslateAccelerator) (
/**//* [in] */ DWORD hWnd,
/**//* [in] */ DWORD nMessage,
/**//* [in] */ DWORD wParam,
/**//* [in] */ DWORD lParam,
/**//* [in] */ BSTR bstrGuidCmdGroup,
/**//* [in] */ DWORD nCmdID,
/**//* [retval][out] */ HRESULT *dwRetVal)
...{
return E_NOTIMPL;
}
STDMETHOD (GetOptionKeyPath) (
/**//* [out] */ BSTR *pbstrKey,
/**//* [in] */ DWORD dw)
...{
return E_NOTIMPL;
}
STDMETHOD (GetDropTarget) (
/**//* [in] */ IUnknown *pDropTarget,
/**//* [out] */ IUnknown **ppDropTarget)
...{
return E_NOTIMPL;
}
STDMETHOD (GetExternal) (
/**//* [out] */ IDispatch **ppDispatch)
...{
//return E_NOTIMPL;
return QueryInterface(IID_IATLOpenerUI,(void**)ppDispatch);
}
STDMETHOD (TranslateUrl) (
/**//* [in] */ DWORD dwTranslate,
/**//* [in] */ BSTR bstrURLIn,
/**//* [out] */ BSTR *pbstrURLOut)
...{
return E_NOTIMPL;
}
STDMETHOD (FilterDataObject) (
/**//* [in] */ IUnknown *pDO,
/**//* [out] */ IUnknown **ppDORet)
...{
return E_NOTIMPL;
}
} ;
#endif // __ATLOPENER_H_
CPP文件
#include
"
stdafx.h
"
#include " ATLMaskWrapper.h "
#include " ATLOpener.h "
#include " PrepareHtml.h "
typedef IDispatchImpl < IATLOpener, & IID_IATLOpener, & LIBID_ATLMASKWRAPPERLib > ATLOpenerType;
typedef IDispatchImpl < IATLOpenerUI, & IID_IATLOpenerUI, & LIBID_ATLMASKWRAPPERLib > ATLOpenerUIType;
const DISPID INTERFACEMASK = 0xFFFF0000 ;
const DISPID DISPIDMASK = 0x0000FFFF ;
const DISPID IDISPATLOPENER = 0x00010000 ;
const DISPID IDISPATLOPENERUI = 0x00020000 ;
/**/ /////
// CATLOpener
STDMETHODIMP CATLOpener::GetIDsOfNames(REFIID riid,
LPOLESTR * rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid)
... {
HRESULT hr = DISP_E_UNKNOWNNAME;
hr = ATLOpenerType::GetIDsOfNames(riid,
rgszNames, cNames, lcid, rgdispid);
if (SUCCEEDED(hr))
...{
rgdispid[0] |= IDISPATLOPENER;
return hr;
}
hr = ATLOpenerUIType::GetIDsOfNames(riid,
rgszNames,
cNames,
lcid,
rgdispid);
if (SUCCEEDED(hr))
...{
rgdispid[0] |= IDISPATLOPENERUI;
return hr;
}
return hr;
}
STDMETHODIMP CATLOpener::Invoke(DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr)
... {
DWORD dwInterface = (dispidMember & INTERFACEMASK);
dispidMember &= DISPIDMASK;
switch(dwInterface)
...{
case IDISPATLOPENERUI:
return ATLOpenerUIType::Invoke(dispidMember,
riid,
lcid,
wFlags,
pdispparams,
pvarResult,
pexcepinfo,
puArgErr);
case IDISPATLOPENER:
default:
//return DISP_E_MEMBERNOTFOUND;
return ATLOpenerType::Invoke(dispidMember,
riid,
lcid,
wFlags,
pdispparams,
pvarResult,
pexcepinfo,
puArgErr);
}
}
STDMETHODIMP CATLOpener::OnClick(IDispatch * pdispBody, VARIANT varColor)
... {
CComQIPtr<IHTMLBodyElement> spBody(pdispBody);
if (spBody != NULL)
spBody->put_bgColor(varColor);
return S_OK;
}
LRESULT CATLOpener::OnCreate(UINT /**/ /*uMsg*/ , WPARAM /**/ /*wParam*/ , LPARAM /**/ /*lParam*/ , BOOL & /**/ /*bHandled*/ )
... {
CAxWindow wnd(m_hWnd);
HRESULT hr = wnd.CreateControl(IDH_ATLOPENER);
if (SUCCEEDED(hr))
...{
// 有滚动条
CComQIPtr<IDocHostUIHandlerDispatch> pIUI(static_cast<IDocHostUIHandlerDispatch*>(this));
hr = wnd.SetExternalUIHandler(pIUI);
// 无滚动条
// hr = wnd.SetExternalDispatch(static_cast<IATLOpenerUI*>(this));
}
if (SUCCEEDED(hr))
...{
hr = wnd.QueryControl(IID_IWebBrowser2, (void**)&m_spBrowser);
}
return SUCCEEDED(hr) ? 0 : -1;
}
STDMETHODIMP CATLOpener::OpenURL(BSTR bstrURL) // 显示组件界面
... {
// TODO: Add your implementation code here
HRESULT hr = NULL;
hr = m_spBrowser->Navigate(bstrURL, NULL, NULL, NULL, NULL);
if (hr != S_OK)
...{
MessageBox("Navigate failed!");
}
return S_OK;
}
STDMETHODIMP CATLOpener::fireEvent(BSTR bstrID, BSTR bstrValue) // 脚本抛事件
... {
// TODO: Add your implementation code here
Fire_OnEvent(bstrID,bstrValue);
return S_OK;
}
STDMETHODIMP CATLOpener::OpenHTML(BSTR bstrURL) // 显示HTML页面
... {
// TODO: Add your implementation code here
CPrepareHtml Prepare;
Prepare.Prepare(bstrURL);
return S_OK;
}
#include " ATLMaskWrapper.h "
#include " ATLOpener.h "
#include " PrepareHtml.h "
typedef IDispatchImpl < IATLOpener, & IID_IATLOpener, & LIBID_ATLMASKWRAPPERLib > ATLOpenerType;
typedef IDispatchImpl < IATLOpenerUI, & IID_IATLOpenerUI, & LIBID_ATLMASKWRAPPERLib > ATLOpenerUIType;
const DISPID INTERFACEMASK = 0xFFFF0000 ;
const DISPID DISPIDMASK = 0x0000FFFF ;
const DISPID IDISPATLOPENER = 0x00010000 ;
const DISPID IDISPATLOPENERUI = 0x00020000 ;
/**/ /////
// CATLOpener
STDMETHODIMP CATLOpener::GetIDsOfNames(REFIID riid,
LPOLESTR * rgszNames,
UINT cNames,
LCID lcid,
DISPID * rgdispid)
... {
HRESULT hr = DISP_E_UNKNOWNNAME;
hr = ATLOpenerType::GetIDsOfNames(riid,
rgszNames, cNames, lcid, rgdispid);
if (SUCCEEDED(hr))
...{
rgdispid[0] |= IDISPATLOPENER;
return hr;
}
hr = ATLOpenerUIType::GetIDsOfNames(riid,
rgszNames,
cNames,
lcid,
rgdispid);
if (SUCCEEDED(hr))
...{
rgdispid[0] |= IDISPATLOPENERUI;
return hr;
}
return hr;
}
STDMETHODIMP CATLOpener::Invoke(DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS * pdispparams,
VARIANT * pvarResult,
EXCEPINFO * pexcepinfo,
UINT * puArgErr)
... {
DWORD dwInterface = (dispidMember & INTERFACEMASK);
dispidMember &= DISPIDMASK;
switch(dwInterface)
...{
case IDISPATLOPENERUI:
return ATLOpenerUIType::Invoke(dispidMember,
riid,
lcid,
wFlags,
pdispparams,
pvarResult,
pexcepinfo,
puArgErr);
case IDISPATLOPENER:
default:
//return DISP_E_MEMBERNOTFOUND;
return ATLOpenerType::Invoke(dispidMember,
riid,
lcid,
wFlags,
pdispparams,
pvarResult,
pexcepinfo,
puArgErr);
}
}
STDMETHODIMP CATLOpener::OnClick(IDispatch * pdispBody, VARIANT varColor)
... {
CComQIPtr<IHTMLBodyElement> spBody(pdispBody);
if (spBody != NULL)
spBody->put_bgColor(varColor);
return S_OK;
}
LRESULT CATLOpener::OnCreate(UINT /**/ /*uMsg*/ , WPARAM /**/ /*wParam*/ , LPARAM /**/ /*lParam*/ , BOOL & /**/ /*bHandled*/ )
... {
CAxWindow wnd(m_hWnd);
HRESULT hr = wnd.CreateControl(IDH_ATLOPENER);
if (SUCCEEDED(hr))
...{
// 有滚动条
CComQIPtr<IDocHostUIHandlerDispatch> pIUI(static_cast<IDocHostUIHandlerDispatch*>(this));
hr = wnd.SetExternalUIHandler(pIUI);
// 无滚动条
// hr = wnd.SetExternalDispatch(static_cast<IATLOpenerUI*>(this));
}
if (SUCCEEDED(hr))
...{
hr = wnd.QueryControl(IID_IWebBrowser2, (void**)&m_spBrowser);
}
return SUCCEEDED(hr) ? 0 : -1;
}
STDMETHODIMP CATLOpener::OpenURL(BSTR bstrURL) // 显示组件界面
... {
// TODO: Add your implementation code here
HRESULT hr = NULL;
hr = m_spBrowser->Navigate(bstrURL, NULL, NULL, NULL, NULL);
if (hr != S_OK)
...{
MessageBox("Navigate failed!");
}
return S_OK;
}
STDMETHODIMP CATLOpener::fireEvent(BSTR bstrID, BSTR bstrValue) // 脚本抛事件
... {
// TODO: Add your implementation code here
Fire_OnEvent(bstrID,bstrValue);
return S_OK;
}
STDMETHODIMP CATLOpener::OpenHTML(BSTR bstrURL) // 显示HTML页面
... {
// TODO: Add your implementation code here
CPrepareHtml Prepare;
Prepare.Prepare(bstrURL);
return S_OK;
}