Re[4]: Обработка события DISPID_NAVIGATEERROR
От: REASY  
Дата: 09.05.11 17:15
Оценка:
Решил эту проблему. Кому может понадобиться. Идея — создаю тред, внутри которого создается окно
#define WM_NAVIGATE_ERROR WM_USER + 0x100

DWORD WINAPI Run(LPVOID lpParam) 
{
    CoInitialize(NULL);

    HANDLE hMutex = *((HANDLE *)lpParam);
    DWORD dwRes = WaitForSingleObject(hMutex, INFINITE);
    
    HWND hwnd;
    MSG msg;
    WNDCLASS w;
    memset(&w,0,sizeof(WNDCLASS));
    w.style = CS_HREDRAW | CS_VREDRAW;
    w.cbClsExtra = w.cbWndExtra = 0;    
    w.lpfnWndProc = WndProc;
    w.hInstance = NULL;
    w.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    w.lpszClassName = L"Invisible Class for IE";
    w.lpszMenuName = NULL;
    w.hCursor = NULL;
    RegisterClass(&w);
    hwnd = CreateWindow(w.lpszClassName,L"BLABLABLA",WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,NULL,NULL);
    if (hwnd == NULL){      
        ReleaseMutex(hMutex);
        return 1;
    }
    m_InvisibleHWND = hwnd;

    UpdateWindow(hwnd);

    ReleaseMutex(hMutex);

    while (GetMessage(&msg, NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    
    CoUninitialize();
    return msg.wParam;

}

Функция обработки сообщений окна. Т.к. разные треды, то нужен маршалинг указателя. Для этого воспользуемся CComGITPtr:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_NAVIGATE_ERROR:
        {
            CComVariant varURL = CComBSTR(TEXT("http://ya.ru/"));
            CComVariant vEmpty;
            HRESULT hr;

            IWebBrowser2* pWebBrowser;
            DWORD dwCookie = (DWORD)wParam;

            ATLASSERT(dwCookie != 0);
            
            CComGITPtr<IWebBrowser2> pFromGIT(dwCookie);            
            hr = pFromGIT.CopyTo(&pWebBrowser);    
            if (hr == S_OK)
                hr = pWebBrowser->Navigate2(&varURL, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
            break;
    
        }
        
    case WM_DESTROY:
        PostQuitMessage(0);        
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

В Invoke() при обработке DISPID_NAVIGATEERROR отправляю своему созданному окну сообщение, где WPARAM — это cookie CComGITPtr:
if (dwStatusCode == INET_E_RESOURCE_NOT_FOUND)
{
   DWORD m_GITCookie = 0;
   CComGITPtr<IWebBrowser2> pToGIT(m_spWebBrowser);    
   m_GITCookie = pToGIT.Detach();        
   ATLASSERT(m_GITCookie!=0);
   PostMessage(PluginBHO::GetHWND(), WM_NAVIGATE_ERROR, (WPARAM)m_GITCookie, 0);
}
dispid_navigateerror маршалинг
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.