最近做一个项目,总是需要在同一个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后会自动跳转到百度首页。
如有疑问请留下您的联系方式。