最近做一个项目,总是需要在同一个IE中打开不同的地址。我们常用的打开网页的方法有以下几种:
一、shellexecute
二、navigate/navigate2
但是这几种方法不好控制IE。在网上看到一篇文章,Automate the Active Windows Explorer or Internet Explorer Window - CodeProject (网址是http://www.codeproject.com/KB/shell/AutomateShellWindow.aspx),修改了一下其中的代码,实现了自己想要的功能。
步骤如下:
1,新建一个工程
2,在头文件中加入
#include "afxtempl.h"
和
typedef CComQIPtr<IWebBrowser2> CComQIPtrIWebBrowser2;
3,声明如下函数
void AttachShellWindow(BOOL bIE);
void AdviseSinkIE();
void UnadvisesinkIE();
void NavigateToSamplePage(BOOL bIE);
CString GetWindowClassName(IWebBrowser2* pwb);
4,实现上述函数。
void AdviseSinkIE()
{
if(m_pWebBrowser2)
{
LPUNKNOWN pUnkSink = GetIDispatch(FALSE);
AfxConnectionAdvise((LPUNKNOWN)m_pWebBrowser2,
DIID_DWebBrowserEvents2,pUnkSink,FALSE,&m_dwCookie);
}
}
void UnadvisesinkIE()
{
if(m_dwCookie != 0&&m_pWebBrowser2!=NULL)
{
LPUNKNOWN pUnkSink = GetIDispatch(FALSE);
AfxConnectionUnadvise((LPUNKNOWN)m_pWebBrowser2, DIID_DWebBrowserEvents2, pUnkSink, FALSE, m_dwCookie);
m_dwCookie = 0;
}
}
CString GetWindowClassName(IWebBrowser2* pwb)取得所有打开的窗口名
{
TCHAR szClassName[_MAX_PATH];
ZeroMemory(szClassName,_MAX_PATH*sizeof(TCHAR));
HWND hwnd=NULL;
if(pwb)
{
LONG_PTR lwnd=NULL;
pwb->get_HWND(&lwnd);
hwnd=reinterpret_cast<HWND>(lwnd);
::GetClassName(hwnd,szClassName,_MAX_PATH);
}
return szClassName;
}
void AttachShellWindow(BOOL bIE)
{
CoInitialize(NULL);初始化com,此句非常重要。
if(!UpdateData())return;
if(m_pWebBrowser2)
{
if(m_bOwnIE)
{
m_pWebBrowser2->Quit();
m_bOwnIE=FALSE;
}
UnadvisesinkIE();
}
CComPtr<IShellWindows> psw;得到正在运行的IE实例列表
psw.CoCreateInstance(CLSID_ShellWindows);
if(psw)
{
CDWordArray arHWNDShellWindows;用来存储IE句柄的数组
arHWNDShellWindows.SetSize(0,10);
CTypedPtrArray<CPtrArray,CComQIPtrIWebBrowser2*> arShellWindows;
arShellWindows.SetSize(0,10);
long lShellWindowCount=0;
psw->get_Count(&lShellWindowCount);
for(long i=0;i<lShellWindowCount;i++)
{
CComPtr<IDispatch> pdispShellWindow;
psw->Item(COleVariant(i),&pdispShellWindow);
CComQIPtr<IWebBrowser2> pIE(pdispShellWindow);
if(pIE)
{
CString strWindowClass=GetWindowClassName(pIE);
if(bIE? strWindowClass==_T("IEFrame")判断是否是需要的窗口
:strWindowClass==_T("ExploreWClass"))
{
HWND hWndID=NULL;
pIE->get_HWND((long*)&hWndID);
arHWNDShellWindows.Add((DWORD)hWndID);
arShellWindows.Add(new CComQIPtrIWebBrowser2(pIE));
}
}
}
if(arHWNDShellWindows.GetSize()>0) 根据IE窗口的Z顺序,找到最新的窗口
{
BOOL bFound=FALSE;
HWND hwndTest=::GetWindow((HWND)arHWNDShellWindows[0],GW_HWNDFIRST);
while( hwndTest&& !bFound)
{
for(int i=0;i<arHWNDShellWindows.GetSize();i++)
{
if(hwndTest==(HWND)arHWNDShellWindows[i])
{
m_pWebBrowser2=*arShellWindows[i];
AdviseSinkIE();
NavigateToSamplePage(bIE);
bFound=TRUE;
m_bOwnIE=FALSE;
break;
}
}
hwndTest = ::GetWindow(hwndTest, GW_HWNDNEXT);
}
}
for(int i=0;i<arShellWindows.GetSize();i++)
{
delete arShellWindows[i];
}
}
}
void NavigateToSamplePage(BOOL bIE)用来打开的网页
{
if(bIE)
{
if(!::PathIsURL(m_strFileToFind))
m_strFileToFind=_T("http://www.baidu.com/");
COleVariant vaURL((LPCTSTR)m_strFileToFind);
m_pWebBrowser2->Navigate2(
&vaURL,COleVariant((long) 0, VT_I4),
COleVariant((LPCTSTR)NULL, VT_BSTR),
COleSafeArray(),
COleVariant((LPCTSTR)NULL, VT_BSTR)
);
}
}
5,在工程中新增一个函数,如onXXX(),在其中加入如下代码便能实现。
ShellExecute(m_hWnd,_T("open"),_T("IEXPLORE"),_T("www.sina.com.cn"),NULL,SW_SHOWNORMAL);
Sleep(2000);
AttachShellWindow(TRUE);
最后,程序会打开一个IE,跳转到新浪首页,过2s后会自动跳转到百度首页。
如有疑问请留下您的联系方式。