| Index: src/plugin/PluginClass.cpp |
| =================================================================== |
| --- a/src/plugin/PluginClass.cpp |
| +++ b/src/plugin/PluginClass.cpp |
| @@ -39,9 +39,16 @@ |
| extern CComModule _Module; |
| -typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); |
| -typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPRECT); |
| -typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); |
| +namespace |
| +{ |
| + typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); |
| + typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPRECT); |
| + typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); |
| + |
| + CLOSETHEMEDATA pfnClose = NULL; |
| + DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; |
| + OPENTHEMEDATA pfnOpenThemeData = NULL; |
| +} |
| HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL }; |
| DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABLED, IDI_ICON_DEACTIVATED }; |
| @@ -49,20 +56,14 @@ |
| uint32_t iconWidth = 32; |
| CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; |
| - |
| -CLOSETHEMEDATA pfnClose = NULL; |
| -DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; |
| -OPENTHEMEDATA pfnOpenThemeData = NULL; |
| - |
| ATOM CPluginClass::s_atomPaneClass = NULL; |
| -HINSTANCE CPluginClass::s_hUxtheme = NULL; |
| std::set<CPluginClass*> CPluginClass::s_instances; |
| std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances; |
| - |
| CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; |
| CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; |
| +CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; |
| +CPluginClass::DetachedInitializerType CPluginClass::di; |
| -CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; |
| /* |
| * Without namespace declaration, the identifier "Rectangle" is ambiguous |
| @@ -103,11 +104,9 @@ |
| m_pWndProcStatus = NULL; |
| m_hTheme = NULL; |
| m_isInitializedOk = false; |
| - |
| - |
| m_tab = new CPluginTab(this); |
| - |
| Dictionary::Create(GetBrowserLanguage()); |
| + di.SpawnInitializer(); |
| } |
| CPluginClass::~CPluginClass() |
| @@ -115,6 +114,50 @@ |
| delete m_tab; |
| } |
| +/* |
| + * Because this initialization function does not throw, neither can EnsureInitialized(). |
| + */ |
| +void CPluginClass::Initializer() // noexcept |
| +{ |
| + try |
| + { |
| + /* |
| + * Initializes these static, anonymous-namespace variables |
| + * - pfnClose |
| + * - pfnDrawThemeBackground |
| + * - pfnOpenThemeData |
| + */ |
| + HINSTANCE UxthemeModule = ::GetModuleHandle(L"uxtheme.dll"); |
| + if (!UxthemeModule) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME, "CPluginClass::Initializer - GetModuleHandle(uxtheme.dll)"); |
| + } |
| + else |
| + { |
| + pfnClose = (CLOSETHEMEDATA)::GetProcAddress(UxthemeModule, "CloseThemeData"); |
| + if (!pfnClose) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_CLOSE, "CPluginClass::Initializer - GetProcAddress(CloseThemeData)"); |
| + } |
| + pfnDrawThemeBackground = (DRAWTHEMEBACKGROUND)::GetProcAddress(UxthemeModule, "DrawThemeBackground"); |
| + if (!pfnDrawThemeBackground) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_DRAW_BACKGROUND, "CPluginClass::Initializer - GetProcAddress(DrawThemeBackground)"); |
| + } |
| + pfnOpenThemeData = (OPENTHEMEDATA)::GetProcAddress(UxthemeModule, "OpenThemeData"); |
| + if (!pfnOpenThemeData) |
| + { |
| + DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_OPEN, "CPluginClass::Initializer - GetProcAddress(pfnOpenThemeData)"); |
| + } |
| + } |
| + } |
| + catch (...) |
| + { |
| + // Suppress all exceptions |
| + } |
| +} |
| + |
| + |
| HWND CPluginClass::GetBrowserHWND() const |
| { |
| if (!m_webBrowser2) |
| @@ -596,40 +639,6 @@ |
| s_mimeFilter->Unregister(); |
| } |
| - // Load theme module |
| - s_criticalSectionLocal.Lock(); |
| - { |
| - if (!s_hUxtheme) |
| - { |
| - s_hUxtheme = ::GetModuleHandle(L"uxtheme.dll"); |
| - if (s_hUxtheme) |
| - { |
| - pfnClose = (CLOSETHEMEDATA)::GetProcAddress(s_hUxtheme, "CloseThemeData"); |
| - if (!pfnClose) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_CLOSE, "Class::InitObject - GetProcAddress(CloseThemeData)"); |
| - } |
| - |
| - pfnDrawThemeBackground = (DRAWTHEMEBACKGROUND)::GetProcAddress(s_hUxtheme, "DrawThemeBackground"); |
| - if (!pfnDrawThemeBackground) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_DRAW_BACKGROUND, "Class::InitObject - GetProcAddress(DrawThemeBackground)"); |
| - } |
| - |
| - pfnOpenThemeData = (OPENTHEMEDATA)::GetProcAddress(s_hUxtheme, "OpenThemeData"); |
| - if (!pfnOpenThemeData) |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME_OPEN, "Class::InitObject - GetProcAddress(pfnOpenThemeData)"); |
| - } |
| - } |
| - else |
| - { |
| - DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXTHEME, "Class::InitObject - GetModuleHandle(uxtheme.dll)"); |
| - } |
| - } |
| - } |
| - s_criticalSectionLocal.Unlock(); |
| - |
| // Register pane class |
| if (!GetAtomPaneClass()) |
| { |
| @@ -902,29 +911,21 @@ |
| DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION_WELCOME, "Navigation::Welcome page failed") |
| } |
| } |
| -void CPluginClass::CloseTheme() |
| + |
| +void CPluginClass::UpdateTheme() |
| { |
| + EnsureInitialized(); // pfnClose, pfnOpenThemeData |
| if (m_hTheme) |
| { |
| if (pfnClose) |
| { |
| pfnClose(m_hTheme); |
| } |
| - |
| m_hTheme = NULL; |
| } |
| -} |
| - |
| -void CPluginClass::UpdateTheme() |
| -{ |
| - CloseTheme(); |
| - |
| if (pfnOpenThemeData) |
| { |
| m_hTheme = pfnOpenThemeData(m_hPaneWnd, L"STATUS"); |
| - if (!m_hTheme) |
| - { |
| - } |
| } |
| } |
| @@ -1413,6 +1414,7 @@ |
| else |
| { |
| // Draw background |
| + EnsureInitialized(); // pfnDrawThemeBackground |
| if (pfnDrawThemeBackground) |
| { |
| AdblockPlus::Rectangle rc = rcClient; |