WebBrowser Control (MFC) создан в отдельном потоке, работающем в Windows 7 и Vista, но в Windows XP - PullRequest
2 голосов
/ 13 сентября 2010

У меня есть CWnd в главном потоке и CWnd с элементом управления WebBrower, созданным в отдельном потоке. Это необходимо, потому что WebBrowser переходит к URL-адресам, на которых запущены JavaScript, которые блокируют WebBrowser. Поэтому я с помощью элемента управления WebBrowser в отдельном потоке предотвращаю зависание потока GUI. Также я сделал это в главной теме в моем приложении:

CCustomOccManager *pMgr = new CCustomOccManager();

AfxEnableControlContainer(pMgr);

Это для расширения элемента управления WebBrowser на мой интерфейс "window.external".

Механизм с отдельными потоками прекрасно работает в Windows 7 и Vista. Но в Windows XP я получаю подтверждения MFC.

Это мой код:

    m_WndMain.CreateEx(WS_EX_TOPMOST | WS_EX_TOOLWINDOW, m_mainWndClass, NULL, WS_POPUP, m_pArgs->m_WindowRect, NULL, 0);
    m_WndMain.ShowWindow(SW_SHOW);
    m_WndMain.UpdateWindow();

    CRect clientRect;
    m_WndMain.GetClientRect(&clientRect);

    /* !!! CreateControl FAILS IN WINDOWS XP (=ASSERT)!!! */
    m_CtrlBrowser.CreateControl(CLSID_WebBrowser, NULL, WS_VISIBLE | WS_CHILD, clientRect, &m_WndMain, AFX_IDW_PANE_FIRST);

    .....

MFC Assert (внутренняя линия 925 вызывает линию 305):

wincore.cpp, LINE 925
-----------------------------------
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL);   <--- pMap is NULL, ASSERT is raised


wincore.cpp, LINE 305
-----------------------------------
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();

...some code

pState->m_pmapHWND;  <--- m_pmapHWND is NULL!

Таким образом, «m_pmapHWND» имеет значение NULL в Windows XP. Но это не NULL в Vista, а 7.

В Windows XP, если я создаю элемент управления WebBrowser в главном потоке, он работает.

Так в чем проблема? Разные версии MFC или проблема с Windows XP?

1 Ответ

3 голосов
/ 13 сентября 2010

Я отладил MFC и обнаружил, что COM должен быть инициализирован во вновь созданном потоке.

Итак, в процедуре запуска потока я делаю

CoInitializeEx(NULL,  COINIT_APARTMENTTHREADED);

вСначала все работает.

Интересно, что в Windows 7 и Vista это не нужно, только XP.

...