미리 말씀드리면, 저도 아직 이 2가지 메서드의 근본적인 차이점은 MSDN 도움말 이상으로는 알지 못합니다. Navigate2 메서드가 Shell과 통합된 기능을 제공한다는 정도.
단지, 이번 글에서는 테스트를 통해 알아낸 사실을 공유하는 것에 지나지 않습니다. 테스트 환경은 Vista/IE 7이고, 그 외의 환경에서는 결과가 다를 수 있습니다.
테스트는 아래의 4가지 경우로 했습니다.
- 인터넷 영역에 속하는 웹 사이트를 IWebBrowser2::Navigate로 탐색
- 신뢰할 수 있는 영역에 속하는 웹 사이트를 IWebBrowser2::Navigate로 탐색
- 인터넷 영역에 속하는 웹 사이트를 IWebBrowser2::Navigate2로 탐색
- 신뢰할 수 있는 영역에 속하는 웹 사이트를 IWebBrowser2::Navigate2로 탐색
응용 프로그램은 상당히 간단합니다. MFC 대화창 유형으로 아래와 같이 4개의 버튼만을 가지고 있으며 각각의 이벤트 처리기는 위에서 나열한 4가지 경우의 테스트를 합니다.
[그림 1: 예제 응용 프로그램 실행 화면]
테스트를 위해 "
http://www.sysnet.pe.kr" 주소는 인터넷 영역에 속하고, "
https://www.sysnet.pe.kr" 주소는 신뢰할 수 있는 웹 사이트 영역에 등록해 두었습니다.
코드도 나열해 보면,
void CActiveXHostMfcDlg::OnBnClickedBtnNavigateInternetzonesite()
{
VARIANT vtEmpty;
vtEmpty.vt = VT_EMPTY;
CComPtr<IWebBrowser2> pWebBrowser2;
HRESULT hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER,
IID_IWebBrowser2,(LPVOID*)&pWebBrowser2);
hr = pWebBrowser2->Navigate(L"https://www.sysnet.pe.kr", &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);
}
void CActiveXHostMfcDlg::OnBnClickedBtnNavigateTrustedzonesite()
{
VARIANT vtEmpty;
vtEmpty.vt = VT_EMPTY;
CComPtr<IWebBrowser2> pWebBrowser2;
HRESULT hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER,
IID_IWebBrowser2,(LPVOID*)&pWebBrowser2);
hr = pWebBrowser2->Navigate(L"https://www.sysnet.pe.kr", &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);
hr = pWebBrowser2->put_Visible(VARIANT_TRUE);
}
void CActiveXHostMfcDlg::OnBnClickedBtnNavigate2Internetzonesite()
{
VARIANT vtEmpty;
vtEmpty.vt = VT_EMPTY;
VARIANT vtUrl;
vtUrl.vt = VT_BSTR;
vtUrl.bstrVal = ::SysAllocString(L"https://www.sysnet.pe.kr");
HRESULT hr;
CComPtr<IWebBrowser2> pWebBrowser2;
hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER,
IID_IWebBrowser2,(LPVOID*)&pWebBrowser2);
hr = pWebBrowser2->Navigate2(&vtUrl, &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);
}
void CActiveXHostMfcDlg::OnBnClickedBtnNavigate2Trustedzonesite()
{
VARIANT vtEmpty;
vtEmpty.vt = VT_EMPTY;
VARIANT vtUrl;
vtUrl.vt = VT_BSTR;
vtUrl.bstrVal = ::SysAllocString(L"https://www.sysnet.pe.kr");
HRESULT hr;
CComPtr<IWebBrowser2> pWebBrowser2;
hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER,
IID_IWebBrowser2,(LPVOID*)&pWebBrowser2);
hr = pWebBrowser2->Navigate2(&vtUrl, &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);
hr = pWebBrowser2->put_Visible(VARIANT_TRUE);
}
간단하지요. ^^ 각각의 메서드에 실행 결과에 대해서 정리해 보겠습니다.
1. Navigate(인터넷 영역의 웹 사이트 탐색)
빈 화면의 IE 웹 브라우저만 실행됩니다.
2. Navigate(신뢰할 수 있는 영역의 웹 사이트 탐색
이번 테스트가 좀 재미있습니다. 결과적으로, 이 테스트 코드는 아래와 같은 예외가 발생합니다.
"
First-chance exception at 0x77889b30 (msvcrt.dll) in ActiveXHostMfc.exe: 0xC0000005: Access violation reading location 0x0139a000.
Unhandled exception at 0x77889b30 (msvcrt.dll) in ActiveXHostMfc.exe: 0xC0000005: Access violation reading location 0x0139a000.
"
이 코드에서 &vtEmpty 인자를 NULL로 전달하면 또 다른 재미있는 결과가 나옵니다.
hr = pWebBrowser2->Navigate(L"https://www.sysnet.pe.kr", NULL, NULL, NULL, NULL);
// hr == 0x800706f4 A null reference pointer was passed to the stub.
hr 값은 실패를 나타내고, 그 순간의 Debug 창을 보면 예외가 발생한 것을 알 수 있습니다.
First-chance exception at 0x776342eb (kernel32.dll) in ActiveXHostMfc.exe:
0x000006F4: A null reference pointer was passed to the stub.
뒤이은, put_Visible(VARIANT_TRUE); 코드 덕분에 웹 브라우저 창이 뜨긴 하지만, 아래 화면처럼 "Connecting..."만을 보여준 체로 아무런 동작도 발생하지 않습니다.
[그림 2: Navigate 메서드로 신뢰할 수 있는 사이트를 방문하는 경우]
3. Navigate2(인터넷 영역의 웹사이트 탐색)
예상할 수 있겠지만, 이제부터는 정상적으로 웹 사이트 탐색이 가능합니다. 단지, 실행되는 MFC 응용 프로그램이 Medium 신뢰도를 갖고 있기 때문에, 인터넷 영역 웹 사이트를 호스팅하는 보호모드 프로세스에서 활성화된 웹 브라우저 인스턴스를 직접 제어할 수 없기 때문에 이후의 제어가 불가능합니다. 왜냐하면 중개 역할을 하는 ieuser.exe 프로세스를 거쳐서 iexplore.exe가 생성되기 때문입니다.
4. Navigate2(신뢰할 수 있는 영역의 웹 사이트 탐색)
Medium 신뢰도의 MFC 응용 프로그램이 보호 모드가 해제된 IE 웹 브라우저 인스턴스를 생성했기 때문에 직접적인 제어가 가능합니다. "3번"의 경우와는 달리 "put_Visible(VARIANT_TRUE);"를 해줘야만 화면에 브라우저가 나타납니다.
정리해 보면, Navigate 메서드는 비스타 버전의 IE 7에서는 정상 동작하지 않기 때문에 사용해서는 안됩니다. 또한, 같은 신뢰도 등급을 갖게 되는 신뢰할 수 있는 웹 사이트를 방문해야만 직접적인 제어가 가능하다는 점. (부가적으로 말씀드리면, IE 8에서는 Navigate2 메서드 하나만으로 Low/Medium 인스턴스를 모두 생성해서 제어할 수 있습니다.)
(
첨부한 파일은 위의 코드를 테스트해 본 프로젝트입니다.)