Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/plugin/PluginClass.cpp

Issue 29332665: Issue #3391 - Initialize themed drawing variables using DetachedInitializer
Patch Set: Created Dec. 14, 2015, 6:06 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/plugin/PluginClass.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 21 matching lines...) Expand all
32 #include "../shared/Version.h" 32 #include "../shared/Version.h"
33 #include <thread> 33 #include <thread>
34 #include <array> 34 #include <array>
35 35
36 #ifdef DEBUG_HIDE_EL 36 #ifdef DEBUG_HIDE_EL
37 DWORD profileTime = 0; 37 DWORD profileTime = 0;
38 #endif 38 #endif
39 39
40 extern CComModule _Module; 40 extern CComModule _Module;
41 41
42 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); 42 namespace
43 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR ECT); 43 {
44 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); 44 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR);
45 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, L PRECT);
46 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE);
47
48 CLOSETHEMEDATA pfnClose = NULL;
49 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL;
50 OPENTHEMEDATA pfnOpenThemeData = NULL;
51 }
45 52
46 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL }; 53 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL };
47 DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABL ED, IDI_ICON_DEACTIVATED }; 54 DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABL ED, IDI_ICON_DEACTIVATED };
48 uint32_t iconHeight = 32; 55 uint32_t iconHeight = 32;
49 uint32_t iconWidth = 32; 56 uint32_t iconWidth = 32;
50 57
51 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; 58 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL;
52
53 CLOSETHEMEDATA pfnClose = NULL;
54 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL;
55 OPENTHEMEDATA pfnOpenThemeData = NULL;
56
57 ATOM CPluginClass::s_atomPaneClass = NULL; 59 ATOM CPluginClass::s_atomPaneClass = NULL;
58 HINSTANCE CPluginClass::s_hUxtheme = NULL;
59 std::set<CPluginClass*> CPluginClass::s_instances; 60 std::set<CPluginClass*> CPluginClass::s_instances;
60 std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances; 61 std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances;
61
62 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; 62 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal;
63 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; 63 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow;
64 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2;
65 CPluginClass::DetachedInitializerType CPluginClass::di;
64 66
65 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2;
66 67
67 /* 68 /*
68 * Without namespace declaration, the identifier "Rectangle" is ambiguous 69 * Without namespace declaration, the identifier "Rectangle" is ambiguous
69 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx 70 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx
70 */ 71 */
71 namespace AdblockPlus 72 namespace AdblockPlus
72 { 73 {
73 /** 74 /**
74 * Replacement for ATL type CRect. 75 * Replacement for ATL type CRect.
75 */ 76 */
(...skipping 20 matching lines...) Expand all
96 // _CrtDumpMemoryLeaks(); 97 // _CrtDumpMemoryLeaks();
97 98
98 m_isAdvised = false; 99 m_isAdvised = false;
99 m_hTabWnd = NULL; 100 m_hTabWnd = NULL;
100 m_hStatusBarWnd = NULL; 101 m_hStatusBarWnd = NULL;
101 m_hPaneWnd = NULL; 102 m_hPaneWnd = NULL;
102 m_nPaneWidth = 0; 103 m_nPaneWidth = 0;
103 m_pWndProcStatus = NULL; 104 m_pWndProcStatus = NULL;
104 m_hTheme = NULL; 105 m_hTheme = NULL;
105 m_isInitializedOk = false; 106 m_isInitializedOk = false;
106
107
108 m_tab = new CPluginTab(this); 107 m_tab = new CPluginTab(this);
109
110 Dictionary::Create(GetBrowserLanguage()); 108 Dictionary::Create(GetBrowserLanguage());
109 di.SpawnInitializer();
111 } 110 }
112 111
113 CPluginClass::~CPluginClass() 112 CPluginClass::~CPluginClass()
114 { 113 {
115 delete m_tab; 114 delete m_tab;
116 } 115 }
117 116
117 /*
118 * Because this initialization function does not throw, neither can EnsureInitia lized().
119 */
120 void CPluginClass::Initializer() // noexcept
121 {
122 try
123 {
124 /*
125 * Initializes these static, anonymous-namespace variables
126 * - pfnClose
127 * - pfnDrawThemeBackground
128 * - pfnOpenThemeData
129 */
130 HINSTANCE UxthemeModule = ::GetModuleHandle(L"uxtheme.dll");
131 if (!UxthemeModule)
132 {
133 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_UXT HEME, "CPluginClass::Initializer - GetModuleHandle(uxtheme.dll)");
134 }
135 else
136 {
137 pfnClose = (CLOSETHEMEDATA)::GetProcAddress(UxthemeModule, "CloseThemeData ");
138 if (!pfnClose)
139 {
140 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_U XTHEME_CLOSE, "CPluginClass::Initializer - GetProcAddress(CloseThemeData)");
141 }
142 pfnDrawThemeBackground = (DRAWTHEMEBACKGROUND)::GetProcAddress(UxthemeModu le, "DrawThemeBackground");
143 if (!pfnDrawThemeBackground)
144 {
145 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_U XTHEME_DRAW_BACKGROUND, "CPluginClass::Initializer - GetProcAddress(DrawThemeBac kground)");
146 }
147 pfnOpenThemeData = (OPENTHEMEDATA)::GetProcAddress(UxthemeModule, "OpenThe meData");
148 if (!pfnOpenThemeData)
149 {
150 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_U XTHEME_OPEN, "CPluginClass::Initializer - GetProcAddress(pfnOpenThemeData)");
151 }
152 }
153 }
154 catch (...)
155 {
156 // Suppress all exceptions
157 }
158 }
159
160
118 HWND CPluginClass::GetBrowserHWND() const 161 HWND CPluginClass::GetBrowserHWND() const
119 { 162 {
120 if (!m_webBrowser2) 163 if (!m_webBrowser2)
121 { 164 {
122 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::GetBrowserHWND - Reached with m_webB rowser2 == nullptr"); 165 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::GetBrowserHWND - Reached with m_webB rowser2 == nullptr");
123 return nullptr; 166 return nullptr;
124 } 167 }
125 SHANDLE_PTR hBrowserWndHandle = 0; 168 SHANDLE_PTR hBrowserWndHandle = 0;
126 HRESULT hr = m_webBrowser2->get_HWND(&hBrowserWndHandle); 169 HRESULT hr = m_webBrowser2->get_HWND(&hBrowserWndHandle);
127 if (FAILED(hr)) 170 if (FAILED(hr))
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 } 211 }
169 return url; 212 return url;
170 } 213 }
171 214
172 DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr) 215 DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr)
173 { 216 {
174 if (thisPtr == NULL) 217 if (thisPtr == NULL)
175 return 0; 218 return 0;
176 if (!((CPluginClass*)thisPtr)->InitObject()) 219 if (!((CPluginClass*)thisPtr)->InitObject())
177 { 220 {
178 ((CPluginClass*)thisPtr)->Unadvise(); 221 ((CPluginClass*)thisPtr)->Unadvise();
Eric 2015/12/14 18:46:02 This statement is the motivation to clean up detac
179 } 222 }
180 223
181 return 0; 224 return 0;
182 } 225 }
183 226
184 /* 227 /*
185 * IE calls this when it creates a new browser window or tab, immediately after it also 228 * IE calls this when it creates a new browser window or tab, immediately after it also
186 * creates the object. The argument 'unknownSite' in is the OLE "site" of the ob ject, 229 * creates the object. The argument 'unknownSite' in is the OLE "site" of the ob ject,
187 * which is an IWebBrowser2 interface associated with the window/tab. 230 * which is an IWebBrowser2 interface associated with the window/tab.
188 * 231 *
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 try 273 try
231 { 274 {
232 DEBUG_GENERAL("Loaded as BHO"); 275 DEBUG_GENERAL("Loaded as BHO");
233 HRESULT hr = DispEventAdvise(m_webBrowser2); 276 HRESULT hr = DispEventAdvise(m_webBrowser2);
234 if (SUCCEEDED(hr)) 277 if (SUCCEEDED(hr))
235 { 278 {
236 m_isAdvised = true; 279 m_isAdvised = true;
237 try 280 try
238 { 281 {
239 std::thread startInitObjectThread(StartInitObject, this); 282 std::thread startInitObjectThread(StartInitObject, this);
240 startInitObjectThread.detach(); // TODO: but actually we should wait for the thread in the dtr. 283 startInitObjectThread.detach(); // TODO: but actually we should wait for the thread in the dtr.
Eric 2015/12/14 18:46:01 This comment is sort-of-right; at least it express
241 } 284 }
242 catch (const std::system_error& ex) 285 catch (const std::system_error& ex)
243 { 286 {
244 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_TH READ_CREATE_PROCESS, 287 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_TH READ_CREATE_PROCESS,
245 "Class::Thread - Failed to create StartInitObject thread"); 288 "Class::Thread - Failed to create StartInitObject thread");
246 } 289 }
247 } 290 }
248 else 291 else
249 { 292 {
250 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVIC E, "Class::SetSite - Advise"); 293 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVIC E, "Class::SetSite - Advise");
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 bool CPluginClass::InitObject() 632 bool CPluginClass::InitObject()
590 { 633 {
591 DEBUG_GENERAL("InitObject - begin"); 634 DEBUG_GENERAL("InitObject - begin");
592 CPluginSettings* settings = CPluginSettings::GetInstance(); 635 CPluginSettings* settings = CPluginSettings::GetInstance();
593 636
594 if (!settings->GetPluginEnabled()) 637 if (!settings->GetPluginEnabled())
595 { 638 {
596 s_mimeFilter->Unregister(); 639 s_mimeFilter->Unregister();
597 } 640 }
598 641
599 // Load theme module
600 s_criticalSectionLocal.Lock();
601 {
602 if (!s_hUxtheme)
603 {
604 s_hUxtheme = ::GetModuleHandle(L"uxtheme.dll");
605 if (s_hUxtheme)
606 {
607 pfnClose = (CLOSETHEMEDATA)::GetProcAddress(s_hUxtheme, "CloseThemeData" );
608 if (!pfnClose)
609 {
610 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET _UXTHEME_CLOSE, "Class::InitObject - GetProcAddress(CloseThemeData)");
611 }
612
613 pfnDrawThemeBackground = (DRAWTHEMEBACKGROUND)::GetProcAddress(s_hUxthem e, "DrawThemeBackground");
614 if (!pfnDrawThemeBackground)
615 {
616 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET _UXTHEME_DRAW_BACKGROUND, "Class::InitObject - GetProcAddress(DrawThemeBackgroun d)");
617 }
618
619 pfnOpenThemeData = (OPENTHEMEDATA)::GetProcAddress(s_hUxtheme, "OpenThem eData");
620 if (!pfnOpenThemeData)
621 {
622 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET _UXTHEME_OPEN, "Class::InitObject - GetProcAddress(pfnOpenThemeData)");
623 }
624 }
625 else
626 {
627 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_U XTHEME, "Class::InitObject - GetModuleHandle(uxtheme.dll)");
628 }
629 }
630 }
631 s_criticalSectionLocal.Unlock();
632
633 // Register pane class 642 // Register pane class
634 if (!GetAtomPaneClass()) 643 if (!GetAtomPaneClass())
635 { 644 {
636 WNDCLASSEX wcex; 645 WNDCLASSEX wcex;
637 646
638 wcex.cbSize = sizeof(wcex); 647 wcex.cbSize = sizeof(wcex);
639 wcex.style = 0; 648 wcex.style = 0;
640 wcex.lpfnWndProc = (WNDPROC)PaneWindowProc; 649 wcex.lpfnWndProc = (WNDPROC)PaneWindowProc;
641 wcex.cbClsExtra = 0; 650 wcex.cbClsExtra = 0;
642 wcex.cbWndExtra = 0; 651 wcex.cbWndExtra = 0;
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 { 904 {
896 vFlags.intVal = navOpenInNewWindow; 905 vFlags.intVal = navOpenInNewWindow;
897 hr = GetAsyncBrowser()->Navigate(navigatePath, &vFlags, NULL, NULL, NULL); 906 hr = GetAsyncBrowser()->Navigate(navigatePath, &vFlags, NULL, NULL, NULL);
898 } 907 }
899 908
900 if (FAILED(hr)) 909 if (FAILED(hr))
901 { 910 {
902 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION_WELCOME , "Navigation::Welcome page failed") 911 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION_WELCOME , "Navigation::Welcome page failed")
903 } 912 }
904 } 913 }
905 void CPluginClass::CloseTheme() 914
915 void CPluginClass::UpdateTheme()
906 { 916 {
917 EnsureInitialized(); // pfnClose, pfnOpenThemeData
907 if (m_hTheme) 918 if (m_hTheme)
908 { 919 {
909 if (pfnClose) 920 if (pfnClose)
910 { 921 {
911 pfnClose(m_hTheme); 922 pfnClose(m_hTheme);
912 } 923 }
913
914 m_hTheme = NULL; 924 m_hTheme = NULL;
915 } 925 }
926 if (pfnOpenThemeData)
927 {
928 m_hTheme = pfnOpenThemeData(m_hPaneWnd, L"STATUS");
929 }
916 } 930 }
917 931
918 void CPluginClass::UpdateTheme()
919 {
920 CloseTheme();
921
922 if (pfnOpenThemeData)
923 {
924 m_hTheme = pfnOpenThemeData(m_hPaneWnd, L"STATUS");
925 if (!m_hTheme)
926 {
927 }
928 }
929 }
930
931 932
932 CPluginClass* CPluginClass::FindInstance(HWND hStatusBarWnd) 933 CPluginClass* CPluginClass::FindInstance(HWND hStatusBarWnd)
933 { 934 {
934 CPluginClass* result = nullptr; 935 CPluginClass* result = nullptr;
935 936
936 s_criticalSectionLocal.Lock(); 937 s_criticalSectionLocal.Lock();
937 { 938 {
938 for (auto instance : s_instances) 939 for (auto instance : s_instances)
939 { 940 {
940 if (instance->m_hStatusBarWnd == hStatusBarWnd) 941 if (instance->m_hStatusBarWnd == hStatusBarWnd)
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 1407
1407 nDrawEdge = 3; 1408 nDrawEdge = 3;
1408 rcClient.left += 3; 1409 rcClient.left += 3;
1409 1410
1410 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); 1411 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT);
1411 } 1412 }
1412 // Themed background drawing 1413 // Themed background drawing
1413 else 1414 else
1414 { 1415 {
1415 // Draw background 1416 // Draw background
1417 EnsureInitialized(); // pfnDrawThemeBackground
1416 if (pfnDrawThemeBackground) 1418 if (pfnDrawThemeBackground)
1417 { 1419 {
1418 AdblockPlus::Rectangle rc = rcClient; 1420 AdblockPlus::Rectangle rc = rcClient;
1419 rc.right -= 2; 1421 rc.right -= 2;
1420 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL); 1422 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL);
1421 } 1423 }
1422 1424
1423 // Copy separator picture to left side 1425 // Copy separator picture to left side
1424 int nHeight = rcClient.Height(); 1426 int nHeight = rcClient.Height();
1425 int nWidth = rcClient.Width() - 2; 1427 int nWidth = rcClient.Width() - 2;
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 s_criticalSectionLocal.Unlock(); 1635 s_criticalSectionLocal.Unlock();
1634 1636
1635 return icon; 1637 return icon;
1636 } 1638 }
1637 1639
1638 ATOM CPluginClass::GetAtomPaneClass() 1640 ATOM CPluginClass::GetAtomPaneClass()
1639 { 1641 {
1640 return s_atomPaneClass; 1642 return s_atomPaneClass;
1641 } 1643 }
1642 1644
OLDNEW
« no previous file with comments | « src/plugin/PluginClass.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld