LEFT | RIGHT |
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-2016 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 |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 #include "PluginStdAfx.h" | 18 #include "PluginStdAfx.h" |
19 | 19 |
20 #include "PluginClass.h" | 20 #include "PluginClass.h" |
21 #include "PluginSettings.h" | 21 #include "PluginSettings.h" |
22 #include "PluginSystem.h" | 22 #include "PluginSystem.h" |
23 #include "PluginFilter.h" | 23 #include "PluginFilter.h" |
24 #include "PluginMimeFilterClient.h" | 24 #include "PluginMimeFilterClient.h" |
25 #include "AdblockPlusClient.h" | 25 #include "AdblockPlusClient.h" |
26 #include "PluginClientBase.h" | 26 #include "PluginClientBase.h" |
27 #include "PluginClientFactory.h" | 27 #include "PluginClientFactory.h" |
28 #include "PluginUtil.h" | 28 #include "PluginUtil.h" |
29 #include "../shared/Utils.h" | 29 #include "../shared/Utils.h" |
30 #include "../shared/Dictionary.h" | 30 #include "../shared/Dictionary.h" |
31 #include "IeVersion.h" | 31 #include "IeVersion.h" |
32 #include "../shared/Version.h" | 32 #include "../shared/Version.h" |
| 33 #include "Instances.h" |
33 #include <thread> | 34 #include <thread> |
34 #include <array> | 35 #include <array> |
35 | 36 |
36 #ifdef DEBUG_HIDE_EL | 37 #ifdef DEBUG_HIDE_EL |
37 DWORD profileTime = 0; | 38 DWORD profileTime = 0; |
38 #endif | 39 #endif |
39 | 40 |
40 extern CComModule _Module; | 41 extern CComModule _Module; |
41 | 42 |
42 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); | 43 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); |
43 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR
ECT); | 44 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR
ECT); |
44 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); | 45 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); |
45 | 46 |
46 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL }; | 47 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 }; | 48 DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABL
ED, IDI_ICON_DEACTIVATED }; |
48 uint32_t iconHeight = 32; | 49 uint32_t iconHeight = 32; |
49 uint32_t iconWidth = 32; | 50 uint32_t iconWidth = 32; |
50 | 51 |
51 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; | 52 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; |
52 | 53 |
53 CLOSETHEMEDATA pfnClose = NULL; | 54 CLOSETHEMEDATA pfnClose = NULL; |
54 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; | 55 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; |
55 OPENTHEMEDATA pfnOpenThemeData = NULL; | 56 OPENTHEMEDATA pfnOpenThemeData = NULL; |
56 | 57 |
57 ATOM CPluginClass::s_atomPaneClass = NULL; | 58 ATOM CPluginClass::s_atomPaneClass = NULL; |
58 HINSTANCE CPluginClass::s_hUxtheme = NULL; | 59 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 | 61 |
62 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; | 62 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; |
63 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; | 63 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; |
64 | 64 |
65 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; | 65 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; |
| 66 |
| 67 namespace |
| 68 { |
| 69 /** |
| 70 * A synchronized map whose key is always the current thread ID. |
| 71 */ |
| 72 class CurrentThreadMap |
| 73 : public SyncMap<DWORD, CPluginClass*, nullptr> |
| 74 { |
| 75 typedef SyncMap<DWORD, CPluginClass*, nullptr> Base; |
| 76 |
| 77 public: |
| 78 bool AddIfAbsent(CPluginClass* p) |
| 79 { |
| 80 return Base::AddIfAbsent(::GetCurrentThreadId(), p); |
| 81 } |
| 82 |
| 83 bool RemoveAndCheck() |
| 84 { |
| 85 return Base::RemoveIfPresent(::GetCurrentThreadId()); |
| 86 } |
| 87 |
| 88 CPluginClass* Locate() |
| 89 { |
| 90 return Base::Locate(::GetCurrentThreadId()); |
| 91 } |
| 92 }; |
| 93 |
| 94 /** |
| 95 * Map from thread ID's to CPluginClass instances |
| 96 */ |
| 97 CurrentThreadMap threadMap; |
| 98 } |
66 | 99 |
67 /* | 100 /* |
68 * Without namespace declaration, the identifier "Rectangle" is ambiguous | 101 * Without namespace declaration, the identifier "Rectangle" is ambiguous |
69 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85)
.aspx | 102 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85)
.aspx |
70 */ | 103 */ |
71 namespace AdblockPlus | 104 namespace AdblockPlus |
72 { | 105 { |
73 /** | 106 /** |
74 * Replacement for ATL type CRect. | 107 * Replacement for ATL type CRect. |
75 */ | 108 */ |
76 class Rectangle | 109 class Rectangle |
77 : public RECT | 110 : public RECT |
78 { | 111 { |
79 public: | 112 public: |
80 int Height() const | 113 unsigned long Height() const |
81 { | 114 { |
82 return bottom - top; | 115 if (bottom < top) |
83 } | 116 { |
84 | 117 throw std::runtime_error("invariant violation: rectangle bottom < top"); |
85 int Width() const | 118 } |
86 { | 119 return static_cast<unsigned long>(bottom - top); |
87 return right - left; | 120 } |
| 121 |
| 122 unsigned long Width() const |
| 123 { |
| 124 if (right < left) |
| 125 { |
| 126 throw std::runtime_error("invariant violation: rectangle right < left"); |
| 127 } |
| 128 return static_cast<unsigned long>(right - left); |
88 } | 129 } |
89 }; | 130 }; |
90 } | 131 } |
91 | 132 |
92 CPluginClass::CPluginClass() | 133 CPluginClass::CPluginClass() |
93 : m_webBrowser2(nullptr), | 134 : m_webBrowser2(nullptr), |
94 detachedInitializationFailed(false) | 135 detachedInitializationFailed(false) |
95 { | 136 { |
| 137 DEBUG_GENERAL([this]() -> std::wstring |
| 138 { |
| 139 std::wstring s = L"CPluginClass::<constructor>, this = "; |
| 140 s += ToHexLiteral(this); |
| 141 return s; |
| 142 }()); |
| 143 |
96 //Use this line to debug memory leaks | 144 //Use this line to debug memory leaks |
97 // _CrtDumpMemoryLeaks(); | 145 // _CrtDumpMemoryLeaks(); |
98 | 146 |
99 m_hTabWnd = NULL; | 147 m_hTabWnd = NULL; |
100 m_hStatusBarWnd = NULL; | 148 m_hStatusBarWnd = NULL; |
101 m_hPaneWnd = NULL; | 149 m_hPaneWnd = NULL; |
102 m_nPaneWidth = 0; | 150 m_nPaneWidth = 0; |
103 m_pWndProcStatus = NULL; | 151 m_pWndProcStatus = NULL; |
104 m_hTheme = NULL; | 152 m_hTheme = NULL; |
105 m_isInitializedOk = false; | 153 m_isInitializedOk = false; |
106 | 154 m_tab = new CPluginTab(); |
107 | |
108 m_tab = new CPluginTab(this); | |
109 | |
110 Dictionary::Create(GetBrowserLanguage()); | 155 Dictionary::Create(GetBrowserLanguage()); |
111 } | 156 } |
112 | 157 |
113 CPluginClass::~CPluginClass() | 158 CPluginClass::~CPluginClass() |
114 { | 159 { |
| 160 DEBUG_GENERAL([this]() -> std::wstring |
| 161 { |
| 162 std::wstring s = L"CPluginClass::<destructor>, this = "; |
| 163 s += ToHexLiteral(this); |
| 164 return s; |
| 165 }()); |
| 166 |
115 delete m_tab; | 167 delete m_tab; |
116 } | 168 } |
117 | 169 |
118 HWND CPluginClass::GetBrowserHWND() const | 170 HWND CPluginClass::GetBrowserHWND() const |
119 { | 171 { |
120 if (!m_webBrowser2) | 172 if (!m_webBrowser2) |
121 { | 173 { |
122 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::GetBrowserHWND - Reached with m_webB
rowser2 == nullptr"); | 174 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::GetBrowserHWND - Reached with m_webB
rowser2 == nullptr"); |
123 return nullptr; | 175 return nullptr; |
124 } | 176 } |
(...skipping 24 matching lines...) Expand all Loading... |
149 | 201 |
150 return browser; | 202 return browser; |
151 } | 203 } |
152 | 204 |
153 std::wstring CPluginClass::GetBrowserUrl() const | 205 std::wstring CPluginClass::GetBrowserUrl() const |
154 { | 206 { |
155 std::wstring url; | 207 std::wstring url; |
156 if (m_webBrowser2) | 208 if (m_webBrowser2) |
157 { | 209 { |
158 CComBSTR bstrURL; | 210 CComBSTR bstrURL; |
159 if (SUCCEEDED(m_webBrowser2->get_LocationURL(&bstrURL)) && bstrURL) | 211 if (SUCCEEDED(m_webBrowser2->get_LocationURL(&bstrURL))) |
160 { | 212 { |
161 url = std::wstring(bstrURL, SysStringLen(bstrURL)); | 213 url = ToWstring(bstrURL); |
162 } | 214 } |
163 } | 215 } |
164 else | 216 else |
165 { | 217 { |
166 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::GetBrowserUrl - Reached with m_webBr
owser2 == nullptr"); | 218 DEBUG_GENERAL(L"CPluginClass::GetBrowserUrl - Reached with m_webBrowser2 ==
nullptr (probable invariant violation)"); |
| 219 } |
| 220 if (url.empty()) |
| 221 { |
167 url = m_tab->GetDocumentUrl(); | 222 url = m_tab->GetDocumentUrl(); |
168 } | 223 } |
169 return url; | 224 return url; |
170 } | 225 } |
171 | 226 |
172 DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr) | 227 DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr) |
173 { | 228 { |
174 if (thisPtr == NULL) | 229 if (thisPtr == NULL) |
175 return 0; | 230 return 0; |
176 auto self = static_cast<CPluginClass*>(thisPtr); | 231 auto self = static_cast<CPluginClass*>(thisPtr); |
(...skipping 13 matching lines...) Expand all Loading... |
190 * 'unknownSite' will be null. Extraordinarily, this is sometimes _not_ called w
hen IE | 245 * 'unknownSite' will be null. Extraordinarily, this is sometimes _not_ called w
hen IE |
191 * is shutting down. Thus 'SetSite(nullptr)' has some similarities with a destru
ctor, | 246 * is shutting down. Thus 'SetSite(nullptr)' has some similarities with a destru
ctor, |
192 * but it is not a proper substitute for one. | 247 * but it is not a proper substitute for one. |
193 */ | 248 */ |
194 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) | 249 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) |
195 { | 250 { |
196 try | 251 try |
197 { | 252 { |
198 if (unknownSite) | 253 if (unknownSite) |
199 { | 254 { |
200 | 255 DEBUG_GENERAL(L"==========================================================
======================\nNEW TAB UI\n============================================
===================================="); |
201 DEBUG_GENERAL(L"==========================================================
======================\nNEW TAB UI\n============================================
====================================") | |
202 | 256 |
203 HRESULT hr = ::CoInitialize(NULL); | 257 HRESULT hr = ::CoInitialize(NULL); |
204 if (FAILED(hr)) | 258 if (FAILED(hr)) |
205 { | 259 { |
206 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT,
"Class::SetSite - CoInitialize"); | 260 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT,
"Class::SetSite - CoInitialize"); |
207 } | 261 } |
208 /* | 262 /* |
209 * We were instantiated as a BHO, so our site is always of type IWebBrowse
r2. | 263 * We were instantiated as a BHO, so our site is always of type IWebBrowse
r2. |
210 */ | 264 */ |
211 m_webBrowser2 = ATL::CComQIPtr<IWebBrowser2>(unknownSite); | 265 m_webBrowser2 = ATL::CComQIPtr<IWebBrowser2>(unknownSite); |
212 if (!m_webBrowser2) | 266 if (!m_webBrowser2) |
213 { | 267 { |
214 throw std::logic_error("CPluginClass::SetSite - Unable to convert site p
ointer to IWebBrowser2*"); | 268 throw std::logic_error("CPluginClass::SetSite - Unable to convert site p
ointer to IWebBrowser2*"); |
215 } | 269 } |
| 270 DEBUG_GENERAL([this]() -> std::wstring |
| 271 { |
| 272 std::wstringstream ss; |
| 273 ss << L"CPluginClass::SetSite, this = " << ToHexLiteral(this); |
| 274 ss << L", browser = " << ToHexLiteral(m_webBrowser2); |
| 275 return ss.str(); |
| 276 }()); |
| 277 |
| 278 /* |
| 279 * Add ourselves to the thread map. |
| 280 */ |
| 281 if (!threadMap.AddIfAbsent(this)) |
| 282 { |
| 283 throw std::logic_error("CPluginClass::SetSite - May not overwrite existi
ng entry in thread map"); |
| 284 } |
216 | 285 |
217 //register the mimefilter | 286 //register the mimefilter |
218 //and only mimefilter | 287 //and only mimefilter |
219 //on some few computers the mimefilter does not get properly registered wh
en it is done on another thread | 288 //on some few computers the mimefilter does not get properly registered wh
en it is done on another thread |
220 s_criticalSectionLocal.Lock(); | 289 s_criticalSectionLocal.Lock(); |
221 { | 290 { |
222 // Always register on startup, then check if we need to unregister in a
separate thread | 291 // Always register on startup, then check if we need to unregister in a
separate thread |
223 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); | 292 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
224 s_asyncWebBrowser2 = unknownSite; | 293 s_asyncWebBrowser2 = unknownSite; |
225 s_instances.insert(this); | 294 s_instances.insert(this); |
226 } | 295 } |
227 s_criticalSectionLocal.Unlock(); | 296 s_criticalSectionLocal.Unlock(); |
228 | 297 |
229 DEBUG_GENERAL("Loaded as BHO"); | |
230 try | 298 try |
231 { | 299 { |
232 std::thread startInitObjectThread(StartInitObject, this); | 300 std::thread startInitObjectThread(StartInitObject, this); |
233 startInitObjectThread.detach(); // TODO: but actually we should wait for
the thread in the dtr. | 301 startInitObjectThread.detach(); // TODO: but actually we should wait for
the thread in the dtr. |
234 } | 302 } |
235 catch (const std::system_error& ex) | 303 catch (const std::system_error& ex) |
236 { | 304 { |
237 detachedInitializationFailed = true; | 305 detachedInitializationFailed = true; |
238 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD
_CREATE_PROCESS, | 306 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_THREAD
_CREATE_PROCESS, |
239 "Class::Thread - Failed to create StartInitObject thread"); | 307 "Class::Thread - Failed to create StartInitObject thread"); |
240 } | 308 } |
241 | 309 |
242 // Start event last, after everything is ready to go | 310 // Start events last to alleviate issues with deferred evaluation |
243 browserEvents.Start(this, m_webBrowser2); | 311 browserEvents.Start(this, m_webBrowser2); |
244 } | 312 } |
245 else | 313 else |
246 { | 314 { |
247 browserEvents.Stop(); | 315 browserEvents.Stop(); |
| 316 DEBUG_GENERAL([this]() -> std::wstring |
| 317 { |
| 318 std::wstringstream ss; |
| 319 ss << L"CPluginClass::SetSite, this = " << ToHexLiteral(this); |
| 320 ss << L", browser = nullptr"; |
| 321 return ss.str(); |
| 322 }()); |
| 323 |
248 | 324 |
249 // Destroy window | 325 // Destroy window |
250 if (m_pWndProcStatus) | 326 if (m_pWndProcStatus) |
251 { | 327 { |
252 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWn
dProcStatus); | 328 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWn
dProcStatus); |
253 | 329 |
254 m_pWndProcStatus = NULL; | 330 m_pWndProcStatus = NULL; |
255 } | 331 } |
256 | 332 |
257 if (m_hPaneWnd) | 333 if (m_hPaneWnd) |
258 { | 334 { |
259 DestroyWindow(m_hPaneWnd); | 335 DestroyWindow(m_hPaneWnd); |
260 m_hPaneWnd = NULL; | 336 m_hPaneWnd = NULL; |
261 } | 337 } |
262 | 338 |
263 m_hTabWnd = NULL; | 339 m_hTabWnd = NULL; |
264 m_hStatusBarWnd = NULL; | 340 m_hStatusBarWnd = NULL; |
265 | 341 |
266 // Remove instance from the list, shutdown threads | 342 // Remove instance from the list, shutdown threads |
267 HANDLE hMainThread = NULL; | 343 HANDLE hMainThread = NULL; |
268 HANDLE hTabThread = NULL; | 344 HANDLE hTabThread = NULL; |
269 | 345 |
| 346 if (!threadMap.RemoveAndCheck()) |
| 347 { |
| 348 throw std::logic_error("CPluginClass::SetSite - Missing entry in thread
map"); |
| 349 } |
| 350 |
270 s_criticalSectionLocal.Lock(); | 351 s_criticalSectionLocal.Lock(); |
271 { | 352 { |
272 s_instances.erase(this); | 353 s_instances.erase(this); |
273 | |
274 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::Ge
tCurrentThreadId()); | |
275 if (it != s_threadInstances.end()) | |
276 { | |
277 s_threadInstances.erase(it); | |
278 } | |
279 if (s_instances.empty()) | 354 if (s_instances.empty()) |
280 { | 355 { |
281 // TODO: Explicitly releasing a resource when a container becomes empt
y looks like a job better suited for shared_ptr | 356 // TODO: Explicitly releasing a resource when a container becomes empt
y looks like a job better suited for shared_ptr |
282 CPluginClientFactory::ReleaseMimeFilterClientInstance(); | 357 CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
283 } | 358 } |
284 } | 359 } |
285 s_criticalSectionLocal.Unlock(); | 360 s_criticalSectionLocal.Unlock(); |
286 | 361 |
287 m_webBrowser2 = nullptr; | 362 m_webBrowser2 = nullptr; |
288 | 363 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 | 503 |
429 ATL::CComQIPtr<IWebBrowser2> webBrowser = frameBrowserDisp; | 504 ATL::CComQIPtr<IWebBrowser2> webBrowser = frameBrowserDisp; |
430 if (!webBrowser) | 505 if (!webBrowser) |
431 { | 506 { |
432 return; | 507 return; |
433 } | 508 } |
434 if (!urlVariant || urlVariant->vt != VT_BSTR) | 509 if (!urlVariant || urlVariant->vt != VT_BSTR) |
435 { | 510 { |
436 return; | 511 return; |
437 } | 512 } |
438 std::wstring url(urlVariant->bstrVal, SysStringLen(urlVariant->bstrVal)); | 513 std::wstring url = ToWstring(urlVariant->bstrVal); |
439 | 514 |
440 // If webbrowser2 is equal to top level browser (as set in SetSite), we are | 515 // If webbrowser2 is equal to top level browser (as set in SetSite), we are |
441 // navigating new page | 516 // navigating new page |
442 CPluginClient* client = CPluginClient::GetInstance(); | 517 CPluginClient* client = CPluginClient::GetInstance(); |
443 if (url.find(L"javascript") == 0) | 518 if (url.find(L"javascript") == 0) |
444 { | 519 { |
445 } | 520 } |
446 else if (IsRootBrowser(webBrowser)) | 521 else if (IsRootBrowser(webBrowser)) |
447 { | 522 { |
448 m_tab->OnNavigate(url); | 523 m_tab->OnNavigate(url); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u
nsigned long validFlagsMask) | 585 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u
nsigned long validFlagsMask) |
511 { | 586 { |
512 if (detachedInitializationFailed) return; | 587 if (detachedInitializationFailed) return; |
513 try | 588 try |
514 { | 589 { |
515 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); | 590 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); |
516 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL
ECMDIDF_WINDOWSTATE_ENABLED) | 591 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL
ECMDIDF_WINDOWSTATE_ENABLED) |
517 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA
BLED); | 592 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA
BLED); |
518 if (newtabshown) | 593 if (newtabshown) |
519 { | 594 { |
520 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(
GetCurrentThreadId()); | 595 if (!m_isInitializedOk) |
521 if (it == s_threadInstances.end()) | 596 { |
522 { | 597 m_isInitializedOk = true; |
523 s_threadInstances[::GetCurrentThreadId()] = this; | 598 InitObject(); |
524 if (!m_isInitializedOk) | 599 UpdateStatusBar(); |
525 { | |
526 m_isInitializedOk = true; | |
527 InitObject(); | |
528 UpdateStatusBar(); | |
529 } | |
530 } | 600 } |
531 } | 601 } |
532 notificationMessage.Hide(); | 602 notificationMessage.Hide(); |
533 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end"); | 603 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end"); |
534 } | 604 } |
535 catch (...) | 605 catch (...) |
536 { | 606 { |
537 } | 607 } |
538 } | 608 } |
539 | 609 |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 s_criticalSectionLocal.Unlock(); | 997 s_criticalSectionLocal.Unlock(); |
928 | 998 |
929 return result; | 999 return result; |
930 } | 1000 } |
931 | 1001 |
932 CPluginTab* CPluginClass::GetTab() | 1002 CPluginTab* CPluginClass::GetTab() |
933 { | 1003 { |
934 return m_tab; | 1004 return m_tab; |
935 } | 1005 } |
936 | 1006 |
937 CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) | 1007 CPluginTab* CPluginClass::GetTabForCurrentThread() |
938 { | 1008 { |
939 CPluginTab* tab = NULL; | 1009 auto p = threadMap.Locate(); |
940 | 1010 return p ? p->m_tab : nullptr; |
941 s_criticalSectionLocal.Lock(); | 1011 } |
942 { | 1012 |
943 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(dw
ThreadId); | 1013 // Entry point |
944 if (it != s_threadInstances.end()) | |
945 { | |
946 tab = it->second->m_tab; | |
947 } | |
948 } | |
949 s_criticalSectionLocal.Unlock(); | |
950 | |
951 return tab; | |
952 } | |
953 | |
954 | |
955 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O
LECMD prgCmds[], OLECMDTEXT* pCmdText) | 1014 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O
LECMD prgCmds[], OLECMDTEXT* pCmdText) |
956 { | 1015 { |
957 if (detachedInitializationFailed) return; | 1016 if (detachedInitializationFailed) return S_OK; |
958 if (cCmds == 0) return E_INVALIDARG; | 1017 try |
959 if (prgCmds == 0) return E_POINTER; | 1018 { |
960 | 1019 if (cCmds == 0) return E_INVALIDARG; |
961 prgCmds[0].cmdf = OLECMDF_ENABLED; | 1020 if (prgCmds == 0) return E_POINTER; |
962 | 1021 |
| 1022 prgCmds[0].cmdf = OLECMDF_ENABLED; |
| 1023 } |
| 1024 catch (...) |
| 1025 { |
| 1026 DEBUG_GENERAL(L"CPluginClass::QueryStatus - exception"); |
| 1027 return E_FAIL; |
| 1028 } |
963 return S_OK; | 1029 return S_OK; |
964 } | 1030 } |
965 | 1031 |
966 HMENU CPluginClass::CreatePluginMenu(const std::wstring& url) | 1032 HMENU CPluginClass::CreatePluginMenu(const std::wstring& url) |
967 { | 1033 { |
968 DEBUG_GENERAL("CreatePluginMenu"); | 1034 DEBUG_GENERAL("CreatePluginMenu"); |
969 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance(); | 1035 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance(); |
970 | 1036 |
971 HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); | 1037 HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); |
972 | 1038 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 | 1168 |
1103 MENUITEMINFOW miiSep = {}; | 1169 MENUITEMINFOW miiSep = {}; |
1104 miiSep.cbSize = sizeof(miiSep); | 1170 miiSep.cbSize = sizeof(miiSep); |
1105 miiSep.fMask = MIIM_TYPE | MIIM_FTYPE; | 1171 miiSep.fMask = MIIM_TYPE | MIIM_FTYPE; |
1106 miiSep.fType = MFT_SEPARATOR; | 1172 miiSep.fType = MFT_SEPARATOR; |
1107 | 1173 |
1108 CPluginClient* client = CPluginClient::GetInstance(); | 1174 CPluginClient* client = CPluginClient::GetInstance(); |
1109 CPluginSettings* settings = CPluginSettings::GetInstance(); | 1175 CPluginSettings* settings = CPluginSettings::GetInstance(); |
1110 { | 1176 { |
1111 ctext = dictionary->Lookup("menu", "menu-disable-on-site"); | 1177 ctext = dictionary->Lookup("menu", "menu-disable-on-site"); |
1112 // Is domain in white list? | |
1113 ReplaceString(ctext, L"?1?", client->GetHostFromUrl(url)); | 1178 ReplaceString(ctext, L"?1?", client->GetHostFromUrl(url)); |
1114 if (client->IsWhitelistedUrl(GetTab()->GetDocumentUrl())) | 1179 /* |
1115 { | 1180 * The display state of the "disable on this site" menu item depends upon ta
b content |
| 1181 */ |
| 1182 if (!GetTab()->IsPossibleToDisableOnSite()) |
| 1183 { |
| 1184 // Since we can't disable the present content, |
| 1185 // it makes no sense to offer the user an option to block it. |
| 1186 fmii.fState = MFS_UNCHECKED | MFS_DISABLED; |
| 1187 } |
| 1188 else if (client->IsWhitelistedUrl(GetTab()->GetDocumentUrl())) |
| 1189 { |
| 1190 // Domain is in white list, indicated by a check mark |
1116 fmii.fState = MFS_CHECKED | MFS_ENABLED; | 1191 fmii.fState = MFS_CHECKED | MFS_ENABLED; |
1117 } | 1192 } |
1118 else | 1193 else |
1119 { | 1194 { |
1120 fmii.fState = MFS_UNCHECKED | MFS_ENABLED; | 1195 fmii.fState = MFS_UNCHECKED | MFS_ENABLED; |
1121 } | 1196 } |
1122 fmii.fMask = MIIM_STRING | MIIM_STATE; | 1197 fmii.fMask = MIIM_STRING | MIIM_STATE; |
1123 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); | 1198 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); |
1124 fmii.cch = static_cast<UINT>(ctext.size()); | 1199 fmii.cch = static_cast<UINT>(ctext.size()); |
1125 | 1200 |
(...skipping 28 matching lines...) Expand all Loading... |
1154 ctext = dictionary->Lookup("menu", "menu-settings"); | 1229 ctext = dictionary->Lookup("menu", "menu-settings"); |
1155 fmii.fMask = MIIM_STATE | MIIM_STRING; | 1230 fmii.fMask = MIIM_STATE | MIIM_STRING; |
1156 fmii.fState = MFS_ENABLED; | 1231 fmii.fState = MFS_ENABLED; |
1157 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); | 1232 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); |
1158 fmii.cch = static_cast<UINT>(ctext.size()); | 1233 fmii.cch = static_cast<UINT>(ctext.size()); |
1159 ::SetMenuItemInfoW(hMenu, ID_MENU_SETTINGS, FALSE, &fmii); | 1234 ::SetMenuItemInfoW(hMenu, ID_MENU_SETTINGS, FALSE, &fmii); |
1160 | 1235 |
1161 return true; | 1236 return true; |
1162 } | 1237 } |
1163 | 1238 |
1164 | 1239 // Entry point |
1165 STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V
ARIANTARG*) | 1240 STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V
ARIANTARG*) |
1166 { | 1241 { |
1167 if (detachedInitializationFailed) return; | 1242 if (detachedInitializationFailed) return S_OK; |
1168 HWND hBrowserWnd = GetBrowserHWND(); | 1243 try |
1169 if (!hBrowserWnd) | 1244 { |
1170 { | 1245 HWND hBrowserWnd = GetBrowserHWND(); |
1171 return E_FAIL; | 1246 if (!hBrowserWnd) |
1172 } | 1247 { |
1173 | 1248 return E_FAIL; |
1174 // Create menu | 1249 } |
1175 HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl()); | 1250 |
1176 if (!hMenu) | 1251 // Create menu |
1177 { | 1252 HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl()); |
1178 return E_FAIL; | 1253 if (!hMenu) |
1179 } | 1254 { |
1180 | 1255 return E_FAIL; |
1181 // Check if button in toolbar was pressed | 1256 } |
1182 int nIDCommand = -1; | 1257 |
1183 BOOL bRightAlign = FALSE; | 1258 // Check if button in toolbar was pressed |
1184 | 1259 int nIDCommand = -1; |
1185 POINT pt; | 1260 BOOL bRightAlign = FALSE; |
1186 GetCursorPos(&pt); | 1261 |
1187 | 1262 POINT pt; |
1188 HWND hWndToolBar = ::WindowFromPoint(pt); | 1263 GetCursorPos(&pt); |
1189 | 1264 |
1190 DWORD nProcessId; | 1265 HWND hWndToolBar = ::WindowFromPoint(pt); |
1191 ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); | 1266 |
1192 | 1267 DWORD nProcessId; |
1193 if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) | 1268 ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); |
1194 { | 1269 |
1195 ::ScreenToClient(hWndToolBar, &pt); | 1270 if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) |
1196 int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); | 1271 { |
1197 | 1272 ::ScreenToClient(hWndToolBar, &pt); |
1198 if (nButton > 0) | 1273 int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); |
1199 { | 1274 |
1200 TBBUTTON pTBBtn = {}; | 1275 if (nButton > 0) |
1201 | 1276 { |
1202 if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) | 1277 TBBUTTON pTBBtn = {}; |
1203 { | 1278 |
1204 RECT rcButton; | 1279 if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) |
1205 nIDCommand = pTBBtn.idCommand; | 1280 { |
1206 | 1281 RECT rcButton; |
1207 if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton)) | 1282 nIDCommand = pTBBtn.idCommand; |
1208 { | 1283 |
1209 pt.x = rcButton.left; | 1284 if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton
)) |
1210 pt.y = rcButton.bottom; | |
1211 ClientToScreen(hWndToolBar, &pt); | |
1212 | |
1213 RECT rcWorkArea; | |
1214 SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0); | |
1215 if (rcWorkArea.right - pt.x < 150) | |
1216 { | 1285 { |
1217 bRightAlign = TRUE; | 1286 pt.x = rcButton.left; |
1218 pt.x = rcButton.right; | |
1219 pt.y = rcButton.bottom; | 1287 pt.y = rcButton.bottom; |
1220 ClientToScreen(hWndToolBar, &pt); | 1288 ClientToScreen(hWndToolBar, &pt); |
| 1289 |
| 1290 RECT rcWorkArea; |
| 1291 SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0); |
| 1292 if (rcWorkArea.right - pt.x < 150) |
| 1293 { |
| 1294 bRightAlign = TRUE; |
| 1295 pt.x = rcButton.right; |
| 1296 pt.y = rcButton.bottom; |
| 1297 ClientToScreen(hWndToolBar, &pt); |
| 1298 } |
1221 } | 1299 } |
1222 } | 1300 } |
1223 } | 1301 } |
| 1302 else |
| 1303 { |
| 1304 GetCursorPos(&pt); |
| 1305 } |
| 1306 } |
| 1307 |
| 1308 // Display menu |
| 1309 UINT nFlags = 0; |
| 1310 if (bRightAlign) |
| 1311 { |
| 1312 nFlags |= TPM_RIGHTALIGN; |
1224 } | 1313 } |
1225 else | 1314 else |
1226 { | 1315 { |
1227 GetCursorPos(&pt); | 1316 nFlags |= TPM_LEFTALIGN; |
1228 } | 1317 } |
1229 } | 1318 |
1230 | 1319 DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags); |
1231 // Display menu | 1320 } |
1232 UINT nFlags = 0; | 1321 catch (...) |
1233 if (bRightAlign) | 1322 { |
1234 { | 1323 // Suppress exception, log only |
1235 nFlags |= TPM_RIGHTALIGN; | 1324 DEBUG_GENERAL(L"CPluginClass::Exec - exception"); |
1236 } | 1325 return E_FAIL; |
1237 else | 1326 } |
1238 { | |
1239 nFlags |= TPM_LEFTALIGN; | |
1240 } | |
1241 | |
1242 DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags); | |
1243 | 1327 |
1244 return S_OK; | 1328 return S_OK; |
1245 } | 1329 } |
1246 | 1330 |
1247 ///////////////////////////////////////////////////////////////////////////// | 1331 // Entry point |
1248 // Window procedures | |
1249 | |
1250 LRESULT CALLBACK CPluginClass::NewStatusProc(HWND hWnd, UINT message, WPARAM wPa
ram, LPARAM lParam) | 1332 LRESULT CALLBACK CPluginClass::NewStatusProc(HWND hWnd, UINT message, WPARAM wPa
ram, LPARAM lParam) |
1251 { | 1333 { |
1252 // Find tab | 1334 CPluginClass *pClass; |
1253 CPluginClass *pClass = FindInstance(hWnd); | 1335 try |
1254 if (!pClass) | 1336 { |
1255 { | 1337 // Find tab |
1256 return DefWindowProc(hWnd, message, wParam, lParam); | 1338 pClass = FindInstance(hWnd); |
1257 } | 1339 if (!pClass) |
1258 | 1340 { |
1259 // Process message | 1341 /* |
1260 switch (message) | 1342 * Race condition if reached. |
1261 { | 1343 * We did not unhook the window procedure for the status bar when the last
BHO instance using it terminated. |
1262 case SB_SIMPLE: | 1344 * The next best thing is to call the system default window function. |
1263 { | 1345 */ |
1264 ShowWindow(pClass->m_hPaneWnd, !wParam); | 1346 return DefWindowProc(hWnd, message, wParam, lParam); |
| 1347 } |
| 1348 |
| 1349 // Process message |
| 1350 switch (message) |
| 1351 { |
| 1352 case SB_SIMPLE: |
| 1353 { |
| 1354 ShowWindow(pClass->m_hPaneWnd, !wParam); |
| 1355 break; |
| 1356 } |
| 1357 |
| 1358 case WM_SYSCOLORCHANGE: |
| 1359 { |
| 1360 pClass->UpdateTheme(); |
| 1361 break; |
| 1362 } |
| 1363 |
| 1364 case SB_SETPARTS: |
| 1365 { |
| 1366 if (!lParam || !wParam || wParam > 30 || !IsWindow(pClass->m_hPaneWnd)) |
| 1367 { |
| 1368 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam,
lParam); |
| 1369 } |
| 1370 |
| 1371 WPARAM nParts = wParam; |
| 1372 if (STATUSBAR_PANE_NUMBER >= nParts) |
| 1373 { |
| 1374 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam,
lParam); |
| 1375 } |
| 1376 |
| 1377 HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts + 1)); |
| 1378 LPINT lpParts = (LPINT)LocalLock(hLocal); |
| 1379 memcpy(lpParts, (void*)lParam, wParam*sizeof(int)); |
| 1380 |
| 1381 for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++) |
| 1382 { |
| 1383 lpParts[i] -= pClass->m_nPaneWidth; |
| 1384 } |
| 1385 LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, w
Param, (LPARAM)lpParts); |
| 1386 |
| 1387 AdblockPlus::Rectangle rcPane; |
| 1388 ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane); |
| 1389 |
| 1390 AdblockPlus::Rectangle rcClient; |
| 1391 ::GetClientRect(hWnd, &rcClient); |
| 1392 |
| 1393 ::MoveWindow( |
| 1394 pClass->m_hPaneWnd, |
| 1395 lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth, |
| 1396 0, |
| 1397 pClass->m_nPaneWidth, |
| 1398 rcClient.Height(), |
| 1399 TRUE); |
| 1400 |
| 1401 ::LocalFree(hLocal); |
| 1402 return hRet; |
| 1403 } |
| 1404 |
| 1405 default: |
1265 break; | 1406 break; |
1266 } | 1407 } |
1267 | 1408 } |
1268 case WM_SYSCOLORCHANGE: | 1409 catch (...) |
1269 { | 1410 { |
1270 pClass->UpdateTheme(); | 1411 // Suppress exception. Fall through to default handler. |
1271 break; | 1412 DEBUG_GENERAL(L"CPluginClass::NewStatusProc - exception"); |
1272 } | 1413 } |
1273 | 1414 return ::CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lPara
m); |
1274 case SB_SETPARTS: | |
1275 { | |
1276 if (!lParam || !wParam || wParam > 30 || !IsWindow(pClass->m_hPaneWnd)) | |
1277 { | |
1278 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, l
Param); | |
1279 } | |
1280 | |
1281 WPARAM nParts = wParam; | |
1282 if (STATUSBAR_PANE_NUMBER >= nParts) | |
1283 { | |
1284 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, l
Param); | |
1285 } | |
1286 | |
1287 HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts+1)); | |
1288 LPINT lpParts = (LPINT)LocalLock(hLocal); | |
1289 memcpy(lpParts, (void*)lParam, wParam*sizeof(int)); | |
1290 | |
1291 for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++) | |
1292 { | |
1293 lpParts[i] -= pClass->m_nPaneWidth; | |
1294 } | |
1295 LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wPa
ram, (LPARAM)lpParts); | |
1296 | |
1297 AdblockPlus::Rectangle rcPane; | |
1298 ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane); | |
1299 | |
1300 AdblockPlus::Rectangle rcClient; | |
1301 ::GetClientRect(hWnd, &rcClient); | |
1302 | |
1303 ::MoveWindow( | |
1304 pClass->m_hPaneWnd, | |
1305 lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth, | |
1306 0, | |
1307 pClass->m_nPaneWidth, | |
1308 rcClient.Height(), | |
1309 TRUE); | |
1310 | |
1311 ::LocalFree(hLocal); | |
1312 | |
1313 | |
1314 return hRet; | |
1315 } | |
1316 | |
1317 default: | |
1318 break; | |
1319 } | |
1320 | |
1321 LRESULT result = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wPara
m, lParam); | |
1322 | |
1323 | |
1324 return result; | |
1325 | |
1326 } | 1415 } |
1327 | 1416 |
1328 | 1417 |
1329 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url) | 1418 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url) |
1330 { | 1419 { |
1331 // use the disable icon as defualt, if the client doesn't exists | 1420 // use the disable icon as defualt, if the client doesn't exists |
1332 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); | 1421 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); |
1333 | 1422 |
1334 CPluginTab* tab = GetTab(::GetCurrentThreadId()); | 1423 CPluginTab* tab = GetTabForCurrentThread(); |
1335 if (tab) | 1424 if (tab) |
1336 { | 1425 { |
1337 CPluginClient* client = CPluginClient::GetInstance(); | 1426 CPluginClient* client = CPluginClient::GetInstance(); |
1338 if (CPluginSettings::GetInstance()->IsPluginEnabled()) | 1427 if (CPluginSettings::GetInstance()->IsPluginEnabled()) |
1339 { | 1428 { |
1340 if (client->IsWhitelistedUrl(url)) | 1429 if (client->IsWhitelistedUrl(url)) |
1341 { | 1430 { |
1342 hIcon = GetIcon(ICON_PLUGIN_DISABLED); | 1431 hIcon = GetIcon(ICON_PLUGIN_DISABLED); |
1343 } | 1432 } |
1344 else | 1433 else |
1345 { | 1434 { |
1346 CPluginSettings* settings = CPluginSettings::GetInstance(); | 1435 CPluginSettings* settings = CPluginSettings::GetInstance(); |
1347 hIcon = GetIcon(ICON_PLUGIN_ENABLED); | 1436 hIcon = GetIcon(ICON_PLUGIN_ENABLED); |
1348 } | 1437 } |
1349 } | 1438 } |
1350 } | 1439 } |
1351 return hIcon; | 1440 return hIcon; |
1352 } | 1441 } |
1353 | 1442 |
1354 | 1443 // Entry point |
1355 LRESULT CALLBACK CPluginClass::PaneWindowProc(HWND hWnd, UINT message, WPARAM wP
aram, LPARAM lParam) | 1444 LRESULT CALLBACK CPluginClass::PaneWindowProc(HWND hWnd, UINT message, WPARAM wP
aram, LPARAM lParam) |
1356 { | 1445 { |
1357 // Find tab | 1446 try |
1358 CPluginClass *pClass = FindInstance(GetParent(hWnd)); | 1447 { |
1359 if (!pClass) | 1448 // Find tab |
1360 { | 1449 CPluginClass *pClass = FindInstance(GetParent(hWnd)); |
1361 return ::DefWindowProc(hWnd, message, wParam, lParam); | 1450 if (!pClass) |
1362 } | 1451 { |
1363 | 1452 return ::DefWindowProc(hWnd, message, wParam, lParam); |
1364 // Process message | 1453 } |
1365 switch (message) | 1454 |
1366 { | 1455 // Process message |
1367 | 1456 switch (message) |
1368 case WM_SETCURSOR: | 1457 { |
1369 { | 1458 case WM_SETCURSOR: |
1370 ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); | 1459 { |
1371 return TRUE; | 1460 ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); |
1372 } | 1461 return TRUE; |
1373 case WM_PAINT: | 1462 } |
1374 { | 1463 case WM_PAINT: |
1375 PAINTSTRUCT ps; | 1464 { |
1376 HDC hDC = ::BeginPaint(hWnd, &ps); | 1465 PAINTSTRUCT ps; |
1377 | 1466 HDC hDC = ::BeginPaint(hWnd, &ps); |
1378 AdblockPlus::Rectangle rcClient; | 1467 |
1379 ::GetClientRect(hWnd, &rcClient); | 1468 AdblockPlus::Rectangle rcClient; |
1380 | 1469 ::GetClientRect(hWnd, &rcClient); |
1381 int nDrawEdge = 0; | 1470 |
1382 | 1471 int nDrawEdge = 0; |
1383 // Old Windows background drawing | 1472 |
1384 if (pClass->m_hTheme == NULL) | 1473 // Old Windows background drawing |
1385 { | 1474 if (pClass->m_hTheme == NULL) |
1386 ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); | 1475 { |
1387 ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT); | 1476 ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); |
1388 | 1477 ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT); |
1389 nDrawEdge = 3; | 1478 |
1390 rcClient.left += 3; | 1479 nDrawEdge = 3; |
1391 | 1480 rcClient.left += 3; |
1392 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); | 1481 |
1393 } | 1482 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); |
1394 // Themed background drawing | 1483 } |
1395 else | 1484 // Themed background drawing |
1396 { | 1485 else |
1397 // Draw background | 1486 { |
1398 if (pfnDrawThemeBackground) | 1487 // Draw background |
1399 { | 1488 if (pfnDrawThemeBackground) |
1400 AdblockPlus::Rectangle rc = rcClient; | |
1401 rc.right -= 2; | |
1402 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL); | |
1403 } | |
1404 | |
1405 // Copy separator picture to left side | |
1406 int nHeight = rcClient.Height(); | |
1407 int nWidth = rcClient.Width() - 2; | |
1408 | |
1409 for (int i = 0; i < 2; i++) | |
1410 { | |
1411 for (int j = 0; j < nHeight; j++) | |
1412 { | 1489 { |
1413 COLORREF clr = ::GetPixel(hDC, i + nWidth, j); | 1490 AdblockPlus::Rectangle rc = rcClient; |
1414 | 1491 rc.right -= 2; |
1415 // Ignore black boxes (if source is obscured by other windows) | 1492 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL); |
1416 if (clr != -1 && (GetRValue(clr) > 8 || GetGValue(clr) > 8 || GetBVa
lue(clr) > 8)) | 1493 } |
| 1494 |
| 1495 // Copy separator picture to left side |
| 1496 int nHeight = rcClient.Height(); |
| 1497 int nWidth = rcClient.Width() - 2; |
| 1498 |
| 1499 for (int i = 0; i < 2; i++) |
| 1500 { |
| 1501 for (int j = 0; j < nHeight; j++) |
1417 { | 1502 { |
1418 ::SetPixel(hDC, i, j, clr); | 1503 COLORREF clr = ::GetPixel(hDC, i + nWidth, j); |
| 1504 |
| 1505 // Ignore black boxes (if source is obscured by other windows) |
| 1506 if (clr != -1 && (GetRValue(clr) > 8 || GetGValue(clr) > 8 || GetB
Value(clr) > 8)) |
| 1507 { |
| 1508 ::SetPixel(hDC, i, j, clr); |
| 1509 } |
1419 } | 1510 } |
1420 } | 1511 } |
1421 } | 1512 } |
1422 } | 1513 |
1423 | 1514 // Draw icon |
1424 // Draw icon | 1515 if (CPluginClient::GetInstance()) |
1425 if (CPluginClient::GetInstance()) | 1516 { |
1426 { | 1517 HICON hIcon = GetStatusBarIcon(pClass->GetTab()->GetDocumentUrl()); |
1427 HICON hIcon = GetStatusBarIcon(pClass->GetTab()->GetDocumentUrl()); | 1518 |
1428 | 1519 int offx = nDrawEdge; |
1429 int offx = nDrawEdge; | 1520 if (hIcon) |
1430 if (hIcon) | 1521 { |
1431 { | 1522 //Get the RECT for the leftmost pane (the status text pane) |
1432 //Get the RECT for the leftmost pane (the status text pane) | 1523 RECT rect; |
| 1524 BOOL rectRes = ::SendMessage(pClass->m_hStatusBarWnd, SB_GETRECT, 0,
(LPARAM)&rect); |
| 1525 ::DrawIconEx(hDC, 0, rect.bottom - rect.top - iconHeight, hIcon, ico
nWidth, iconHeight, NULL, NULL, DI_NORMAL); |
| 1526 offx += iconWidth; |
| 1527 } |
| 1528 #ifdef _DEBUG |
| 1529 // Display version |
| 1530 HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT
, 0, 0); |
| 1531 HGDIOBJ hOldFont = ::SelectObject(hDC, hFont); |
| 1532 |
| 1533 AdblockPlus::Rectangle rcText = rcClient; |
| 1534 rcText.left += offx; |
| 1535 ::SetBkMode(hDC, TRANSPARENT); |
| 1536 ::DrawTextW(hDC, IEPLUGIN_VERSION, -1, &rcText, DT_WORD_ELLIPSIS | DT_
LEFT | DT_SINGLELINE | DT_VCENTER); |
| 1537 |
| 1538 ::SelectObject(hDC, hOldFont); |
| 1539 #endif // _DEBUG |
| 1540 } |
| 1541 |
| 1542 // Done! |
| 1543 EndPaint(hWnd, &ps); |
| 1544 |
| 1545 return 0; |
| 1546 } |
| 1547 |
| 1548 case WM_LBUTTONUP: |
| 1549 case WM_RBUTTONUP: |
| 1550 { |
| 1551 std::wstring url = pClass->GetBrowserUrl(); |
| 1552 if (url != pClass->GetTab()->GetDocumentUrl()) |
| 1553 { |
| 1554 pClass->GetTab()->SetDocumentUrl(url); |
| 1555 } |
| 1556 |
| 1557 // Create menu |
| 1558 HMENU hMenu = pClass->CreatePluginMenu(url); |
| 1559 if (!hMenu) |
| 1560 { |
| 1561 return 0; |
| 1562 } |
| 1563 |
| 1564 // Display menu |
| 1565 POINT pt; |
| 1566 ::GetCursorPos(&pt); |
| 1567 |
| 1568 RECT rc; |
| 1569 ::GetWindowRect(hWnd, &rc); |
| 1570 |
| 1571 if (rc.left >= 0 && rc.top >= 0) |
| 1572 { |
| 1573 pt.x = rc.left; |
| 1574 pt.y = rc.top; |
| 1575 } |
| 1576 |
| 1577 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN | TPM_BOTTOMALIGN
); |
| 1578 break; |
| 1579 } |
| 1580 case WM_DESTROY: |
| 1581 break; |
| 1582 case SC_CLOSE: |
| 1583 break; |
| 1584 |
| 1585 case WM_UPDATEUISTATE: |
| 1586 { |
| 1587 CPluginTab* tab = GetTabForCurrentThread(); |
| 1588 if (tab) |
| 1589 { |
| 1590 tab->OnActivate(); |
1433 RECT rect; | 1591 RECT rect; |
1434 BOOL rectRes = ::SendMessage(pClass->m_hStatusBarWnd, SB_GETRECT, 0, (
LPARAM)&rect); | 1592 GetWindowRect(pClass->m_hPaneWnd, &rect); |
1435 ::DrawIconEx(hDC, 0, rect.bottom - rect.top - iconHeight, hIcon, iconW
idth, iconHeight, NULL, NULL, DI_NORMAL); | 1593 pClass->notificationMessage.MoveToCenter(rect); |
1436 offx += iconWidth; | 1594 } |
1437 } | 1595 if (LOWORD(wParam) == UIS_CLEAR) |
1438 #ifdef _DEBUG | 1596 { |
1439 // Display version | 1597 pClass->notificationMessage.Hide(); |
1440 HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT,
0, 0); | 1598 } |
1441 HGDIOBJ hOldFont = ::SelectObject(hDC,hFont); | 1599 break; |
1442 | 1600 } |
1443 AdblockPlus::Rectangle rcText = rcClient; | 1601 case WM_WINDOWPOSCHANGING: |
1444 rcText.left += offx; | 1602 { |
1445 ::SetBkMode(hDC, TRANSPARENT); | |
1446 ::DrawTextW(hDC, IEPLUGIN_VERSION, -1, &rcText, DT_WORD_ELLIPSIS|DT_LEFT
|DT_SINGLELINE|DT_VCENTER); | |
1447 | |
1448 ::SelectObject(hDC, hOldFont); | |
1449 #endif // _DEBUG | |
1450 } | |
1451 | |
1452 // Done! | |
1453 EndPaint(hWnd, &ps); | |
1454 | |
1455 return 0; | |
1456 } | |
1457 | |
1458 case WM_LBUTTONUP: | |
1459 case WM_RBUTTONUP: | |
1460 { | |
1461 std::wstring url = pClass->GetBrowserUrl(); | |
1462 if (url != pClass->GetTab()->GetDocumentUrl()) | |
1463 { | |
1464 pClass->GetTab()->SetDocumentUrl(url); | |
1465 } | |
1466 | |
1467 // Create menu | |
1468 HMENU hMenu = pClass->CreatePluginMenu(url); | |
1469 if (!hMenu) | |
1470 { | |
1471 return 0; | |
1472 } | |
1473 | |
1474 // Display menu | |
1475 POINT pt; | |
1476 ::GetCursorPos(&pt); | |
1477 | |
1478 RECT rc; | |
1479 ::GetWindowRect(hWnd, &rc); | |
1480 | |
1481 if (rc.left >= 0 && rc.top >= 0) | |
1482 { | |
1483 pt.x = rc.left; | |
1484 pt.y = rc.top; | |
1485 } | |
1486 | |
1487 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN|TPM_BOTTOMALIGN); | |
1488 } | |
1489 break; | |
1490 case WM_DESTROY: | |
1491 break; | |
1492 case SC_CLOSE: | |
1493 break; | |
1494 | |
1495 case WM_UPDATEUISTATE: | |
1496 { | |
1497 CPluginTab* tab = GetTab(::GetCurrentThreadId()); | |
1498 if (tab) | |
1499 { | |
1500 tab->OnActivate(); | |
1501 RECT rect; | 1603 RECT rect; |
1502 GetWindowRect(pClass->m_hPaneWnd, &rect); | 1604 GetWindowRect(pClass->m_hPaneWnd, &rect); |
1503 pClass->notificationMessage.Move(rect.left + (rect.right - rect.left) /
2, rect.top + (rect.bottom - rect.top) / 2); | 1605 if (pClass->notificationMessage.IsVisible()) |
1504 } | 1606 { |
1505 if (LOWORD(wParam) == UIS_CLEAR) | 1607 pClass->notificationMessage.MoveToCenter(rect); |
1506 { | 1608 } |
1507 pClass->notificationMessage.Hide(); | 1609 break; |
1508 } | 1610 } |
1509 } | 1611 case WM_WINDOWPOSCHANGED: |
1510 break; | 1612 { |
1511 case WM_WINDOWPOSCHANGING: | 1613 WINDOWPOS* wndPos = reinterpret_cast<WINDOWPOS*>(lParam); |
1512 { | 1614 if (wndPos->flags & SWP_HIDEWINDOW) |
1513 RECT rect; | 1615 { |
1514 GetWindowRect(pClass->m_hPaneWnd, &rect); | 1616 pClass->notificationMessage.Hide(); |
1515 if (pClass->notificationMessage.IsVisible()) | 1617 } |
1516 { | 1618 break; |
1517 pClass->notificationMessage.Move(rect.left + (rect.right - rect.left) /
2, rect.top + (rect.bottom - rect.top) / 2); | 1619 } |
1518 } | 1620 case WM_ALREADY_UP_TO_DATE: |
1519 } | 1621 { |
1520 break; | 1622 Dictionary* dictionary = Dictionary::GetInstance(); |
1521 case WM_WINDOWPOSCHANGED: | 1623 std::wstring upToDateText = dictionary->Lookup("updater", "update-alread
y-up-to-date-text"); |
1522 { | 1624 std::wstring upToDateTitle = dictionary->Lookup("updater", "update-alrea
dy-up-to-date-title"); |
1523 WINDOWPOS* wndPos = reinterpret_cast<WINDOWPOS*>(lParam); | 1625 pClass->notificationMessage.SetTextAndIcon(upToDateText, upToDateTitle,
TTI_INFO); |
1524 if (wndPos->flags & SWP_HIDEWINDOW) | 1626 break; |
1525 { | 1627 } |
1526 pClass->notificationMessage.Hide(); | 1628 case WM_UPDATE_CHECK_ERROR: |
1527 } | 1629 { |
1528 } | 1630 Dictionary* dictionary = Dictionary::GetInstance(); |
1529 break; | 1631 std::wstring errorText = dictionary->Lookup("updater", "update-error-tex
t"); |
1530 case WM_ALREADY_UP_TO_DATE: | 1632 std::wstring errorTitle = dictionary->Lookup("updater", "update-error-ti
tle"); |
1531 { | 1633 pClass->notificationMessage.SetTextAndIcon(errorText, errorTitle, TTI_ER
ROR); |
1532 Dictionary* dictionary = Dictionary::GetInstance(); | 1634 break; |
1533 std::wstring upToDateText = dictionary->Lookup("updater", "update-already-
up-to-date-text"); | 1635 } |
1534 std::wstring upToDateTitle = dictionary->Lookup("updater", "update-already
-up-to-date-title"); | 1636 case WM_DOWNLOADING_UPDATE: |
1535 pClass->notificationMessage.SetTextAndIcon(upToDateText, upToDateTitle, TT
I_INFO); | 1637 { |
1536 } | 1638 Dictionary* dictionary = Dictionary::GetInstance(); |
1537 break; | 1639 std::wstring downloadingText = dictionary->Lookup("updater", "downloadin
g-update-text"); |
1538 case WM_UPDATE_CHECK_ERROR: | 1640 std::wstring downloadingTitle = dictionary->Lookup("updater", "downloadi
ng-update-title"); |
1539 { | 1641 pClass->notificationMessage.SetTextAndIcon(downloadingText, downloadingT
itle, TTI_INFO); |
1540 Dictionary* dictionary = Dictionary::GetInstance(); | 1642 break; |
1541 std::wstring errorText = dictionary->Lookup("updater", "update-error-text"
); | 1643 } |
1542 std::wstring errorTitle = dictionary->Lookup("updater", "update-error-titl
e"); | 1644 } |
1543 pClass->notificationMessage.SetTextAndIcon(errorText, errorText, TTI_ERROR
); | 1645 } |
1544 } | 1646 catch (...) |
1545 break; | 1647 { |
1546 case WM_DOWNLOADING_UPDATE: | 1648 // Suppress exception. Fall through to default handler. |
1547 { | 1649 DEBUG_GENERAL(L"CPluginClass::PaneWindowProc - exception"); |
1548 Dictionary* dictionary = Dictionary::GetInstance(); | 1650 } |
1549 std::wstring downloadingText = dictionary->Lookup("updater", "downloading-
update-text"); | 1651 return ::DefWindowProc(hWnd, message, wParam, lParam); |
1550 std::wstring downloadingTitle = dictionary->Lookup("updater", "downloading
-update-title"); | |
1551 pClass->notificationMessage.SetTextAndIcon(downloadingText, downloadingTit
le, TTI_INFO); | |
1552 } | |
1553 break; | |
1554 } | |
1555 | |
1556 return DefWindowProc(hWnd, message, wParam, lParam); | |
1557 } | 1652 } |
1558 | 1653 |
1559 | 1654 |
1560 void CPluginClass::UpdateStatusBar() | 1655 void CPluginClass::UpdateStatusBar() |
1561 { | 1656 { |
1562 DEBUG_GENERAL("*** Updating statusbar") | 1657 DEBUG_GENERAL("*** Updating statusbar") |
1563 if (m_hPaneWnd == NULL) | 1658 if (m_hPaneWnd == NULL) |
1564 { | 1659 { |
1565 CreateStatusBarPane(); | 1660 CreateStatusBarPane(); |
1566 } | 1661 } |
(...skipping 25 matching lines...) Expand all Loading... |
1592 s_criticalSectionLocal.Unlock(); | 1687 s_criticalSectionLocal.Unlock(); |
1593 | 1688 |
1594 return icon; | 1689 return icon; |
1595 } | 1690 } |
1596 | 1691 |
1597 ATOM CPluginClass::GetAtomPaneClass() | 1692 ATOM CPluginClass::GetAtomPaneClass() |
1598 { | 1693 { |
1599 return s_atomPaneClass; | 1694 return s_atomPaneClass; |
1600 } | 1695 } |
1601 | 1696 |
LEFT | RIGHT |