| Index: src/plugin/PluginClass.cpp |
| =================================================================== |
| --- a/src/plugin/PluginClass.cpp |
| +++ b/src/plugin/PluginClass.cpp |
| @@ -90,12 +90,12 @@ |
| } |
| CPluginClass::CPluginClass() |
| - : m_webBrowser2(nullptr) |
| + : m_webBrowser2(nullptr), |
| + detachedInitializationFailed(false) |
| { |
| //Use this line to debug memory leaks |
| // _CrtDumpMemoryLeaks(); |
| - m_isAdvised = false; |
| m_hTabWnd = NULL; |
| m_hStatusBarWnd = NULL; |
| m_hPaneWnd = NULL; |
| @@ -173,11 +173,11 @@ |
| { |
| if (thisPtr == NULL) |
| return 0; |
| - if (!((CPluginClass*)thisPtr)->InitObject()) |
| + auto self = static_cast<CPluginClass*>(thisPtr); |
| + if (!self->InitObject()) |
| { |
| - ((CPluginClass*)thisPtr)->Unadvise(); |
| + self->detachedInitializationFailed = true; |
| } |
| - |
| return 0; |
| } |
| @@ -205,7 +205,6 @@ |
| { |
| DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT, "Class::SetSite - CoInitialize"); |
| } |
| - |
| /* |
| * We were instantiated as a BHO, so our site is always of type IWebBrowser2. |
| */ |
| @@ -227,38 +226,25 @@ |
| } |
| s_criticalSectionLocal.Unlock(); |
| + DEBUG_GENERAL("Loaded as BHO"); |
| try |
| { |
| - DEBUG_GENERAL("Loaded as BHO"); |
| - HRESULT hr = DispEventAdvise(m_webBrowser2); |
| - if (SUCCEEDED(hr)) |
| - { |
| - m_isAdvised = true; |
| - try |
| - { |
| - std::thread startInitObjectThread(StartInitObject, this); |
| - startInitObjectThread.detach(); // TODO: but actually we should wait for the thread in the dtr. |
| - } |
| - catch (const std::system_error& ex) |
| - { |
| - DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CREATE_PROCESS, |
| - "Class::Thread - Failed to create StartInitObject thread"); |
| - } |
| - } |
| - else |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVICE, "Class::SetSite - Advise"); |
| - } |
| + std::thread startInitObjectThread(StartInitObject, this); |
| + startInitObjectThread.detach(); // TODO: but actually we should wait for the thread in the dtr. |
| } |
| - catch (const std::runtime_error& ex) |
| + catch (const std::system_error& ex) |
| { |
| - DEBUG_EXCEPTION(ex); |
| - Unadvise(); |
| + detachedInitializationFailed = true; |
| + DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD_CREATE_PROCESS, |
| + "Class::Thread - Failed to create StartInitObject thread"); |
| } |
| + |
| + // Start event last, after everything is ready to go |
| + browserEvents.Start(this, m_webBrowser2); |
| } |
| else |
| { |
| - Unadvise(); |
| + browserEvents.Stop(); |
| // Destroy window |
| if (m_pWndProcStatus) |
| @@ -438,6 +424,8 @@ |
| { |
| try |
| { |
| + if (detachedInitializationFailed) return; |
| + |
| ATL::CComQIPtr<IWebBrowser2> webBrowser = frameBrowserDisp; |
| if (!webBrowser) |
| { |
| @@ -482,6 +470,7 @@ |
| // Entry point |
| void STDMETHODCALLTYPE CPluginClass::OnDownloadComplete() |
| { |
| + if (detachedInitializationFailed) return; |
| try |
| { |
| if (!m_webBrowser2) |
| @@ -500,6 +489,7 @@ |
| // Entry point |
| void STDMETHODCALLTYPE CPluginClass::OnDocumentComplete(IDispatch* frameBrowserDisp, VARIANT* /*urlOrPidl*/) |
| { |
| + if (detachedInitializationFailed) return; |
| try |
| { |
| DEBUG_NAVI(L"Navi::Document Complete"); |
| @@ -519,6 +509,7 @@ |
| // Entry point |
| void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, unsigned long validFlagsMask) |
| { |
| + if (detachedInitializationFailed) return; |
| try |
| { |
| DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); |
| @@ -549,6 +540,7 @@ |
| // Entry point |
| void STDMETHODCALLTYPE CPluginClass::OnCommandStateChange(long /*command*/, VARIANT_BOOL /*enable*/) |
| { |
| + if (detachedInitializationFailed) return; |
| try |
| { |
| if (m_hPaneWnd == NULL) |
| @@ -574,18 +566,6 @@ |
| } |
| } |
| -// Entry point |
| -void STDMETHODCALLTYPE CPluginClass::OnOnQuit() |
| -{ |
| - try |
| - { |
| - Unadvise(); |
| - } |
| - catch (...) |
| - { |
| - } |
| -} |
| - |
| bool CPluginClass::InitObject() |
| { |
| DEBUG_GENERAL("InitObject - begin"); |
| @@ -974,6 +954,7 @@ |
| STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText) |
| { |
| + if (detachedInitializationFailed) return; |
| if (cCmds == 0) return E_INVALIDARG; |
| if (prgCmds == 0) return E_POINTER; |
| @@ -1183,6 +1164,7 @@ |
| STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, VARIANTARG*) |
| { |
| + if (detachedInitializationFailed) return; |
| HWND hBrowserWnd = GetBrowserHWND(); |
| if (!hBrowserWnd) |
| { |
| @@ -1588,29 +1570,6 @@ |
| } |
| } |
| - |
| -void CPluginClass::Unadvise() |
| -{ |
| - if (!m_webBrowser2) |
| - { |
| - DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::Unadvise - Reached with m_webBrowser2 == nullptr"); |
| - return; |
| - } |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - if (m_isAdvised) |
| - { |
| - HRESULT hr = DispEventUnadvise(m_webBrowser2); |
| - if (FAILED(hr)) |
| - { |
| - DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_UNADVISE, "Class::Unadvise - Unadvise"); |
| - } |
| - m_isAdvised = false; |
| - } |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| -} |
| - |
| HICON CPluginClass::GetIcon(int type) |
| { |
| HICON icon = NULL; |