在BHO中处理IE的事件
在IEHelper的SetSite方法的实现过程中,IEHelper通知IE浏览器他想要收到所有IE触发的事件。为了能够从IE中收到事件,你必须实现IDispatch接口。
在默认的情况下,简单的ATL对象从IDispatchImpl中继承,当IE触发了事件的时候, 你可以使用AtlAdvise来让IE通知你。仅有的一个你需要重写的IDispatchImpl方法是Invoke方法。每次IE激发了一个事件的时候,他都会调用你的Invoke方法。
为了停止收到事件,你可以雕用AtlUnadvise方法。当IE通知你,他正在退出的时候,你必须调用AtlUnadvise传递DISPID_QUIT参数到Invoke方法。下面的代码重写了Invoke方法。就象我们看到的那样,下面的大部分代码是为了处理IE的事件并且将这些事件的名字写到IEHelper事件的窗口中。
STDMETHODIMP CIEHlprObj::Invoke(DISPID dispidMember, REFIID riid,
LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pvarResult,
EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
USES_CONVERSION;
strstream strEventInfo;
if (!pDispParams)
return E_INVALIDARG;
//
// Get the current URL.
//
LPOLESTR lpURL = NULL;
m_spWebBrowser2->get_LocationURL(&lpURL);
switch (dispidMember)
{
//
// The parameters for this DISPID are as follows:
// [0]: Cancel flag - VT_BYREF|VT_BOOL
// [1]: HTTP headers - VT_BYREF|VT_VARIANT
// [2]: Address of HTTP POST data - VT_BYREF|VT_VARIANT
// [3]: Target frame name - VT_BYREF|VT_VARIANT
// [4]: Option flags - VT_BYREF|VT_VARIANT
// [5]: URL to navigate to - VT_BYREF|VT_VARIANT
// [6]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event
//
case DISPID_BEFORENAVIGATE2:
strEventInfo << "BeforeNavigate2: ";
if (pDispParams->cArgs >= 5 &&
pDispParams->rgvarg[5].vt == (VT_BYREF|VT_VARIANT))
{
CComVariant varURL(*pDispParams->rgvarg[5].pvarVal);
varURL.ChangeType(VT_BSTR);
strEventInfo << OLE2T(varURL.bstrVal);
}
else
strEventInfo << "NULL";
strEventInfo << ends;
break;
//
// The parameters for this DISPID:
// [0]: URL navigated to - VT_BYREF|VT_VARIANT
// [1]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event
//
case DISPID_NAVIGATECOMPLETE2:
if (pDispParams->rgvarg[0].vt == (VT_BYREF|VT_VARIANT))
{
CComVariant varURL(*pDispParams->rgvarg[0].pvarVal);
varURL.ChangeType(VT_BSTR);
strEventInfo << "NavigateComplete2: "
<< OLE2T(varURL.bstrVal)
<< ends;
}
break;
//
// The parameters for this DISPID:
// [0]: New status bar text - VT_BSTR
//
case DISPID_STATUSTEXTCHANGE:
LPOLESTR lpStatusText;
m_spWebBrowser2->get_StatusText(&lpStatusText);
strEventInfo << "StatusTextChange: ";
if (!strcmp(OLE2T(lpStatusText), ""))
strEventInfo << "NULL";
else
strEventInfo << OLE2T(lpStatusText);
strEventInfo << ends;
break;
//
// The parameters for this DISPID:
// [0]: Maximum progress - VT_I4
// [1]: Amount of total progress - VT_I4
//
case DISPID_PROGRESSCHANGE:
strEventInfo << "ProgressChange: ";
if (pDispParams->cArgs == 0)
strEventInfo << "NULL";
else
{
if (pDispParams->rgvarg[0].vt == VT_I4)
strEventInfo << pDispParams->rgvarg[0].lVal;
if (pDispParams->cArgs > 1 &&
pDispParams->rgvarg[1].vt == VT_I4)
{
strEventInfo << ", " << pDispParams->rgvarg[1].lVal;
}
}
strEventInfo << ends;
break;
case DISPID_DOCUMENTCOMPLETE:
strEventInfo << "DocumentComplete" << ends;
break;
case DISPID_DOWNLOADBEGIN:
strEventInfo << "DownloadBegin" << ends;
break;
case DISPID_DOWNLOADCOMPLETE:
strEventInfo << "DownloadComplete" << ends;
break;
//
// The parameters for this DISPID:
// [0]: Enabled state - VT_BOOL
// [1]: Command identifier - VT_I4
//
case DISPID_COMMANDSTATECHANGE:
strEventInfo << "CommandStateChange: ";
if (pDispParams->cArgs == 0)
strEventInfo << "NULL";
else
{
if (pDispParams->rgvarg[0].vt == VT_BOOL)
{
strEventInfo << ((pDispParams->rgvarg[0].boolVal ==
VARIANT_TRUE) ? "True" : "False");
}
if (pDispParams->cArgs > 1 &&
pDispParams->rgvarg[1].vt == VT_I4)
{
strEventInfo << ", " << pDispParams->rgvarg[1].lVal;
}
}
strEventInfo << ends;
break;
case DISPID_NEWWINDOW2:
strEventInfo << "NewWindow2" << ends;
break;
//
// The parameters for this DISPID:
// [0]: Document title - VT_BSTR
//
case DISPID_TITLECHANGE:
strEventInfo << "TitleChange: ";
if (pDispParams->cArgs > 0 &&
pDispParams->rgvarg[0].vt == VT_BSTR)
{
strEventInfo << OLE2T(pDispParams->rgvarg[0].bstrVal);
}
else
{
strEventInfo << "NULL";
}
strEventInfo << ends;
break;
//
// The parameters for this DISPID:
// [0]: Name of property that changed - VT_BSTR
//
case DISPID_PROPERTYCHANGE:
strEventInfo << "PropertyChange: ";
if (pDispParams->cArgs > 0 &&
pDispParams->rgvarg[0].vt == VT_BSTR)
{
strEventInfo << OLE2T(pDispParams->rgvarg[0].bstrVal);
}
else
{
strEventInfo << "NULL";
}
strEventInfo << ends;
break;
//
// The parameters for this DISPID:
// [0]: Address of cancel flag - VT_BYREF|VT_BOOL
//
case DISPID_QUIT:
strEventInfo << "Quit" << ends;
ManageConnection(Unadvise);
m_dlgEvents.DestroyWindow();
break;
default:
strEventInfo << "Unknown Event" << dispidMember << ends;
break;
}
m_dlgEvents.AddEventToList(strEventInfo.str());
return S_OK;
}
LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pvarResult,
EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
USES_CONVERSION;
strstream strEventInfo;
if (!pDispParams)
return E_INVALIDARG;
//
// Get the current URL.
//
LPOLESTR lpURL = NULL;
m_spWebBrowser2->get_LocationURL(&lpURL);
switch (dispidMember)
{
//
// The parameters for this DISPID are as follows:
// [0]: Cancel flag - VT_BYREF|VT_BOOL
// [1]: HTTP headers - VT_BYREF|VT_VARIANT
// [2]: Address of HTTP POST data - VT_BYREF|VT_VARIANT
// [3]: Target frame name - VT_BYREF|VT_VARIANT
// [4]: Option flags - VT_BYREF|VT_VARIANT
// [5]: URL to navigate to - VT_BYREF|VT_VARIANT
// [6]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event
//
case DISPID_BEFORENAVIGATE2:
strEventInfo << "BeforeNavigate2: ";
if (pDispParams->cArgs >= 5 &&
pDispParams->rgvarg[5].vt == (VT_BYREF|VT_VARIANT))
{
CComVariant varURL(*pDispParams->rgvarg[5].pvarVal);
varURL.ChangeType(VT_BSTR);
strEventInfo << OLE2T(varURL.bstrVal);
}
else
strEventInfo << "NULL";
strEventInfo << ends;
break;
//
// The parameters for this DISPID:
// [0]: URL navigated to - VT_BYREF|VT_VARIANT
// [1]: An object that evaluates to the top-level or frame
// WebBrowser object corresponding to the event
//
case DISPID_NAVIGATECOMPLETE2:
if (pDispParams->rgvarg[0].vt == (VT_BYREF|VT_VARIANT))
{
CComVariant varURL(*pDispParams->rgvarg[0].pvarVal);
varURL.ChangeType(VT_BSTR);
strEventInfo << "NavigateComplete2: "
<< OLE2T(varURL.bstrVal)
<< ends;
}
break;
//
// The parameters for this DISPID:
// [0]: New status bar text - VT_BSTR
//
case DISPID_STATUSTEXTCHANGE:
LPOLESTR lpStatusText;
m_spWebBrowser2->get_StatusText(&lpStatusText);
strEventInfo << "StatusTextChange: ";
if (!strcmp(OLE2T(lpStatusText), ""))
strEventInfo << "NULL";
else
strEventInfo << OLE2T(lpStatusText);
strEventInfo << ends;
break;
//
// The parameters for this DISPID:
// [0]: Maximum progress - VT_I4
// [1]: Amount of total progress - VT_I4
//
case DISPID_PROGRESSCHANGE:
strEventInfo << "ProgressChange: ";
if (pDispParams->cArgs == 0)
strEventInfo << "NULL";
else
{
if (pDispParams->rgvarg[0].vt == VT_I4)
strEventInfo << pDispParams->rgvarg[0].lVal;
if (pDispParams->cArgs > 1 &&
pDispParams->rgvarg[1].vt == VT_I4)
{
strEventInfo << ", " << pDispParams->rgvarg[1].lVal;
}
}
strEventInfo << ends;
break;
case DISPID_DOCUMENTCOMPLETE:
strEventInfo << "DocumentComplete" << ends;
break;
case DISPID_DOWNLOADBEGIN:
strEventInfo << "DownloadBegin" << ends;
break;
case DISPID_DOWNLOADCOMPLETE:
strEventInfo << "DownloadComplete" << ends;
break;
//
// The parameters for this DISPID:
// [0]: Enabled state - VT_BOOL
// [1]: Command identifier - VT_I4
//
case DISPID_COMMANDSTATECHANGE:
strEventInfo << "CommandStateChange: ";
if (pDispParams->cArgs == 0)
strEventInfo << "NULL";
else
{
if (pDispParams->rgvarg[0].vt == VT_BOOL)
{
strEventInfo << ((pDispParams->rgvarg[0].boolVal ==
VARIANT_TRUE) ? "True" : "False");
}
if (pDispParams->cArgs > 1 &&
pDispParams->rgvarg[1].vt == VT_I4)
{
strEventInfo << ", " << pDispParams->rgvarg[1].lVal;
}
}
strEventInfo << ends;
break;
case DISPID_NEWWINDOW2:
strEventInfo << "NewWindow2" << ends;
break;
//
// The parameters for this DISPID:
// [0]: Document title - VT_BSTR
//
case DISPID_TITLECHANGE:
strEventInfo << "TitleChange: ";
if (pDispParams->cArgs > 0 &&
pDispParams->rgvarg[0].vt == VT_BSTR)
{
strEventInfo << OLE2T(pDispParams->rgvarg[0].bstrVal);
}
else
{
strEventInfo << "NULL";
}
strEventInfo << ends;
break;
//
// The parameters for this DISPID:
// [0]: Name of property that changed - VT_BSTR
//
case DISPID_PROPERTYCHANGE:
strEventInfo << "PropertyChange: ";
if (pDispParams->cArgs > 0 &&
pDispParams->rgvarg[0].vt == VT_BSTR)
{
strEventInfo << OLE2T(pDispParams->rgvarg[0].bstrVal);
}
else
{
strEventInfo << "NULL";
}
strEventInfo << ends;
break;
//
// The parameters for this DISPID:
// [0]: Address of cancel flag - VT_BYREF|VT_BOOL
//
case DISPID_QUIT:
strEventInfo << "Quit" << ends;
ManageConnection(Unadvise);
m_dlgEvents.DestroyWindow();
break;
default:
strEventInfo << "Unknown Event" << dispidMember << ends;
break;
}
m_dlgEvents.AddEventToList(strEventInfo.str());
return S_OK;
}