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

Delta Between Two Patch Sets: src/plugin/PluginClass.cpp

Issue 29332848: Issue #3432 - Manage COM events with a resource class
Left Patch Set: Created Dec. 17, 2015, 6:08 p.m.
Right Patch Set: rebase only Created July 27, 2016, 8:55 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/plugin/PluginClass.h ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
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
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
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
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
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
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
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
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
LEFTRIGHT

Powered by Google App Engine
This is Rietveld