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

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

Issue 29323611: Issue #1234, #2058 - Rewrite log facility, improving thread implementation
Left Patch Set: Created Aug. 19, 2015, 5:42 p.m.
Right Patch Set: rebase only Created July 27, 2016, 9:11 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') | src/plugin/PluginClientBase.h » ('j') | 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 "PluginClientFactory.h" 26 #include "PluginClientFactory.h"
27 #include "PluginUtil.h" 27 #include "PluginUtil.h"
28 #include "../shared/Utils.h" 28 #include "../shared/Utils.h"
29 #include "../shared/Dictionary.h" 29 #include "../shared/Dictionary.h"
30 #include "IeVersion.h" 30 #include "IeVersion.h"
31 #include "../shared/Version.h" 31 #include "../shared/Version.h"
32 #include "Instances.h"
32 #include <thread> 33 #include <thread>
33 #include <array> 34 #include <array>
34 35
35 #ifdef DEBUG_HIDE_EL 36 #ifdef DEBUG_HIDE_EL
36 DWORD profileTime = 0; 37 DWORD profileTime = 0;
37 #endif 38 #endif
38 39
39 extern CComModule _Module; 40 extern CComModule _Module;
40 41
41 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); 42 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR);
42 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR ECT); 43 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR ECT);
43 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); 44 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE);
44 45
45 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL }; 46 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL };
46 DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABL ED, IDI_ICON_DEACTIVATED }; 47 DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABL ED, IDI_ICON_DEACTIVATED };
47 uint32_t iconHeight = 32; 48 uint32_t iconHeight = 32;
48 uint32_t iconWidth = 32; 49 uint32_t iconWidth = 32;
49 50
50 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; 51 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL;
51 52
52 CLOSETHEMEDATA pfnClose = NULL; 53 CLOSETHEMEDATA pfnClose = NULL;
53 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; 54 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL;
54 OPENTHEMEDATA pfnOpenThemeData = NULL; 55 OPENTHEMEDATA pfnOpenThemeData = NULL;
55 56
56 ATOM CPluginClass::s_atomPaneClass = NULL; 57 ATOM CPluginClass::s_atomPaneClass = NULL;
57 HINSTANCE CPluginClass::s_hUxtheme = NULL; 58 HINSTANCE CPluginClass::s_hUxtheme = NULL;
58 std::set<CPluginClass*> CPluginClass::s_instances; 59 std::set<CPluginClass*> CPluginClass::s_instances;
59 std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances;
60 60
61 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; 61 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal;
62 CComAutoCriticalSection CPluginClass::s_criticalSectionBrowser;
63 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; 62 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow;
64 63
65 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; 64 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2;
65
66 namespace
67 {
68 /**
69 * A synchronized map whose key is always the current thread ID.
70 */
71 class CurrentThreadMap
72 : public SyncMap<DWORD, CPluginClass*, nullptr>
73 {
74 typedef SyncMap<DWORD, CPluginClass*, nullptr> Base;
75
76 public:
77 bool AddIfAbsent(CPluginClass* p)
78 {
79 return Base::AddIfAbsent(::GetCurrentThreadId(), p);
80 }
81
82 bool RemoveAndCheck()
83 {
84 return Base::RemoveIfPresent(::GetCurrentThreadId());
85 }
86
87 CPluginClass* Locate()
88 {
89 return Base::Locate(::GetCurrentThreadId());
90 }
91 };
92
93 /**
94 * Map from thread ID's to CPluginClass instances
95 */
96 CurrentThreadMap threadMap;
97 }
66 98
67 /* 99 /*
68 * Without namespace declaration, the identifier "Rectangle" is ambiguous 100 * Without namespace declaration, the identifier "Rectangle" is ambiguous
69 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx 101 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx
70 */ 102 */
71 namespace AdblockPlus 103 namespace AdblockPlus
72 { 104 {
73 /** 105 /**
74 * Replacement for ATL type CRect. 106 * Replacement for ATL type CRect.
75 */ 107 */
76 class Rectangle 108 class Rectangle
77 : public RECT 109 : public RECT
78 { 110 {
79 public: 111 public:
80 int Height() const 112 unsigned long Height() const
81 { 113 {
82 return bottom - top; 114 if (bottom < top)
83 } 115 {
84 116 throw std::runtime_error("invariant violation: rectangle bottom < top");
85 int Width() const 117 }
86 { 118 return static_cast<unsigned long>(bottom - top);
87 return right - left; 119 }
120
121 unsigned long Width() const
122 {
123 if (right < left)
124 {
125 throw std::runtime_error("invariant violation: rectangle right < left");
126 }
127 return static_cast<unsigned long>(right - left);
88 } 128 }
89 }; 129 };
90 } 130 }
91 131
92 CPluginClass::CPluginClass() 132 CPluginClass::CPluginClass()
93 { 133 : m_webBrowser2(nullptr)
134 {
135 DEBUG_GENERAL([this]() -> std::wstring
136 {
137 std::wstring s = L"CPluginClass::<constructor>, this = ";
138 s += ToHexLiteral(this);
139 return s;
140 }());
141
94 //Use this line to debug memory leaks 142 //Use this line to debug memory leaks
95 // _CrtDumpMemoryLeaks(); 143 // _CrtDumpMemoryLeaks();
96 144
97 m_isAdvised = false; 145 m_isAdvised = false;
98 m_hTabWnd = NULL; 146 m_hTabWnd = NULL;
99 m_hStatusBarWnd = NULL; 147 m_hStatusBarWnd = NULL;
100 m_hPaneWnd = NULL; 148 m_hPaneWnd = NULL;
101 m_nPaneWidth = 0; 149 m_nPaneWidth = 0;
102 m_pWndProcStatus = NULL; 150 m_pWndProcStatus = NULL;
103 m_hTheme = NULL; 151 m_hTheme = NULL;
104 m_isInitializedOk = false; 152 m_isInitializedOk = false;
105 153 m_tab = new CPluginTab();
106
107 m_tab = new CPluginTab(this);
108
109 Dictionary::Create(GetBrowserLanguage()); 154 Dictionary::Create(GetBrowserLanguage());
110 } 155 }
111 156
112 CPluginClass::~CPluginClass() 157 CPluginClass::~CPluginClass()
113 { 158 {
159 DEBUG_GENERAL([this]() -> std::wstring
160 {
161 std::wstring s = L"CPluginClass::<destructor>, this = ";
162 s += ToHexLiteral(this);
163 return s;
164 }());
165
114 delete m_tab; 166 delete m_tab;
115 } 167 }
116 168
117
118 /////////////////////////////////////////////////////////////////////////////
119 // Initialization
120
121 HRESULT CPluginClass::FinalConstruct()
122 {
123 return S_OK;
124 }
125
126 void CPluginClass::FinalRelease()
127 {
128 s_criticalSectionBrowser.Lock();
129 {
130 m_webBrowser2.Release();
131 }
132 s_criticalSectionBrowser.Unlock();
133 }
134
135 HWND CPluginClass::GetBrowserHWND() const 169 HWND CPluginClass::GetBrowserHWND() const
136 { 170 {
137 SHANDLE_PTR hBrowserWndHandle = NULL; 171 if (!m_webBrowser2)
138 172 {
139 CComQIPtr<IWebBrowser2> browser = GetBrowser(); 173 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::GetBrowserHWND - Reached with m_webB rowser2 == nullptr");
140 if (browser) 174 return nullptr;
141 { 175 }
142 HRESULT hr = browser->get_HWND(&hBrowserWndHandle); 176 SHANDLE_PTR hBrowserWndHandle = 0;
143 if (FAILED(hr)) 177 HRESULT hr = m_webBrowser2->get_HWND(&hBrowserWndHandle);
144 { 178 if (FAILED(hr))
145 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_BROWSER_WINDOW, " Class::GetBrowserHWND - failed"); 179 {
146 } 180 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_BROWSER_WINDOW, "Cl ass::GetBrowserHWND - failed");
147 } 181 return nullptr;
148 182 }
149 return (HWND)hBrowserWndHandle; 183 return (HWND)hBrowserWndHandle;
150 } 184 }
151 185
152 186 bool CPluginClass::IsRootBrowser(IWebBrowser2* otherBrowser)
153 CComQIPtr<IWebBrowser2> CPluginClass::GetBrowser() const 187 {
188 return m_webBrowser2.IsEqualObject(otherBrowser);
189 }
190
191 CComQIPtr<IWebBrowser2> CPluginClass::GetAsyncBrowser()
154 { 192 {
155 CComQIPtr<IWebBrowser2> browser; 193 CComQIPtr<IWebBrowser2> browser;
156 194
157 s_criticalSectionBrowser.Lock(); 195 s_criticalSectionLocal.Lock();
158 { 196 {
159 browser = m_webBrowser2; 197 browser = s_asyncWebBrowser2;
160 } 198 }
161 s_criticalSectionBrowser.Unlock(); 199 s_criticalSectionLocal.Unlock();
162 200
163 return browser; 201 return browser;
164 } 202 }
165 203
166
167 CComQIPtr<IWebBrowser2> CPluginClass::GetAsyncBrowser()
168 {
169 CComQIPtr<IWebBrowser2> browser;
170
171 s_criticalSectionLocal.Lock();
172 {
173 browser = s_asyncWebBrowser2;
174 }
175 s_criticalSectionLocal.Unlock();
176
177 return browser;
178 }
179
180 std::wstring CPluginClass::GetBrowserUrl() const 204 std::wstring CPluginClass::GetBrowserUrl() const
181 { 205 {
182 std::wstring url; 206 std::wstring url;
183 CComQIPtr<IWebBrowser2> browser = GetBrowser(); 207 if (m_webBrowser2)
184 if (browser)
185 { 208 {
186 CComBSTR bstrURL; 209 CComBSTR bstrURL;
187 if (SUCCEEDED(browser->get_LocationURL(&bstrURL)) && bstrURL) 210 if (SUCCEEDED(m_webBrowser2->get_LocationURL(&bstrURL)))
188 { 211 {
189 url = std::wstring(bstrURL, SysStringLen(bstrURL)); 212 url = ToWstring(bstrURL);
190 UnescapeUrl(url);
191 } 213 }
192 } 214 }
193 else 215 else
216 {
217 DEBUG_GENERAL(L"CPluginClass::GetBrowserUrl - Reached with m_webBrowser2 == nullptr (probable invariant violation)");
218 }
219 if (url.empty())
194 { 220 {
195 url = m_tab->GetDocumentUrl(); 221 url = m_tab->GetDocumentUrl();
196 } 222 }
197 return url; 223 return url;
198 } 224 }
199 225
200 DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr) 226 DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr)
201 { 227 {
202 if (thisPtr == NULL) 228 if (thisPtr == NULL)
203 return 0; 229 return 0;
(...skipping 14 matching lines...) Expand all
218 * 'unknownSite' will be null. Extraordinarily, this is sometimes _not_ called w hen IE 244 * 'unknownSite' will be null. Extraordinarily, this is sometimes _not_ called w hen IE
219 * is shutting down. Thus 'SetSite(nullptr)' has some similarities with a destru ctor, 245 * is shutting down. Thus 'SetSite(nullptr)' has some similarities with a destru ctor,
220 * but it is not a proper substitute for one. 246 * but it is not a proper substitute for one.
221 */ 247 */
222 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) 248 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite)
223 { 249 {
224 try 250 try
225 { 251 {
226 if (unknownSite) 252 if (unknownSite)
227 { 253 {
228 254 DEBUG_GENERAL(L"========================================================== ======================\nNEW TAB UI\n============================================ ====================================");
229 DEBUG_GENERAL(L"========================================================== ======================\nNEW TAB UI\n============================================ ====================================")
230 255
231 HRESULT hr = ::CoInitialize(NULL); 256 HRESULT hr = ::CoInitialize(NULL);
232 if (FAILED(hr)) 257 if (FAILED(hr))
233 { 258 {
234 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT, "Class::SetSite - CoInitialize"); 259 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT, "Class::SetSite - CoInitialize");
235 } 260 }
236 261
237 s_criticalSectionBrowser.Lock(); 262 /*
238 { 263 * We were instantiated as a BHO, so our site is always of type IWebBrowse r2.
239 m_webBrowser2 = unknownSite; 264 */
240 } 265 m_webBrowser2 = ATL::CComQIPtr<IWebBrowser2>(unknownSite);
241 s_criticalSectionBrowser.Unlock(); 266 if (!m_webBrowser2)
267 {
268 throw std::logic_error("CPluginClass::SetSite - Unable to convert site p ointer to IWebBrowser2*");
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 }
242 285
243 //register the mimefilter 286 //register the mimefilter
244 //and only mimefilter 287 //and only mimefilter
245 //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
246
247 s_criticalSectionLocal.Lock(); 289 s_criticalSectionLocal.Lock();
248 { 290 {
249 // 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
250 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); 292 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance();
251 s_asyncWebBrowser2 = unknownSite; 293 s_asyncWebBrowser2 = unknownSite;
252 s_instances.insert(this); 294 s_instances.insert(this);
253 } 295 }
254 s_criticalSectionLocal.Unlock(); 296 s_criticalSectionLocal.Unlock();
255 297
256 try 298 try
257 { 299 {
258 auto webBrowser = GetBrowser(); 300 HRESULT hr = DispEventAdvise(m_webBrowser2);
259 if (webBrowser) 301 if (SUCCEEDED(hr))
260 { 302 {
261 DEBUG_GENERAL("Loaded as BHO"); 303 m_isAdvised = true;
262 HRESULT hr = DispEventAdvise(webBrowser); 304 try
263 if (SUCCEEDED(hr))
264 { 305 {
265 m_isAdvised = true; 306 std::thread startInitObjectThread(StartInitObject, this);
266 try 307 startInitObjectThread.detach(); // TODO: but actually we should wait for the thread in the dtr.
267 {
268 std::thread startInitObjectThread(StartInitObject, this);
269 startInitObjectThread.detach(); // TODO: but actually we should wa it for the thread in the dtr.
270 }
271 catch (const std::system_error& ex)
272 {
273 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_ THREAD_CREATE_PROCESS,
274 "Class::Thread - Failed to create StartInitObject thread");
275 }
276 } 308 }
277 else 309 catch (const std::system_error& ex)
278 { 310 {
279 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADV ICE, "Class::SetSite - Advise"); 311 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_TH READ_CREATE_PROCESS,
312 "Class::Thread - Failed to create StartInitObject thread");
280 } 313 }
314 }
315 else
316 {
317 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVIC E, "Class::SetSite - Advise");
281 } 318 }
282 } 319 }
283 catch (const std::runtime_error& ex) 320 catch (const std::runtime_error& ex)
284 { 321 {
285 DEBUG_EXCEPTION(ex); 322 DEBUG_EXCEPTION(ex);
286 Unadvise(); 323 Unadvise();
287 } 324 }
288 } 325 }
289 else 326 else
290 { 327 {
328 DEBUG_GENERAL([this]() -> std::wstring
329 {
330 std::wstringstream ss;
331 ss << L"CPluginClass::SetSite, this = " << ToHexLiteral(this);
332 ss << L", browser = nullptr";
333 return ss.str();
334 }());
335
291 Unadvise(); 336 Unadvise();
292 337
293 // Destroy window 338 // Destroy window
294 if (m_pWndProcStatus) 339 if (m_pWndProcStatus)
295 { 340 {
296 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWn dProcStatus); 341 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWn dProcStatus);
297 342
298 m_pWndProcStatus = NULL; 343 m_pWndProcStatus = NULL;
299 } 344 }
300 345
301 if (m_hPaneWnd) 346 if (m_hPaneWnd)
302 { 347 {
303 DestroyWindow(m_hPaneWnd); 348 DestroyWindow(m_hPaneWnd);
304 m_hPaneWnd = NULL; 349 m_hPaneWnd = NULL;
305 } 350 }
306 351
307 m_hTabWnd = NULL; 352 m_hTabWnd = NULL;
308 m_hStatusBarWnd = NULL; 353 m_hStatusBarWnd = NULL;
309 354
310 // Remove instance from the list, shutdown threads 355 // Remove instance from the list, shutdown threads
311 HANDLE hMainThread = NULL; 356 HANDLE hMainThread = NULL;
312 HANDLE hTabThread = NULL; 357 HANDLE hTabThread = NULL;
313 358
359 if (!threadMap.RemoveAndCheck())
360 {
361 throw std::logic_error("CPluginClass::SetSite - Missing entry in thread map");
362 }
363
314 s_criticalSectionLocal.Lock(); 364 s_criticalSectionLocal.Lock();
315 { 365 {
316 s_instances.erase(this); 366 s_instances.erase(this);
317
318 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::Ge tCurrentThreadId());
319 if (it != s_threadInstances.end())
320 {
321 s_threadInstances.erase(it);
322 }
323 if (s_instances.empty()) 367 if (s_instances.empty())
324 { 368 {
325 // TODO: Explicitly releasing a resource when a container becomes empt y looks like a job better suited for shared_ptr 369 // TODO: Explicitly releasing a resource when a container becomes empt y looks like a job better suited for shared_ptr
326 CPluginClientFactory::ReleaseMimeFilterClientInstance(); 370 CPluginClientFactory::ReleaseMimeFilterClientInstance();
327 } 371 }
328 } 372 }
329 s_criticalSectionLocal.Unlock(); 373 s_criticalSectionLocal.Unlock();
330 374
331 // Release browser interface 375 m_webBrowser2 = nullptr;
332 s_criticalSectionBrowser.Lock();
333 {
334 m_webBrowser2.Release();
335 }
336 s_criticalSectionBrowser.Unlock();
337 376
338 DEBUG_GENERAL("=========================================================== =====================\nNEW TAB UI - END\n======================================= =========================================") 377 DEBUG_GENERAL("=========================================================== =====================\nNEW TAB UI - END\n======================================= =========================================")
339 378
340 ::CoUninitialize(); 379 ::CoUninitialize();
341 } 380 }
342 381
343 IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite);
344 } 382 }
345 catch (...) 383 catch (...)
346 { 384 {
347 } 385 }
386 IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite);
348 return S_OK; 387 return S_OK;
349 } 388 }
350 389
351 bool CPluginClass::IsStatusBarEnabled() 390 bool CPluginClass::IsStatusBarEnabled()
352 { 391 {
353 DEBUG_GENERAL("IsStatusBarEnabled start"); 392 DEBUG_GENERAL("IsStatusBarEnabled start");
354 HKEY pHkey; 393 HKEY pHkey;
355 HKEY pHkeySub; 394 HKEY pHkeySub;
356 RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey); 395 RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey);
357 DWORD truth = 1; 396 DWORD truth = 1;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 { 514 {
476 ATL::CComQIPtr<IWebBrowser2> webBrowser = frameBrowserDisp; 515 ATL::CComQIPtr<IWebBrowser2> webBrowser = frameBrowserDisp;
477 if (!webBrowser) 516 if (!webBrowser)
478 { 517 {
479 return; 518 return;
480 } 519 }
481 if (!urlVariant || urlVariant->vt != VT_BSTR) 520 if (!urlVariant || urlVariant->vt != VT_BSTR)
482 { 521 {
483 return; 522 return;
484 } 523 }
485 std::wstring url(urlVariant->bstrVal, SysStringLen(urlVariant->bstrVal)); 524 std::wstring url = ToWstring(urlVariant->bstrVal);
486 UnescapeUrl(url);
487 525
488 // If webbrowser2 is equal to top level browser (as set in SetSite), we are 526 // If webbrowser2 is equal to top level browser (as set in SetSite), we are
489 // navigating new page 527 // navigating new page
490 CPluginClient* client = CPluginClient::GetInstance(); 528 CPluginClient* client = CPluginClient::GetInstance();
491 if (url.find(L"javascript") == 0) 529 if (url.find(L"javascript") == 0)
492 { 530 {
493 } 531 }
494 else if (GetBrowser().IsEqualObject(webBrowser)) 532 else if (IsRootBrowser(webBrowser))
495 { 533 {
496 m_tab->OnNavigate(url); 534 m_tab->OnNavigate(url);
497 DEBUG_GENERAL( 535 DEBUG_GENERAL(
498 L"======================================================================== ========\n" 536 L"======================================================================== ========\n"
499 L"Begin main navigation url:" + url + L"\n" 537 L"Begin main navigation url:" + url + L"\n"
500 L"======================================================================== ========") 538 L"======================================================================== ========")
501 539
502 #ifdef ENABLE_DEBUG_RESULT 540 #ifdef ENABLE_DEBUG_RESULT
503 CPluginDebug::DebugResultDomain(url); 541 CPluginDebug::DebugResultDomain(url);
504 #endif 542 #endif
505 UpdateStatusBar(); 543 UpdateStatusBar();
506 } 544 }
507 else 545 else
508 { 546 {
509 DEBUG_NAVI(L"Navi::Begin navigation url:" + url) 547 DEBUG_NAVI(L"Navi::Begin navigation url:" + url)
510 m_tab->CacheFrame(url); 548 m_tab->CacheFrame(url);
511 } 549 }
512 } 550 }
513 catch (...) 551 catch (...)
514 { 552 {
515 } 553 }
516 } 554 }
517 555
518 // Entry point 556 // Entry point
519 void STDMETHODCALLTYPE CPluginClass::OnDownloadComplete() 557 void STDMETHODCALLTYPE CPluginClass::OnDownloadComplete()
520 { 558 {
521 try 559 try
522 { 560 {
561 if (!m_webBrowser2)
562 {
563 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::OnDownloadComplete - Reached with m_webBrowser2 == nullptr");
564 return;
565 }
523 DEBUG_NAVI(L"Navi::Download Complete") 566 DEBUG_NAVI(L"Navi::Download Complete")
524 ATL::CComPtr<IWebBrowser2> browser = GetBrowser(); 567 m_tab->OnDownloadComplete(m_webBrowser2);
525 if (browser)
526 {
527 m_tab->OnDownloadComplete(browser);
528 }
529 } 568 }
530 catch (...) 569 catch (...)
531 { 570 {
532 } 571 }
533 } 572 }
534 573
535 // Entry point 574 // Entry point
536 void STDMETHODCALLTYPE CPluginClass::OnDocumentComplete(IDispatch* frameBrowserD isp, VARIANT* /*urlOrPidl*/) 575 void STDMETHODCALLTYPE CPluginClass::OnDocumentComplete(IDispatch* frameBrowserD isp, VARIANT* /*urlOrPidl*/)
537 { 576 {
538 try 577 try
539 { 578 {
540 DEBUG_NAVI(L"Navi::Document Complete"); 579 DEBUG_NAVI(L"Navi::Document Complete");
541 ATL::CComQIPtr<IWebBrowser2> webBrowser2 = frameBrowserDisp; 580 ATL::CComQIPtr<IWebBrowser2> webBrowser2 = frameBrowserDisp;
542 if (!webBrowser2) 581 if (!webBrowser2)
543 { 582 {
544 return; 583 return;
545 } 584 }
546 std::wstring frameSrc = GetLocationUrl(*webBrowser2); 585 std::wstring frameSrc = GetLocationUrl(*webBrowser2);
547 UnescapeUrl(frameSrc); 586 m_tab->OnDocumentComplete(webBrowser2, frameSrc, IsRootBrowser(webBrowser2)) ;
548 bool isRootPageBrowser = GetBrowser().IsEqualObject(webBrowser2);
549 m_tab->OnDocumentComplete(webBrowser2, frameSrc, isRootPageBrowser);
550 } 587 }
551 catch (...) 588 catch (...)
552 { 589 {
553 } 590 }
554 } 591 }
555 592
556 // Entry point 593 // Entry point
557 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u nsigned long validFlagsMask) 594 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u nsigned long validFlagsMask)
558 { 595 {
559 try 596 try
560 { 597 {
561 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); 598 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)");
562 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL ECMDIDF_WINDOWSTATE_ENABLED) 599 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL ECMDIDF_WINDOWSTATE_ENABLED)
563 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA BLED); 600 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA BLED);
564 if (newtabshown) 601 if (newtabshown)
565 { 602 {
566 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find( GetCurrentThreadId()); 603 if (!m_isInitializedOk)
567 if (it == s_threadInstances.end()) 604 {
568 { 605 m_isInitializedOk = true;
569 s_threadInstances[::GetCurrentThreadId()] = this; 606 InitObject();
570 if (!m_isInitializedOk) 607 UpdateStatusBar();
571 {
572 m_isInitializedOk = true;
573 InitObject();
574 UpdateStatusBar();
575 }
576 } 608 }
577 } 609 }
578 notificationMessage.Hide(); 610 notificationMessage.Hide();
579 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end"); 611 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end");
580 } 612 }
581 catch (...) 613 catch (...)
582 { 614 {
583 } 615 }
584 } 616 }
585 617
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 { 650 {
619 Unadvise(); 651 Unadvise();
620 } 652 }
621 catch (...) 653 catch (...)
622 { 654 {
623 } 655 }
624 } 656 }
625 657
626 bool CPluginClass::InitObject() 658 bool CPluginClass::InitObject()
627 { 659 {
628 DEBUG_GENERAL("InitObject"); 660 DEBUG_GENERAL("InitObject - begin");
629 CPluginSettings* settings = CPluginSettings::GetInstance(); 661 CPluginSettings* settings = CPluginSettings::GetInstance();
630 662
631 if (!settings->GetPluginEnabled()) 663 if (!settings->GetPluginEnabled())
632 { 664 {
633 s_mimeFilter->Unregister(); 665 s_mimeFilter->Unregister();
634 } 666 }
635 667
636 // Load theme module 668 // Load theme module
637 s_criticalSectionLocal.Lock(); 669 s_criticalSectionLocal.Lock();
638 { 670 {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 if (((m_hPaneWnd == NULL) || !IsStatusBarEnabled()) && isFirstRun) 763 if (((m_hPaneWnd == NULL) || !IsStatusBarEnabled()) && isFirstRun)
732 { 764 {
733 ShowStatusBar(); 765 ShowStatusBar();
734 } 766 }
735 767
736 // Enable acceptable ads by default 768 // Enable acceptable ads by default
737 std::wstring aaUrl = CPluginClient::GetInstance()->GetPref(L"subscriptions_e xceptionsurl", L""); 769 std::wstring aaUrl = CPluginClient::GetInstance()->GetPref(L"subscriptions_e xceptionsurl", L"");
738 CPluginClient::GetInstance()->AddSubscription(aaUrl); 770 CPluginClient::GetInstance()->AddSubscription(aaUrl);
739 } 771 }
740 s_criticalSectionLocal.Unlock(); 772 s_criticalSectionLocal.Unlock();
773
774 DEBUG_GENERAL("InitObject - end");
741 return true; 775 return true;
742 } 776 }
743 777
744 bool CPluginClass::CreateStatusBarPane() 778 bool CPluginClass::CreateStatusBarPane()
745 { 779 {
746 CriticalSection::Lock lock(m_csStatusBar); 780 CriticalSection::Lock lock(m_csStatusBar);
747 781
748 CPluginClient* client = CPluginClient::GetInstance(); 782 CPluginClient* client = CPluginClient::GetInstance();
749 783
750 std::array<wchar_t, MAX_PATH> className; 784 std::array<wchar_t, MAX_PATH> className;
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 s_criticalSectionLocal.Unlock(); 1016 s_criticalSectionLocal.Unlock();
983 1017
984 return result; 1018 return result;
985 } 1019 }
986 1020
987 CPluginTab* CPluginClass::GetTab() 1021 CPluginTab* CPluginClass::GetTab()
988 { 1022 {
989 return m_tab; 1023 return m_tab;
990 } 1024 }
991 1025
992 CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) 1026 CPluginTab* CPluginClass::GetTabForCurrentThread()
993 { 1027 {
994 CPluginTab* tab = NULL; 1028 auto p = threadMap.Locate();
995 1029 return p ? p->m_tab : nullptr;
996 s_criticalSectionLocal.Lock(); 1030 }
997 { 1031
998 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(dw ThreadId); 1032 // Entry point
999 if (it != s_threadInstances.end())
1000 {
1001 tab = it->second->m_tab;
1002 }
1003 }
1004 s_criticalSectionLocal.Unlock();
1005
1006 return tab;
1007 }
1008
1009
1010 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O LECMD prgCmds[], OLECMDTEXT* pCmdText) 1033 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O LECMD prgCmds[], OLECMDTEXT* pCmdText)
1011 { 1034 {
1012 if (cCmds == 0) return E_INVALIDARG; 1035 try
1013 if (prgCmds == 0) return E_POINTER; 1036 {
1014 1037 if (cCmds == 0) return E_INVALIDARG;
1015 prgCmds[0].cmdf = OLECMDF_ENABLED; 1038 if (prgCmds == 0) return E_POINTER;
1016 1039
1040 prgCmds[0].cmdf = OLECMDF_ENABLED;
1041 }
1042 catch (...)
1043 {
1044 DEBUG_GENERAL(L"CPluginClass::QueryStatus - exception");
1045 return E_FAIL;
1046 }
1017 return S_OK; 1047 return S_OK;
1018 } 1048 }
1019 1049
1020 HMENU CPluginClass::CreatePluginMenu(const std::wstring& url) 1050 HMENU CPluginClass::CreatePluginMenu(const std::wstring& url)
1021 { 1051 {
1022 DEBUG_GENERAL("CreatePluginMenu"); 1052 DEBUG_GENERAL("CreatePluginMenu");
1023 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance(); 1053 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance();
1024 1054
1025 HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); 1055 HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
1026 1056
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 if (FAILED(hr)) 1147 if (FAILED(hr))
1118 { 1148 {
1119 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION _SETTINGS, "Navigation::Failed"); 1149 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION _SETTINGS, "Navigation::Failed");
1120 } 1150 }
1121 } 1151 }
1122 } 1152 }
1123 break; 1153 break;
1124 } 1154 }
1125 case ID_MENU_DISABLE_ON_SITE: 1155 case ID_MENU_DISABLE_ON_SITE:
1126 { 1156 {
1127 CPluginSettings* settings = CPluginSettings::GetInstance();
1128 std::wstring urlString = GetTab()->GetDocumentUrl(); 1157 std::wstring urlString = GetTab()->GetDocumentUrl();
1129 std::string filterText = client->GetWhitelistingFilter(urlString); 1158 std::string filterText = client->GetWhitelistingFilter(urlString);
1130 if (!filterText.empty()) 1159 if (!filterText.empty())
1131 { 1160 {
1132 client->RemoveFilter(filterText); 1161 client->RemoveFilter(filterText);
1133 } 1162 }
1134 else 1163 else
1135 { 1164 {
1136 settings->AddWhiteListedDomain(ToCString(client->GetHostFromUrl(urlStrin g))); 1165 CPluginSettings::GetInstance()->AddWhiteListedDomain(client->GetHostFrom Url(urlString));
1137 } 1166 }
1138 } 1167 }
1139 default: 1168 default:
1140 break; 1169 break;
1141 } 1170 }
1142 1171
1143 // Invalidate and redraw the control 1172 // Invalidate and redraw the control
1144 UpdateStatusBar(); 1173 UpdateStatusBar();
1145 } 1174 }
1146 1175
(...skipping 10 matching lines...) Expand all
1157 1186
1158 MENUITEMINFOW miiSep = {}; 1187 MENUITEMINFOW miiSep = {};
1159 miiSep.cbSize = sizeof(miiSep); 1188 miiSep.cbSize = sizeof(miiSep);
1160 miiSep.fMask = MIIM_TYPE | MIIM_FTYPE; 1189 miiSep.fMask = MIIM_TYPE | MIIM_FTYPE;
1161 miiSep.fType = MFT_SEPARATOR; 1190 miiSep.fType = MFT_SEPARATOR;
1162 1191
1163 CPluginClient* client = CPluginClient::GetInstance(); 1192 CPluginClient* client = CPluginClient::GetInstance();
1164 CPluginSettings* settings = CPluginSettings::GetInstance(); 1193 CPluginSettings* settings = CPluginSettings::GetInstance();
1165 { 1194 {
1166 ctext = dictionary->Lookup("menu", "menu-disable-on-site"); 1195 ctext = dictionary->Lookup("menu", "menu-disable-on-site");
1167 // Is domain in white list?
1168 ReplaceString(ctext, L"?1?", client->GetHostFromUrl(url)); 1196 ReplaceString(ctext, L"?1?", client->GetHostFromUrl(url));
1169 if (client->IsWhitelistedUrl(GetTab()->GetDocumentUrl())) 1197 /*
1170 { 1198 * The display state of the "disable on this site" menu item depends upon ta b content
1199 */
1200 if (!GetTab()->IsPossibleToDisableOnSite())
1201 {
1202 // Since we can't disable the present content,
1203 // it makes no sense to offer the user an option to block it.
1204 fmii.fState = MFS_UNCHECKED | MFS_DISABLED;
1205 }
1206 else if (client->IsWhitelistedUrl(GetTab()->GetDocumentUrl()))
1207 {
1208 // Domain is in white list, indicated by a check mark
1171 fmii.fState = MFS_CHECKED | MFS_ENABLED; 1209 fmii.fState = MFS_CHECKED | MFS_ENABLED;
1172 } 1210 }
1173 else 1211 else
1174 { 1212 {
1175 fmii.fState = MFS_UNCHECKED | MFS_ENABLED; 1213 fmii.fState = MFS_UNCHECKED | MFS_ENABLED;
1176 } 1214 }
1177 fmii.fMask = MIIM_STRING | MIIM_STATE; 1215 fmii.fMask = MIIM_STRING | MIIM_STATE;
1178 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); 1216 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str());
1179 fmii.cch = static_cast<UINT>(ctext.size()); 1217 fmii.cch = static_cast<UINT>(ctext.size());
1180 1218
(...skipping 28 matching lines...) Expand all
1209 ctext = dictionary->Lookup("menu", "menu-settings"); 1247 ctext = dictionary->Lookup("menu", "menu-settings");
1210 fmii.fMask = MIIM_STATE | MIIM_STRING; 1248 fmii.fMask = MIIM_STATE | MIIM_STRING;
1211 fmii.fState = MFS_ENABLED; 1249 fmii.fState = MFS_ENABLED;
1212 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); 1250 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str());
1213 fmii.cch = static_cast<UINT>(ctext.size()); 1251 fmii.cch = static_cast<UINT>(ctext.size());
1214 ::SetMenuItemInfoW(hMenu, ID_MENU_SETTINGS, FALSE, &fmii); 1252 ::SetMenuItemInfoW(hMenu, ID_MENU_SETTINGS, FALSE, &fmii);
1215 1253
1216 return true; 1254 return true;
1217 } 1255 }
1218 1256
1219 1257 // Entry point
1220 STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V ARIANTARG*) 1258 STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V ARIANTARG*)
1221 { 1259 {
1222 HWND hBrowserWnd = GetBrowserHWND(); 1260 try
1223 if (!hBrowserWnd) 1261 {
1224 { 1262 HWND hBrowserWnd = GetBrowserHWND();
1225 return E_FAIL; 1263 if (!hBrowserWnd)
1226 } 1264 {
1227 1265 return E_FAIL;
1228 // Create menu 1266 }
1229 HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl()); 1267
1230 if (!hMenu) 1268 // Create menu
1231 { 1269 HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl());
1232 return E_FAIL; 1270 if (!hMenu)
1233 } 1271 {
1234 1272 return E_FAIL;
1235 // Check if button in toolbar was pressed 1273 }
1236 int nIDCommand = -1; 1274
1237 BOOL bRightAlign = FALSE; 1275 // Check if button in toolbar was pressed
1238 1276 int nIDCommand = -1;
1239 POINT pt; 1277 BOOL bRightAlign = FALSE;
1240 GetCursorPos(&pt); 1278
1241 1279 POINT pt;
1242 HWND hWndToolBar = ::WindowFromPoint(pt); 1280 GetCursorPos(&pt);
1243 1281
1244 DWORD nProcessId; 1282 HWND hWndToolBar = ::WindowFromPoint(pt);
1245 ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); 1283
1246 1284 DWORD nProcessId;
1247 if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) 1285 ::GetWindowThreadProcessId(hWndToolBar, &nProcessId);
1248 { 1286
1249 ::ScreenToClient(hWndToolBar, &pt); 1287 if (hWndToolBar && ::GetCurrentProcessId() == nProcessId)
1250 int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); 1288 {
1251 1289 ::ScreenToClient(hWndToolBar, &pt);
1252 if (nButton > 0) 1290 int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt);
1253 { 1291
1254 TBBUTTON pTBBtn = {}; 1292 if (nButton > 0)
1255 1293 {
1256 if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) 1294 TBBUTTON pTBBtn = {};
1257 { 1295
1258 RECT rcButton; 1296 if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn))
1259 nIDCommand = pTBBtn.idCommand; 1297 {
1260 1298 RECT rcButton;
1261 if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton)) 1299 nIDCommand = pTBBtn.idCommand;
1262 { 1300
1263 pt.x = rcButton.left; 1301 if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton ))
1264 pt.y = rcButton.bottom;
1265 ClientToScreen(hWndToolBar, &pt);
1266
1267 RECT rcWorkArea;
1268 SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0);
1269 if (rcWorkArea.right - pt.x < 150)
1270 { 1302 {
1271 bRightAlign = TRUE; 1303 pt.x = rcButton.left;
1272 pt.x = rcButton.right;
1273 pt.y = rcButton.bottom; 1304 pt.y = rcButton.bottom;
1274 ClientToScreen(hWndToolBar, &pt); 1305 ClientToScreen(hWndToolBar, &pt);
1306
1307 RECT rcWorkArea;
1308 SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0);
1309 if (rcWorkArea.right - pt.x < 150)
1310 {
1311 bRightAlign = TRUE;
1312 pt.x = rcButton.right;
1313 pt.y = rcButton.bottom;
1314 ClientToScreen(hWndToolBar, &pt);
1315 }
1275 } 1316 }
1276 } 1317 }
1277 } 1318 }
1319 else
1320 {
1321 GetCursorPos(&pt);
1322 }
1323 }
1324
1325 // Display menu
1326 UINT nFlags = 0;
1327 if (bRightAlign)
1328 {
1329 nFlags |= TPM_RIGHTALIGN;
1278 } 1330 }
1279 else 1331 else
1280 { 1332 {
1281 GetCursorPos(&pt); 1333 nFlags |= TPM_LEFTALIGN;
1282 } 1334 }
1283 } 1335
1284 1336 DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags);
1285 // Display menu 1337 }
1286 UINT nFlags = 0; 1338 catch (...)
1287 if (bRightAlign) 1339 {
1288 { 1340 // Suppress exception, log only
1289 nFlags |= TPM_RIGHTALIGN; 1341 DEBUG_GENERAL(L"CPluginClass::Exec - exception");
1290 } 1342 return E_FAIL;
1291 else 1343 }
1292 {
1293 nFlags |= TPM_LEFTALIGN;
1294 }
1295
1296 DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags);
1297 1344
1298 return S_OK; 1345 return S_OK;
1299 } 1346 }
1300 1347
1301 ///////////////////////////////////////////////////////////////////////////// 1348 // Entry point
1302 // Window procedures
1303
1304 LRESULT CALLBACK CPluginClass::NewStatusProc(HWND hWnd, UINT message, WPARAM wPa ram, LPARAM lParam) 1349 LRESULT CALLBACK CPluginClass::NewStatusProc(HWND hWnd, UINT message, WPARAM wPa ram, LPARAM lParam)
1305 { 1350 {
1306 // Find tab 1351 CPluginClass *pClass;
1307 CPluginClass *pClass = FindInstance(hWnd); 1352 try
1308 if (!pClass) 1353 {
1309 { 1354 // Find tab
1310 return DefWindowProc(hWnd, message, wParam, lParam); 1355 pClass = FindInstance(hWnd);
1311 } 1356 if (!pClass)
1312 1357 {
1313 // Process message 1358 /*
1314 switch (message) 1359 * Race condition if reached.
1315 { 1360 * We did not unhook the window procedure for the status bar when the last BHO instance using it terminated.
1316 case SB_SIMPLE: 1361 * The next best thing is to call the system default window function.
1317 { 1362 */
1318 ShowWindow(pClass->m_hPaneWnd, !wParam); 1363 return DefWindowProc(hWnd, message, wParam, lParam);
1364 }
1365
1366 // Process message
1367 switch (message)
1368 {
1369 case SB_SIMPLE:
1370 {
1371 ShowWindow(pClass->m_hPaneWnd, !wParam);
1372 break;
1373 }
1374
1375 case WM_SYSCOLORCHANGE:
1376 {
1377 pClass->UpdateTheme();
1378 break;
1379 }
1380
1381 case SB_SETPARTS:
1382 {
1383 if (!lParam || !wParam || wParam > 30 || !IsWindow(pClass->m_hPaneWnd))
1384 {
1385 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lParam);
1386 }
1387
1388 WPARAM nParts = wParam;
1389 if (STATUSBAR_PANE_NUMBER >= nParts)
1390 {
1391 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lParam);
1392 }
1393
1394 HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts + 1));
1395 LPINT lpParts = (LPINT)LocalLock(hLocal);
1396 memcpy(lpParts, (void*)lParam, wParam*sizeof(int));
1397
1398 for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++)
1399 {
1400 lpParts[i] -= pClass->m_nPaneWidth;
1401 }
1402 LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, w Param, (LPARAM)lpParts);
1403
1404 AdblockPlus::Rectangle rcPane;
1405 ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane);
1406
1407 AdblockPlus::Rectangle rcClient;
1408 ::GetClientRect(hWnd, &rcClient);
1409
1410 ::MoveWindow(
1411 pClass->m_hPaneWnd,
1412 lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth,
1413 0,
1414 pClass->m_nPaneWidth,
1415 rcClient.Height(),
1416 TRUE);
1417
1418 ::LocalFree(hLocal);
1419 return hRet;
1420 }
1421
1422 default:
1319 break; 1423 break;
1320 } 1424 }
1321 1425 }
1322 case WM_SYSCOLORCHANGE: 1426 catch (...)
1323 { 1427 {
1324 pClass->UpdateTheme(); 1428 // Suppress exception. Fall through to default handler.
1325 break; 1429 DEBUG_GENERAL(L"CPluginClass::NewStatusProc - exception");
1326 } 1430 }
1327 1431 return ::CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lPara m);
1328 case SB_SETPARTS:
1329 {
1330 if (!lParam || !wParam || wParam > 30 || !IsWindow(pClass->m_hPaneWnd))
1331 {
1332 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, l Param);
1333 }
1334
1335 WPARAM nParts = wParam;
1336 if (STATUSBAR_PANE_NUMBER >= nParts)
1337 {
1338 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, l Param);
1339 }
1340
1341 HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts+1));
1342 LPINT lpParts = (LPINT)LocalLock(hLocal);
1343 memcpy(lpParts, (void*)lParam, wParam*sizeof(int));
1344
1345 for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++)
1346 {
1347 lpParts[i] -= pClass->m_nPaneWidth;
1348 }
1349 LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wPa ram, (LPARAM)lpParts);
1350
1351 AdblockPlus::Rectangle rcPane;
1352 ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane);
1353
1354 AdblockPlus::Rectangle rcClient;
1355 ::GetClientRect(hWnd, &rcClient);
1356
1357 ::MoveWindow(
1358 pClass->m_hPaneWnd,
1359 lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth,
1360 0,
1361 pClass->m_nPaneWidth,
1362 rcClient.Height(),
1363 TRUE);
1364
1365 ::LocalFree(hLocal);
1366
1367
1368 return hRet;
1369 }
1370
1371 default:
1372 break;
1373 }
1374
1375 LRESULT result = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wPara m, lParam);
1376
1377
1378 return result;
1379
1380 } 1432 }
1381 1433
1382 1434
1383 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url) 1435 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url)
1384 { 1436 {
1385 // use the disable icon as defualt, if the client doesn't exists 1437 // use the disable icon as defualt, if the client doesn't exists
1386 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); 1438 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED);
1387 1439
1388 CPluginTab* tab = GetTab(::GetCurrentThreadId()); 1440 CPluginTab* tab = GetTabForCurrentThread();
1389 if (tab) 1441 if (tab)
1390 { 1442 {
1391 CPluginClient* client = CPluginClient::GetInstance(); 1443 CPluginClient* client = CPluginClient::GetInstance();
1392 if (CPluginSettings::GetInstance()->IsPluginEnabled()) 1444 if (CPluginSettings::GetInstance()->IsPluginEnabled())
1393 { 1445 {
1394 if (client->IsWhitelistedUrl(url)) 1446 if (client->IsWhitelistedUrl(url))
1395 { 1447 {
1396 hIcon = GetIcon(ICON_PLUGIN_DISABLED); 1448 hIcon = GetIcon(ICON_PLUGIN_DISABLED);
1397 } 1449 }
1398 else 1450 else
1399 { 1451 {
1400 CPluginSettings* settings = CPluginSettings::GetInstance(); 1452 CPluginSettings* settings = CPluginSettings::GetInstance();
1401 hIcon = GetIcon(ICON_PLUGIN_ENABLED); 1453 hIcon = GetIcon(ICON_PLUGIN_ENABLED);
1402 } 1454 }
1403 } 1455 }
1404 } 1456 }
1405 return hIcon; 1457 return hIcon;
1406 } 1458 }
1407 1459
1408 1460 // Entry point
1409 LRESULT CALLBACK CPluginClass::PaneWindowProc(HWND hWnd, UINT message, WPARAM wP aram, LPARAM lParam) 1461 LRESULT CALLBACK CPluginClass::PaneWindowProc(HWND hWnd, UINT message, WPARAM wP aram, LPARAM lParam)
1410 { 1462 {
1411 // Find tab 1463 try
1412 CPluginClass *pClass = FindInstance(GetParent(hWnd)); 1464 {
1413 if (!pClass) 1465 // Find tab
1414 { 1466 CPluginClass *pClass = FindInstance(GetParent(hWnd));
1415 return ::DefWindowProc(hWnd, message, wParam, lParam); 1467 if (!pClass)
1416 } 1468 {
1417 1469 return ::DefWindowProc(hWnd, message, wParam, lParam);
1418 // Process message 1470 }
1419 switch (message) 1471
1420 { 1472 // Process message
1421 1473 switch (message)
1422 case WM_SETCURSOR: 1474 {
1423 { 1475 case WM_SETCURSOR:
1424 ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); 1476 {
1425 return TRUE; 1477 ::SetCursor(::LoadCursor(NULL, IDC_ARROW));
1426 } 1478 return TRUE;
1427 case WM_PAINT: 1479 }
1428 { 1480 case WM_PAINT:
1429 PAINTSTRUCT ps; 1481 {
1430 HDC hDC = ::BeginPaint(hWnd, &ps); 1482 PAINTSTRUCT ps;
1431 1483 HDC hDC = ::BeginPaint(hWnd, &ps);
1432 AdblockPlus::Rectangle rcClient; 1484
1433 ::GetClientRect(hWnd, &rcClient); 1485 AdblockPlus::Rectangle rcClient;
1434 1486 ::GetClientRect(hWnd, &rcClient);
1435 int nDrawEdge = 0; 1487
1436 1488 int nDrawEdge = 0;
1437 // Old Windows background drawing 1489
1438 if (pClass->m_hTheme == NULL) 1490 // Old Windows background drawing
1439 { 1491 if (pClass->m_hTheme == NULL)
1440 ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); 1492 {
1441 ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT); 1493 ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1));
1442 1494 ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT);
1443 nDrawEdge = 3; 1495
1444 rcClient.left += 3; 1496 nDrawEdge = 3;
1445 1497 rcClient.left += 3;
1446 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); 1498
1447 } 1499 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT);
1448 // Themed background drawing 1500 }
1449 else 1501 // Themed background drawing
1450 { 1502 else
1451 // Draw background 1503 {
1452 if (pfnDrawThemeBackground) 1504 // Draw background
1453 { 1505 if (pfnDrawThemeBackground)
1454 AdblockPlus::Rectangle rc = rcClient;
1455 rc.right -= 2;
1456 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL);
1457 }
1458
1459 // Copy separator picture to left side
1460 int nHeight = rcClient.Height();
1461 int nWidth = rcClient.Width() - 2;
1462
1463 for (int i = 0; i < 2; i++)
1464 {
1465 for (int j = 0; j < nHeight; j++)
1466 { 1506 {
1467 COLORREF clr = ::GetPixel(hDC, i + nWidth, j); 1507 AdblockPlus::Rectangle rc = rcClient;
1468 1508 rc.right -= 2;
1469 // Ignore black boxes (if source is obscured by other windows) 1509 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL);
1470 if (clr != -1 && (GetRValue(clr) > 8 || GetGValue(clr) > 8 || GetBVa lue(clr) > 8)) 1510 }
1511
1512 // Copy separator picture to left side
1513 int nHeight = rcClient.Height();
1514 int nWidth = rcClient.Width() - 2;
1515
1516 for (int i = 0; i < 2; i++)
1517 {
1518 for (int j = 0; j < nHeight; j++)
1471 { 1519 {
1472 ::SetPixel(hDC, i, j, clr); 1520 COLORREF clr = ::GetPixel(hDC, i + nWidth, j);
1521
1522 // Ignore black boxes (if source is obscured by other windows)
1523 if (clr != -1 && (GetRValue(clr) > 8 || GetGValue(clr) > 8 || GetB Value(clr) > 8))
1524 {
1525 ::SetPixel(hDC, i, j, clr);
1526 }
1473 } 1527 }
1474 } 1528 }
1475 } 1529 }
1476 } 1530
1477 1531 // Draw icon
1478 // Draw icon 1532 if (CPluginClient::GetInstance())
1479 if (CPluginClient::GetInstance()) 1533 {
1480 { 1534 HICON hIcon = GetStatusBarIcon(pClass->GetTab()->GetDocumentUrl());
1481 HICON hIcon = GetStatusBarIcon(pClass->GetTab()->GetDocumentUrl()); 1535
1482 1536 int offx = nDrawEdge;
1483 int offx = nDrawEdge; 1537 if (hIcon)
1484 if (hIcon) 1538 {
1485 { 1539 //Get the RECT for the leftmost pane (the status text pane)
1486 //Get the RECT for the leftmost pane (the status text pane) 1540 RECT rect;
1541 BOOL rectRes = ::SendMessage(pClass->m_hStatusBarWnd, SB_GETRECT, 0, (LPARAM)&rect);
1542 ::DrawIconEx(hDC, 0, rect.bottom - rect.top - iconHeight, hIcon, ico nWidth, iconHeight, NULL, NULL, DI_NORMAL);
1543 offx += iconWidth;
1544 }
1545 #ifdef _DEBUG
1546 // Display version
1547 HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT , 0, 0);
1548 HGDIOBJ hOldFont = ::SelectObject(hDC, hFont);
1549
1550 AdblockPlus::Rectangle rcText = rcClient;
1551 rcText.left += offx;
1552 ::SetBkMode(hDC, TRANSPARENT);
1553 ::DrawTextW(hDC, IEPLUGIN_VERSION, -1, &rcText, DT_WORD_ELLIPSIS | DT_ LEFT | DT_SINGLELINE | DT_VCENTER);
1554
1555 ::SelectObject(hDC, hOldFont);
1556 #endif // _DEBUG
1557 }
1558
1559 // Done!
1560 EndPaint(hWnd, &ps);
1561
1562 return 0;
1563 }
1564
1565 case WM_LBUTTONUP:
1566 case WM_RBUTTONUP:
1567 {
1568 std::wstring url = pClass->GetBrowserUrl();
1569 if (url != pClass->GetTab()->GetDocumentUrl())
1570 {
1571 pClass->GetTab()->SetDocumentUrl(url);
1572 }
1573
1574 // Create menu
1575 HMENU hMenu = pClass->CreatePluginMenu(url);
1576 if (!hMenu)
1577 {
1578 return 0;
1579 }
1580
1581 // Display menu
1582 POINT pt;
1583 ::GetCursorPos(&pt);
1584
1585 RECT rc;
1586 ::GetWindowRect(hWnd, &rc);
1587
1588 if (rc.left >= 0 && rc.top >= 0)
1589 {
1590 pt.x = rc.left;
1591 pt.y = rc.top;
1592 }
1593
1594 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN | TPM_BOTTOMALIGN );
1595 break;
1596 }
1597 case WM_DESTROY:
1598 break;
1599 case SC_CLOSE:
1600 break;
1601
1602 case WM_UPDATEUISTATE:
1603 {
1604 CPluginTab* tab = GetTabForCurrentThread();
1605 if (tab)
1606 {
1607 tab->OnActivate();
1487 RECT rect; 1608 RECT rect;
1488 BOOL rectRes = ::SendMessage(pClass->m_hStatusBarWnd, SB_GETRECT, 0, ( LPARAM)&rect); 1609 GetWindowRect(pClass->m_hPaneWnd, &rect);
1489 ::DrawIconEx(hDC, 0, rect.bottom - rect.top - iconHeight, hIcon, iconW idth, iconHeight, NULL, NULL, DI_NORMAL); 1610 pClass->notificationMessage.MoveToCenter(rect);
1490 offx += iconWidth; 1611 }
1491 } 1612 if (LOWORD(wParam) == UIS_CLEAR)
1492 #ifdef _DEBUG 1613 {
1493 // Display version 1614 pClass->notificationMessage.Hide();
1494 HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT, 0, 0); 1615 }
1495 HGDIOBJ hOldFont = ::SelectObject(hDC,hFont); 1616 break;
1496 1617 }
1497 AdblockPlus::Rectangle rcText = rcClient; 1618 case WM_WINDOWPOSCHANGING:
1498 rcText.left += offx;
1499 ::SetBkMode(hDC, TRANSPARENT);
1500 ::DrawTextW(hDC, IEPLUGIN_VERSION, -1, &rcText, DT_WORD_ELLIPSIS|DT_LEFT |DT_SINGLELINE|DT_VCENTER);
1501
1502 ::SelectObject(hDC, hOldFont);
1503 #endif // _DEBUG
1504 }
1505
1506 // Done!
1507 EndPaint(hWnd, &ps);
1508
1509 return 0;
1510 }
1511
1512 case WM_LBUTTONUP:
1513 case WM_RBUTTONUP:
1514 {
1515 std::wstring url = pClass->GetBrowserUrl();
1516 if (url != pClass->GetTab()->GetDocumentUrl())
1517 {
1518 pClass->GetTab()->SetDocumentUrl(url);
1519 }
1520
1521 // Create menu
1522 HMENU hMenu = pClass->CreatePluginMenu(url);
1523 if (!hMenu)
1524 {
1525 return 0;
1526 }
1527
1528 // Display menu
1529 POINT pt;
1530 ::GetCursorPos(&pt);
1531
1532 RECT rc;
1533 ::GetWindowRect(hWnd, &rc);
1534
1535 if (rc.left >= 0 && rc.top >= 0)
1536 {
1537 pt.x = rc.left;
1538 pt.y = rc.top;
1539 }
1540
1541 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN|TPM_BOTTOMALIGN);
1542 }
1543 break;
1544 case WM_DESTROY:
1545 break;
1546 case SC_CLOSE:
1547 break;
1548
1549 case WM_UPDATEUISTATE:
1550 {
1551 CPluginTab* tab = GetTab(::GetCurrentThreadId());
1552 if (tab)
1553 { 1619 {
1554 RECT rect; 1620 RECT rect;
1555 GetWindowRect(pClass->m_hPaneWnd, &rect); 1621 GetWindowRect(pClass->m_hPaneWnd, &rect);
1556 pClass->notificationMessage.Move(rect.left + (rect.right - rect.left) / 2, rect.top + (rect.bottom - rect.top) / 2); 1622 if (pClass->notificationMessage.IsVisible())
1557 } 1623 {
1558 if (LOWORD(wParam) == UIS_CLEAR) 1624 pClass->notificationMessage.MoveToCenter(rect);
1559 { 1625 }
1560 pClass->notificationMessage.Hide(); 1626 break;
1561 } 1627 }
1562 } 1628 case WM_WINDOWPOSCHANGED:
1563 break; 1629 {
1564 case WM_WINDOWPOSCHANGING: 1630 WINDOWPOS* wndPos = reinterpret_cast<WINDOWPOS*>(lParam);
1565 { 1631 if (wndPos->flags & SWP_HIDEWINDOW)
1566 RECT rect; 1632 {
1567 GetWindowRect(pClass->m_hPaneWnd, &rect); 1633 pClass->notificationMessage.Hide();
1568 if (pClass->notificationMessage.IsVisible()) 1634 }
1569 { 1635 break;
1570 pClass->notificationMessage.Move(rect.left + (rect.right - rect.left) / 2, rect.top + (rect.bottom - rect.top) / 2); 1636 }
1571 } 1637 case WM_ALREADY_UP_TO_DATE:
1572 } 1638 {
1573 break; 1639 Dictionary* dictionary = Dictionary::GetInstance();
1574 case WM_WINDOWPOSCHANGED: 1640 std::wstring upToDateText = dictionary->Lookup("updater", "update-alread y-up-to-date-text");
1575 { 1641 std::wstring upToDateTitle = dictionary->Lookup("updater", "update-alrea dy-up-to-date-title");
1576 WINDOWPOS* wndPos = reinterpret_cast<WINDOWPOS*>(lParam); 1642 pClass->notificationMessage.SetTextAndIcon(upToDateText, upToDateTitle, TTI_INFO);
1577 if (wndPos->flags & SWP_HIDEWINDOW) 1643 break;
1578 { 1644 }
1579 pClass->notificationMessage.Hide(); 1645 case WM_UPDATE_CHECK_ERROR:
1580 } 1646 {
1581 } 1647 Dictionary* dictionary = Dictionary::GetInstance();
1582 break; 1648 std::wstring errorText = dictionary->Lookup("updater", "update-error-tex t");
1583 case WM_ALREADY_UP_TO_DATE: 1649 std::wstring errorTitle = dictionary->Lookup("updater", "update-error-ti tle");
1584 { 1650 pClass->notificationMessage.SetTextAndIcon(errorText, errorTitle, TTI_ER ROR);
1585 Dictionary* dictionary = Dictionary::GetInstance(); 1651 break;
1586 std::wstring upToDateText = dictionary->Lookup("updater", "update-already- up-to-date-text"); 1652 }
1587 std::wstring upToDateTitle = dictionary->Lookup("updater", "update-already -up-to-date-title"); 1653 case WM_DOWNLOADING_UPDATE:
1588 pClass->notificationMessage.SetTextAndIcon(upToDateText, upToDateTitle, TT I_INFO); 1654 {
1589 } 1655 Dictionary* dictionary = Dictionary::GetInstance();
1590 break; 1656 std::wstring downloadingText = dictionary->Lookup("updater", "downloadin g-update-text");
1591 case WM_UPDATE_CHECK_ERROR: 1657 std::wstring downloadingTitle = dictionary->Lookup("updater", "downloadi ng-update-title");
1592 { 1658 pClass->notificationMessage.SetTextAndIcon(downloadingText, downloadingT itle, TTI_INFO);
1593 Dictionary* dictionary = Dictionary::GetInstance(); 1659 break;
1594 std::wstring errorText = dictionary->Lookup("updater", "update-error-text" ); 1660 }
1595 std::wstring errorTitle = dictionary->Lookup("updater", "update-error-titl e"); 1661 }
1596 pClass->notificationMessage.SetTextAndIcon(errorText, errorText, TTI_ERROR ); 1662 }
1597 } 1663 catch (...)
1598 break; 1664 {
1599 case WM_DOWNLOADING_UPDATE: 1665 // Suppress exception. Fall through to default handler.
1600 { 1666 DEBUG_GENERAL(L"CPluginClass::PaneWindowProc - exception");
1601 Dictionary* dictionary = Dictionary::GetInstance(); 1667 }
1602 std::wstring downloadingText = dictionary->Lookup("updater", "downloading- update-text"); 1668 return ::DefWindowProc(hWnd, message, wParam, lParam);
1603 std::wstring downloadingTitle = dictionary->Lookup("updater", "downloading -update-title");
1604 pClass->notificationMessage.SetTextAndIcon(downloadingText, downloadingTit le, TTI_INFO);
1605 }
1606 break;
1607 }
1608
1609 return DefWindowProc(hWnd, message, wParam, lParam);
1610 } 1669 }
1611 1670
1612 1671
1613 void CPluginClass::UpdateStatusBar() 1672 void CPluginClass::UpdateStatusBar()
1614 { 1673 {
1615 DEBUG_GENERAL("*** Updating statusbar") 1674 DEBUG_GENERAL("*** Updating statusbar")
1616 if (m_hPaneWnd == NULL) 1675 if (m_hPaneWnd == NULL)
1617 { 1676 {
1618 CreateStatusBarPane(); 1677 CreateStatusBarPane();
1619 } 1678 }
1620 if ((m_hPaneWnd != NULL) && !::InvalidateRect(m_hPaneWnd, NULL, FALSE)) 1679 if ((m_hPaneWnd != NULL) && !::InvalidateRect(m_hPaneWnd, NULL, FALSE))
1621 { 1680 {
1622 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_INVALID ATE_STATUSBAR, "Class::Invalidate statusbar"); 1681 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_INVALID ATE_STATUSBAR, "Class::Invalidate statusbar");
1623 } 1682 }
1624 } 1683 }
1625 1684
1626 1685
1627 void CPluginClass::Unadvise() 1686 void CPluginClass::Unadvise()
1628 { 1687 {
1688 if (!m_webBrowser2)
1689 {
1690 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::Unadvise - Reached with m_webBrowser 2 == nullptr");
1691 return;
1692 }
1629 s_criticalSectionLocal.Lock(); 1693 s_criticalSectionLocal.Lock();
1630 { 1694 {
1631 if (m_isAdvised) 1695 if (m_isAdvised)
1632 { 1696 {
1633 HRESULT hr = DispEventUnadvise(GetBrowser()); 1697 HRESULT hr = DispEventUnadvise(m_webBrowser2);
1634 if (FAILED(hr)) 1698 if (FAILED(hr))
1635 { 1699 {
1636 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_UNADVIS E, "Class::Unadvise - Unadvise"); 1700 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_UNADVIS E, "Class::Unadvise - Unadvise");
1637 } 1701 }
1638 m_isAdvised = false; 1702 m_isAdvised = false;
1639 } 1703 }
1640 } 1704 }
1641 s_criticalSectionLocal.Unlock(); 1705 s_criticalSectionLocal.Unlock();
1642 } 1706 }
1643 1707
(...skipping 19 matching lines...) Expand all
1663 s_criticalSectionLocal.Unlock(); 1727 s_criticalSectionLocal.Unlock();
1664 1728
1665 return icon; 1729 return icon;
1666 } 1730 }
1667 1731
1668 ATOM CPluginClass::GetAtomPaneClass() 1732 ATOM CPluginClass::GetAtomPaneClass()
1669 { 1733 {
1670 return s_atomPaneClass; 1734 return s_atomPaneClass;
1671 } 1735 }
1672 1736
1673 HWND CPluginClass::GetTabHWND() const
1674 {
1675 std::array<wchar_t, MAX_PATH> className;
1676 // Get browser window and url
1677 HWND hBrowserWnd = GetBrowserHWND();
1678 if (!hBrowserWnd)
1679 {
1680 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_BROWSER, "C lass::GetTabWindow - No tab window");
1681 s_criticalSectionWindow.Unlock();
1682 return false;
1683 }
1684
1685 // Looking for a TabWindowClass window in IE7
1686
1687 HWND hTabWnd = ::GetWindow(hBrowserWnd, GW_CHILD);
1688 while (hTabWnd)
1689 {
1690 className[0] = L'\0';
1691 int classNameLength = GetClassNameW(hTabWnd, className.data(), className.siz e());
1692
1693 if (classNameLength && (wcscmp(className.data(), L"TabWindowClass") == 0 || wcscmp(className.data(), L"Frame Tab") == 0))
1694 {
1695 // IE8 support
1696 HWND hTabWnd2 = hTabWnd;
1697 if (wcscmp(className.data(), L"Frame Tab") == 0)
1698 {
1699 hTabWnd2 = ::FindWindowEx(hTabWnd2, NULL, L"TabWindowClass", NULL);
1700 }
1701
1702 if (hTabWnd2)
1703 {
1704 DWORD nProcessId;
1705 ::GetWindowThreadProcessId(hTabWnd2, &nProcessId);
1706 if (::GetCurrentProcessId() == nProcessId)
1707 {
1708 bool bExistingTab = false;
1709 s_criticalSectionLocal.Lock();
1710
1711 {
1712 for (auto instance : s_instances)
1713 {
1714 if (instance->m_hTabWnd == hTabWnd2)
1715 {
1716 bExistingTab = true;
1717 break;
1718 }
1719 }
1720 }
1721
1722 if (!bExistingTab)
1723 {
1724 hBrowserWnd = hTabWnd2;
1725 hTabWnd = hTabWnd2;
1726 s_criticalSectionLocal.Unlock();
1727 break;
1728 }
1729 s_criticalSectionLocal.Unlock();
1730
1731 }
1732 }
1733 }
1734
1735 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT);
1736 }
1737 return hTabWnd;
1738 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld