📄 iecomctrlsink.cpp
字号:
// IEComCtrlSink.cpp : implementation file
//
#include "stdafx.h"
#include "IEComCtrlSink.h"
#include <Afxctl.h>//定义了AfxConnectionAdvise、AfxConnectionUnadvise
#include <atlbase.h>//使用ATL相关函数
// CIEComCtrlSink
//定义静态指针,对于静态变量,注意一定要在类定义之外定义该变量
COfficeCtrl CIEComCtrlSink::officeCtrl;
IMPLEMENT_DYNAMIC(CIEComCtrlSink, CCmdTarget)
CIEComCtrlSink::CIEComCtrlSink()
{
// enable OLE
EnableAutomation();
CoInitialize(NULL);
//初始化欲监听的IWebBrowser2控件接口指针
m_pWebBrowser2 = NULL;
// 初始化IE应用程序指针
m_pIEApp = NULL;
// 初始化Cookie值,以便以后监听事件
m_dwCookie = 0;
//没有正在监听IE对象,初始化bSinking为FALSE
bSinking=FALSE;
}
CIEComCtrlSink::~CIEComCtrlSink()
{
HRESULT hr = 0;
//取消事件监听
UnAdviseSink();
if(IsWindow(m_wndWebBrowser.m_hWnd))
{
m_wndWebBrowser.Detach();
}
m_wndWebBrowser.m_hWnd = NULL;
if(m_pIEApp)
{
hr = m_pIEApp->Release();
m_pIEApp = NULL;
}
if(m_pWebBrowser2)
{
hr = m_pWebBrowser2->Release();
m_pWebBrowser2 = NULL;
}
// unload OLE
CoUninitialize();
}
BEGIN_MESSAGE_MAP(CIEComCtrlSink, CCmdTarget)
END_MESSAGE_MAP()
//填充Dispatch Map表
// 以下是我们想监听的事件
//相关事件意义参见相关函数的说明
BEGIN_DISPATCH_MAP(CIEComCtrlSink, CCmdTarget)
DISP_FUNCTION_ID(CIEComCtrlSink, "OnQuit",DISPID_ONQUIT,OnQuit,VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CIEComCtrlSink, "BeforeNavigate2",DISPID_BEFORENAVIGATE2,BeforeNavigate2,
VT_EMPTY, VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
DISP_FUNCTION_ID(CIEComCtrlSink, "DocumentComplete",DISPID_DOCUMENTCOMPLETE,DocumentComplete,
VT_EMPTY, VTS_DISPATCH VTS_PVARIANT)
DISP_FUNCTION_ID(CIEComCtrlSink, "DownloadBegin",DISPID_DOWNLOADBEGIN,DownloadBegin,VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CIEComCtrlSink, "DownloadEnd",DISPID_DOWNLOADCOMPLETE,DownloadEnd,VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
// CIEComCtrlSink message handlers
//通过调用以下函数,打开一个IE, 开始连接该IE的 DWebBrowserEvents2 事件
BOOL CIEComCtrlSink::MyAdviseSink()
{
//用IWebBrowser2创建Web浏览器
HRESULT hr = CoCreateInstance(CLSID_InternetExplorer,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IWebBrowser2,
(void**)&m_pWebBrowser2);
if(!SUCCEEDED(hr))
{
CString strMsg;
strMsg.Format(_T("创建InternetExplorer失败,错误: %d"),(int)hr);
AfxMessageBox(strMsg);
return false;
}
//得到IWebBrowserApp接口,以便设置IE的菜单栏,状态栏,工具栏
hr = m_pWebBrowser2->QueryInterface(IID_IWebBrowserApp,(void**)&m_pIEApp);
hr = m_pIEApp->put_StatusBar(true);
hr = m_pIEApp->put_ToolBar(true);
hr = m_pIEApp->put_MenuBar(true);
long hIE;
//得到该IE的Window句柄,以便显示该IE窗口
hr = m_pWebBrowser2->get_HWND(&hIE);
if(!SUCCEEDED(hr))
{
CString strMsg;
strMsg.Format(_T("无法得到IE的window句柄 错误: %d"),(int)hr);
AfxMessageBox(strMsg);
return FALSE;
}
// 通过IE的window句柄显示该IE窗口
m_wndWebBrowser.Attach((HWND)hIE);
m_wndWebBrowser.EnableScrollBar(SB_BOTH, ESB_DISABLE_BOTH);
m_wndWebBrowser.ShowWindow(SW_NORMAL);
// 以下让IE转到一特定的测试页面,以便测试程序的功能
//获取主程序所在路径,保存在sPath中
CString sPath;
GetModuleFileName(_Module.m_hInst,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH);
sPath.ReleaseBuffer ();
int nPos;
nPos=sPath.ReverseFind ('\\');
sPath=sPath.Left (nPos);
//转到test.htm测试页面
Navigate2(sPath+"\\test.htm");
// advise the browser to send events here
LPUNKNOWN pUnkSink = GetIDispatch(FALSE);
//通知IE监听相关事件
//这个函数内部将进行QueryInterface(IConnectionPointContainer,..)、FindConnectionPoint()、Advise()等一系列调用
AfxConnectionAdvise(
(LPUNKNOWN)m_pWebBrowser2//可连接对象的接口指针
DIID_DWebBrowserEvents2//连接接口ID
pUnkSink,//把内嵌的IDispatch实现类的一个对象实例传出来
FALSE//不增加引用记数
&m_dwCookie//保存Cookie值以便以后取消监听
);
//正在监听IE对象,设置bSinking为TRUE
bSinking=TRUE;
return TRUE;
}
// 停止监听 DWebBrowserEvents2 事件
BOOL CIEComCtrlSink::UnAdviseSink()
{
BOOL bOK = TRUE;
// 如果 Cookie 不为0,则取消事件监听
if(m_dwCookie != 0)
{
LPUNKNOWN pUnkSink = GetIDispatch(FALSE);
//断开事件监听连接
//将调用Unadvise()
bOK = AfxConnectionUnadvise((LPUNKNOWN)m_pWebBrowser2, DIID_DWebBrowserEvents2, pUnkSink, FALSE, m_dwCookie);
//清空Cookie值
m_dwCookie = 0;
}
//没有正在监听IE对象,设置bSinking为FALSE
bSinking=FALSE;
return bOK;
}
// 当IE浏览器退出 时取消事件监听
void CIEComCtrlSink::OnQuit()
{
//取消事件监听
UnAdviseSink();
}
//当监听的IE对象转到一新的URL之前,调用以下函数
void CIEComCtrlSink::BeforeNavigate2(LPDISPATCH pDisp, VARIANT FAR *url, VARIANT FAR *Flags,
VARIANT FAR *TargetFrameName, VARIANT FAR *PostData, VARIANT FAR *Headers, VARIANT_BOOL* Cancel)
{
CString strUrl=(CString)(url->bstrVal);
//检查是否为具有一定特征的URL
int idx =strUrl.Find(_T("insertResToPowerPoint.asp?fileURL="));
if(idx!=-1){
*Cancel=true; //取消该事件,让程序正常的执行我们的将资源插入到PowerPoint 2000中
// 分析strUrl字符串,将该字符号串中指定路径的资源插入到PowerPoint中
CIEComCtrlSink::officeCtrl.insertResToPowerPoint(strUrl);
}
return;
}
//当监听的IE对象"准备就绪"(READYSTATE_COMPLETE)后,调用以下函数
void CIEComCtrlSink::DocumentComplete(IDispatch *pDisp,VARIANT *URL)
{
}
//当监听的IE对象下载数据之前,调用以下函数
void CIEComCtrlSink::DownloadBegin()
{
}
//当监听的IE对象开始下载数据完成后,调用以下函数
void CIEComCtrlSink::DownloadEnd()
{
}
// 装载一指定web页面
BOOL CIEComCtrlSink::Navigate2(CString strURL)
{
HRESULT hr = S_OK;
DWORD dwFlags = 0;
LPCTSTR lpszTargetFrameName = NULL;
LPCTSTR lpszHeaders = NULL;
LPVOID lpvPostData = NULL;
DWORD dwPostDataLen = 0;
COleSafeArray vPostData;
// 转换 CString 为 COleVariant
COleVariant vaURL(strURL);
hr = m_pWebBrowser2->Navigate2(vaURL, COleVariant((long) dwFlags, VT_I4), COleVariant(lpszTargetFrameName, VT_BSTR),
vPostData, COleVariant(lpszHeaders, VT_BSTR));
return (hr == S_OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -