Re[2]: WebBrowser и редирект
От: Tilir Россия http://tilir.livejournal.com
Дата: 14.05.09 11:22
Оценка:
Здравствуйте, Flamer, Вы писали:

E>>Вопрос такой, как узнать url сайта на который происходит редирект, до того как WebBrowser обработает редирект и начнет загружать эту страницу?


F>Курить в MSDN DWebBrowserEvents2::BeforeNavigate2.


Совершенно точно не ловит. Я в своё время исследовал этот вопрос весьма подробно. У меня есть страничка http://tilir.6te.net/redirect.html, которая перебрасывает на www.google.com

Вот простенький код для воспроизведения:

#include <windows.h>
#include <exdisp.h>
#include <exdispid.h>
#include <atlbase.h>
#include <atlcom.h>
#include <mshtml.h>
#include <string>
#include <iostream>

class CEventHandler : public DWebBrowserEvents2 {
public:
  STDMETHODIMP QueryInterface(REFIID riid, void** ppv){
      *ppv = NULL;
      if (IsEqualGUID(riid, IID_IUnknown)){
        *ppv = (IUnknown *)this;
      }    
      if (IsEqualGUID(riid, IID_IDispatch)){
        *ppv = (IDispatch *)this;
      }
      if (IsEqualGUID(riid, __uuidof(DWebBrowserEvents2))){
        *ppv = (DWebBrowserEvents2 *)this;
      }
      if (*ppv) {
          ((IUnknown *)(*ppv))->AddRef();
          return S_OK;
      }
    return E_NOINTERFACE;
  }

  STDMETHODIMP_(ULONG) AddRef(){
    return InterlockedIncrement(&counter);
  }
  
  STDMETHODIMP_(ULONG) Release(){
      if (InterlockedDecrement(&counter) <= 0) {
        return 0;
      }
      return counter;    
  }
  
  STDMETHODIMP GetTypeInfoCount(UINT *pctinfo){
      *pctinfo = 0;
      return E_NOTIMPL;  
  }
  
  STDMETHODIMP GetTypeInfo(UINT /*iTInfo*/, LCID /*lcid*/, ITypeInfo** ppTInfo){
      *ppTInfo = NULL;
      return E_NOTIMPL;
  }
  
  STDMETHODIMP GetIDsOfNames(REFIID /* riid */, LPOLESTR* /* rgszNames */, UINT /* cNames */, LCID /* lcid */, DISPID* /* rgDispId */){
    return S_OK;
  }
  
  STDMETHODIMP Invoke(DISPID dispIdMember, REFIID /* riid */, LCID /* lcid */, WORD /* wFlags */, DISPPARAMS *pDispParams, VARIANT* /*pVarResult*/, EXCEPINFO* /* pExcepInfo */, UINT* /* *puArgErr */){
    int ndispid = dispIdMember;
    std::cout << "dispid = " << std::dec << ndispid << std::endl;
    if (DISPID_BEFORENAVIGATE2 == dispIdMember){
      int order = 7;      
      LPCWSTR wcsNav = pDispParams->rgvarg[order - 2].pvarVal->bstrVal;       
      std::wcout << L"navigate detected to: " << wcsNav << std::endl;      
    }
    return S_OK;
  }
private:
    volatile long counter;
};

bool checkRedirect(const wchar_t *wcsUrl){
  CComPtr<IWebBrowser2> webBrowser;
  HRESULT hr = webBrowser.CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER);
  hr = webBrowser->put_Visible(VARIANT_TRUE);
  
  CComQIPtr<IConnectionPoint> conn;
  CEventHandler handler;
  DWORD dwConnectionCookie;  
  
  CComQIPtr<IConnectionPointContainer> cp_container;    
  cp_container = webBrowser;
    hr = cp_container->FindConnectionPoint(DIID_DWebBrowserEvents2, &conn);
    CComPtr<IUnknown> unk;
    handler.QueryInterface(IID_IUnknown, (void**)&unk);
    conn->Advise(unk, &dwConnectionCookie);
  
  CComVariant vEmpty;  
  hr = webBrowser->Navigate(CComBSTR(wcsUrl), &vEmpty, &vEmpty, &vEmpty, &vEmpty);
  
  for(;;){
      VARIANT_BOOL vtb = VARIANT_TRUE;
      hr = webBrowser->get_Busy(&vtb);
      if (FAILED(hr) || (VARIANT_FALSE == vtb)){
        break;
      }
    }
    
    return false;
}

int main(int argc, char** argv){
  std::locale::global(std::locale(""));
  HRESULT hr = ::CoInitialize(NULL);
  std::cout << "CoInitialize with HR = " << std::hex << hr << std::endl;
  
  checkRedirect(L"http://tilir.6te.net/redirect.html");
  
  ::CoUninitialize();
  return 0;
}


Выводит вот такую статистику по DISPID'ам

[quote]
CoInitialize with HR = 0
dispid = 112
dispid = 250
navigate detected to: http://tilir.6te.net/redirect.html
dispid = 106
dispid = 112
dispid = 105
dispid = 105
dispid = 102
dispid = 108
dispid = 102
dispid = 102
dispid = 108
dispid = 102
dispid = 102
dispid = 270
dispid = 104
dispid = 102
dispid = 106
[/quote]

Коды можно посмотреть в exdispid.h, там ничего интересного. И переход на google.com не случается хотя по факту в конце мы уже там.

Я в своё время плюнул на это сделал воркэраунд, а теперь раз уж тема есть предлагаю на общее обсуждение.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.