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

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

Issue 6567422169448448: Issue 119 - Switch to injecting CSS for element hiding (Closed)
Left Patch Set: Created Dec. 10, 2014, 5:12 p.m.
Right Patch Set: rename OnQuit Created Sept. 30, 2016, 3:25 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/PluginDomTraverserBase.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 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2016 Eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
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/>.
16 */
17
1 #include "PluginStdAfx.h" 18 #include "PluginStdAfx.h"
2 19
3 #include "PluginClass.h" 20 #include "PluginClass.h"
4 #include "PluginSettings.h" 21 #include "PluginSettings.h"
5 #include "PluginSystem.h" 22 #include "PluginSystem.h"
6 #include "PluginFilter.h" 23 #include "PluginFilter.h"
7 #include "PluginMimeFilterClient.h" 24 #include "PluginMimeFilterClient.h"
8 #include "PluginClient.h" 25 #include "AdblockPlusClient.h"
26 #include "PluginClientBase.h"
9 #include "PluginClientFactory.h" 27 #include "PluginClientFactory.h"
10 #include "PluginMutex.h"
11 #include "sddl.h"
12 #include "PluginUtil.h" 28 #include "PluginUtil.h"
13 #include "PluginUserSettings.h"
14 #include "../shared/Utils.h" 29 #include "../shared/Utils.h"
15 #include "../shared/Dictionary.h" 30 #include "../shared/Dictionary.h"
16 #include "WebBrowserEventsListener.h" 31 #include "IeVersion.h"
32 #include "../shared/Version.h"
17 #include <thread> 33 #include <thread>
18 #include <array> 34 #include <array>
35 #include "WebBrowserEventsListener.h"
19 36
20 #ifdef DEBUG_HIDE_EL 37 #ifdef DEBUG_HIDE_EL
21 DWORD profileTime = 0; 38 DWORD profileTime = 0;
22 #endif 39 #endif
23 40
41 extern CComModule _Module;
42
24 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); 43 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR);
25 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR ECT); 44 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR ECT);
26 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); 45 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE);
27 46
28 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL }; 47 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL };
29 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 };
49 uint32_t iconHeight = 32;
50 uint32_t iconWidth = 32;
30 51
31 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; 52 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL;
32 53
33 CLOSETHEMEDATA pfnClose = NULL; 54 CLOSETHEMEDATA pfnClose = NULL;
34 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; 55 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL;
35 OPENTHEMEDATA pfnOpenThemeData = NULL; 56 OPENTHEMEDATA pfnOpenThemeData = NULL;
36 57
37 ATOM CPluginClass::s_atomPaneClass = NULL; 58 ATOM CPluginClass::s_atomPaneClass = NULL;
38 HINSTANCE CPluginClass::s_hUxtheme = NULL; 59 HINSTANCE CPluginClass::s_hUxtheme = NULL;
39 std::set<CPluginClass*> CPluginClass::s_instances; 60 std::set<CPluginClass*> CPluginClass::s_instances;
40 std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances; 61 std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances;
41 62
42 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; 63 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal;
43 CComAutoCriticalSection CPluginClass::s_criticalSectionBrowser;
44 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; 64 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow;
45 65
46 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; 66 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2;
47 std::map<UINT,CString> CPluginClass::s_menuDomains;
48 67
49 /* 68 /*
50 * Without namespace declaration, the identifier "Rectangle" is ambiguous 69 * Without namespace declaration, the identifier "Rectangle" is ambiguous
51 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx 70 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx
52 */ 71 */
53 namespace AdblockPlus 72 namespace AdblockPlus
54 { 73 {
55 /** 74 /**
56 * Replacement for ATL type CRect. 75 * Replacement for ATL type CRect.
57 */ 76 */
58 class Rectangle 77 class Rectangle
59 : public RECT 78 : public RECT
60 { 79 {
61 public: 80 public:
62 int Height() const 81 unsigned long Height() const
63 { 82 {
64 return bottom - top; 83 if (bottom < top)
65 } 84 {
66 85 throw std::runtime_error("invariant violation: rectangle bottom < top");
67 int Width() const 86 }
68 { 87 return static_cast<unsigned long>(bottom - top);
69 return right - left; 88 }
89
90 unsigned long Width() const
91 {
92 if (right < left)
93 {
94 throw std::runtime_error("invariant violation: rectangle right < left");
95 }
96 return static_cast<unsigned long>(right - left);
70 } 97 }
71 }; 98 };
72 } 99 }
73 100
74 CPluginClass::CPluginClass() 101 CPluginClass::CPluginClass()
75 : m_data(std::make_shared<Data>()) 102 : m_data(std::make_shared<Data>())
76 { 103 {
104 DEBUG_GENERAL([this]() -> std::wstring
105 {
106 std::wstring s = L"CPluginClass::<constructor>, this = ";
107 s += ToHexLiteral(this);
108 return s;
109 }());
110
77 //Use this line to debug memory leaks 111 //Use this line to debug memory leaks
78 // _CrtDumpMemoryLeaks(); 112 // _CrtDumpMemoryLeaks();
79 113
80 m_isAdviced = false; 114 m_isAdvised = false;
81 m_hTabWnd = NULL; 115 m_hTabWnd = NULL;
82 m_hStatusBarWnd = NULL; 116 m_hStatusBarWnd = NULL;
83 m_hPaneWnd = NULL; 117 m_hPaneWnd = NULL;
84 m_nPaneWidth = 0; 118 m_nPaneWidth = 0;
85 m_pWndProcStatus = NULL; 119 m_pWndProcStatus = NULL;
86 m_hTheme = NULL; 120 m_hTheme = NULL;
87 m_isInitializedOk = false; 121 m_isInitializedOk = false;
88 122
89 123
90 m_data->tab.reset(new CPluginTab(this)); 124 m_data->tab.reset(new CPluginTab());
125
91 Dictionary::Create(GetBrowserLanguage()); 126 Dictionary::Create(GetBrowserLanguage());
92 } 127 }
93 128
94 CPluginClass::~CPluginClass() 129 CPluginClass::~CPluginClass()
95 { 130 {
96 } 131 DEBUG_GENERAL([this]() -> std::wstring
97 132 {
98 ///////////////////////////////////////////////////////////////////////////// 133 std::wstring s = L"CPluginClass::<destructor>, this = ";
99 // Initialization 134 s += ToHexLiteral(this);
100 135 return s;
101 HRESULT CPluginClass::FinalConstruct() 136 }());
102 { 137
103 return S_OK; 138 m_data.reset();
104 }
105
106 void CPluginClass::FinalRelease()
107 {
108 s_criticalSectionBrowser.Lock();
109 {
110 m_data.reset();
111 }
112 s_criticalSectionBrowser.Unlock();
113 } 139 }
114 140
115 HWND CPluginClass::GetBrowserHWND() const 141 HWND CPluginClass::GetBrowserHWND() const
116 { 142 {
117 SHANDLE_PTR hBrowserWndHandle = NULL; 143 if (!m_data->webBrowser2)
118 144 {
119 CComQIPtr<IWebBrowser2> browser = GetBrowser(); 145 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::GetBrowserHWND - Reached with webBro wser2 == nullptr");
120 if (browser) 146 return nullptr;
121 { 147 }
122 HRESULT hr = browser->get_HWND(&hBrowserWndHandle); 148 SHANDLE_PTR hBrowserWndHandle = 0;
123 if (FAILED(hr)) 149 HRESULT hr = m_data->webBrowser2->get_HWND(&hBrowserWndHandle);
124 { 150 if (FAILED(hr))
125 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_BROWSER_WINDOW, " Class::GetBrowserHWND - failed") 151 {
126 } 152 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_BROWSER_WINDOW, "Cl ass::GetBrowserHWND - failed");
127 } 153 return nullptr;
128 154 }
129 return (HWND)hBrowserWndHandle; 155 return (HWND)hBrowserWndHandle;
130 } 156 }
131 157
132 158 bool CPluginClass::IsRootBrowser(IWebBrowser2* otherBrowser)
133 CComQIPtr<IWebBrowser2> CPluginClass::GetBrowser() const 159 {
160 return m_data->webBrowser2.IsEqualObject(otherBrowser);
161 }
162
163 CComQIPtr<IWebBrowser2> CPluginClass::GetAsyncBrowser()
134 { 164 {
135 CComQIPtr<IWebBrowser2> browser; 165 CComQIPtr<IWebBrowser2> browser;
136 166
137 s_criticalSectionBrowser.Lock(); 167 s_criticalSectionLocal.Lock();
138 { 168 {
139 browser = m_data->webBrowser2; 169 browser = s_asyncWebBrowser2;
140 } 170 }
141 s_criticalSectionBrowser.Unlock(); 171 s_criticalSectionLocal.Unlock();
142 172
143 return browser; 173 return browser;
144 } 174 }
145 175
146 176 std::wstring CPluginClass::GetBrowserUrl() const
147 CComQIPtr<IWebBrowser2> CPluginClass::GetAsyncBrowser() 177 {
148 { 178 std::wstring url;
149 CComQIPtr<IWebBrowser2> browser; 179 if (m_data->webBrowser2)
150
151 s_criticalSectionLocal.Lock();
152 {
153 browser = s_asyncWebBrowser2;
154 }
155 s_criticalSectionLocal.Unlock();
156
157 return browser;
158 }
159
160 CString CPluginClass::GetBrowserUrl() const
161 {
162 CString url;
163
164 CComQIPtr<IWebBrowser2> browser = GetBrowser();
165 if (browser)
166 { 180 {
167 CComBSTR bstrURL; 181 CComBSTR bstrURL;
168 182 if (SUCCEEDED(m_data->webBrowser2->get_LocationURL(&bstrURL)))
169 if (SUCCEEDED(browser->get_LocationURL(&bstrURL))) 183 {
170 { 184 url = ToWstring(bstrURL);
171 url = bstrURL;
172 CPluginClient::UnescapeUrl(url);
173 } 185 }
174 } 186 }
175 else 187 else
176 { 188 {
189 DEBUG_GENERAL(L"CPluginClass::GetBrowserUrl - Reached with webBrowser2 == nu llptr (probable invariant violation)");
190 }
191 if (url.empty())
192 {
177 url = m_data->tab->GetDocumentUrl(); 193 url = m_data->tab->GetDocumentUrl();
178 } 194 }
179
180 return url; 195 return url;
181 } 196 }
182 197
183 DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr) 198 DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr)
184 { 199 {
185 if (thisPtr == NULL) 200 if (thisPtr == NULL)
186 return 0; 201 return 0;
187 if (!((CPluginClass*)thisPtr)->InitObject(true)) 202 if (!((CPluginClass*)thisPtr)->InitObject())
188 { 203 {
189 ((CPluginClass*)thisPtr)->Unadvice(); 204 ((CPluginClass*)thisPtr)->Unadvise();
190 } 205 }
191 206
192 return 0; 207 return 0;
193 } 208 }
194 209
195 210 /*
196 211 * IE calls this when it creates a new browser window or tab, immediately after it also
197 // This gets called when a new browser window is created (which also triggers th e 212 * creates the object. The argument 'unknownSite' in is the OLE "site" of the ob ject,
198 // creation of this object). The pointer passed in should be to a IWebBrowser2 213 * which is an IWebBrowser2 interface associated with the window/tab.
199 // interface that represents the browser for the window. 214 *
200 // it is also called when a tab is closed, this unknownSite will be null 215 * IE also ordinarily calls this again when its window/tab is closed, in which c ase
201 // so we should handle that it is called this way several times during a session 216 * 'unknownSite' will be null. Extraordinarily, this is sometimes _not_ called w hen IE
217 * is shutting down. Thus 'SetSite(nullptr)' has some similarities with a destru ctor,
218 * but it is not a proper substitute for one.
219 */
202 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) 220 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite)
203 { 221 {
204 CPluginSettings* settings = CPluginSettings::GetInstance(); 222 try
205 223 {
206 MULTIPLE_VERSIONS_CHECK(); 224 if (unknownSite)
207 225 {
208 if (unknownSite) 226 DEBUG_GENERAL(L"========================================================== ======================\nNEW TAB UI\n============================================ ====================================");
209 { 227
210 228 HRESULT hr = ::CoInitialize(NULL);
211 DEBUG_GENERAL(L"============================================================ ====================\nNEW TAB UI\n============================================== ==================================") 229 if (FAILED(hr))
212 230 {
213 HRESULT hr = ::CoInitialize(NULL); 231 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT, "Class::SetSite - CoInitialize");
214 if (FAILED(hr)) 232 }
215 { 233
216 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT, " Class::SetSite - CoInitialize"); 234 /*
217 } 235 * We were instantiated as a BHO, so our site is always of type IWebBrowse r2.
218 236 */
219 s_criticalSectionBrowser.Lock();
220 {
221 m_data->webBrowser2 = ATL::CComQIPtr<IWebBrowser2>(unknownSite); 237 m_data->webBrowser2 = ATL::CComQIPtr<IWebBrowser2>(unknownSite);
222 } 238 if (!m_data->webBrowser2)
223 s_criticalSectionBrowser.Unlock(); 239 {
224 240 throw std::logic_error("CPluginClass::SetSite - Unable to convert site p ointer to IWebBrowser2*");
225 //register the mimefilter 241 }
226 //and only mimefilter 242 DEBUG_GENERAL([this]() -> std::wstring
227 //on some few computers the mimefilter does not get properly registered when it is done on another thread 243 {
228 244 std::wstringstream ss;
229 s_criticalSectionLocal.Lock(); 245 ss << L"CPluginClass::SetSite, this = " << ToHexLiteral(this);
230 { 246 ss << L", browser = " << ToHexLiteral(m_data->webBrowser2);
231 // Always register on startup, then check if we need to unregister in a se parate thread 247 return ss.str();
232 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); 248 }());
233 s_asyncWebBrowser2 = unknownSite; 249
234 s_instances.insert(this); 250 //register the mimefilter
235 } 251 //and only mimefilter
236 s_criticalSectionLocal.Unlock(); 252 //on some few computers the mimefilter does not get properly registered wh en it is done on another thread
237 253 s_criticalSectionLocal.Lock();
238 try 254 {
239 { 255 // Always register on startup, then check if we need to unregister in a separate thread
240 // Check if loaded as BHO 256 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance();
241 auto webBrowser = GetBrowser(); 257 s_asyncWebBrowser2 = unknownSite;
242 if (webBrowser) 258 s_instances.insert(this);
243 { 259 }
244 DEBUG_GENERAL("Loaded as BHO"); 260 s_criticalSectionLocal.Unlock();
245 HRESULT hr = DispEventAdvise(webBrowser); 261
262 try
263 {
264 HRESULT hr = DispEventAdvise(m_data->webBrowser2);
246 if (SUCCEEDED(hr)) 265 if (SUCCEEDED(hr))
247 { 266 {
248 m_isAdviced = true; 267 m_isAdvised = true;
249 try 268 try
250 { 269 {
251 std::thread startInitObjectThread(StartInitObject, this); 270 std::thread startInitObjectThread(StartInitObject, this);
252 startInitObjectThread.detach(); // TODO: but actually we should wait for the thread in the dtr. 271 startInitObjectThread.detach(); // TODO: but actually we should wait for the thread in the dtr.
253 } 272 }
254 catch (const std::system_error& ex) 273 catch (const std::system_error& ex)
255 { 274 {
256 auto errDescription = std::string("Class::Thread - Failed to create StartInitObject thread, ") + 275 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_TH READ_CREATE_PROCESS,
257 ex.code().message() + ex.what(); 276 "Class::Thread - Failed to create StartInitObject thread");
258 DEBUG_ERROR_LOG(ex.code().value(), PLUGIN_ERROR_THREAD, PLUGIN_ERROR _MAIN_THREAD_CREATE_PROCESS, errDescription.c_str());
259 } 277 }
260 } 278 }
261 else 279 else
262 { 280 {
263 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVIC E, "Class::SetSite - Advice"); 281 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVIC E, "Class::SetSite - Advise");
264 } 282 }
265 } 283 }
266 else // Check if loaded as toolbar handler 284 catch (const std::runtime_error& ex)
267 { 285 {
268 DEBUG_GENERAL("Loaded as toolbar handler"); 286 DEBUG_EXCEPTION(ex);
269 CComPtr<IServiceProvider> pServiceProvider; 287 Unadvise();
270 288 }
271 HRESULT hr = unknownSite->QueryInterface(&pServiceProvider); 289 }
272 if (SUCCEEDED(hr)) 290 else
273 { 291 {
274 if (pServiceProvider) 292 DEBUG_GENERAL([this]() -> std::wstring
275 { 293 {
276 s_criticalSectionBrowser.Lock(); 294 std::wstringstream ss;
277 { 295 ss << L"CPluginClass::SetSite, this = " << ToHexLiteral(this);
278 HRESULT hr = pServiceProvider->QueryService(IID_IWebBrowserApp, &m _data->webBrowser2); 296 ss << L", browser = nullptr";
279 if (SUCCEEDED(hr)) 297 return ss.str();
280 { 298 }());
281 if (m_data->webBrowser2) 299
282 { 300 Unadvise();
283 InitObject(false); 301 assert(m_data->connectedWebBrowsersCache.empty() && "Connected web browser cache should be already empty");
284 } 302
285 } 303 // Destroy window
286 else 304 if (m_pWndProcStatus)
287 { 305 {
288 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE _QUERY_BROWSER, "Class::SetSite - QueryService (IID_IWebBrowserApp)"); 306 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWn dProcStatus);
289 } 307
290 } 308 m_pWndProcStatus = NULL;
291 s_criticalSectionBrowser.Unlock(); 309 }
292 } 310
293 } 311 if (m_hPaneWnd)
294 else 312 {
295 { 313 DestroyWindow(m_hPaneWnd);
296 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_QUERY _SERVICE_PROVIDER, "Class::SetSite - QueryInterface (service provider)"); 314 m_hPaneWnd = NULL;
297 } 315 }
298 } 316
299 } 317 m_hTabWnd = NULL;
300 catch (std::runtime_error e) 318 m_hStatusBarWnd = NULL;
301 { 319
302 DEBUG_ERROR(e.what()); 320 // Remove instance from the list, shutdown threads
303 Unadvice(); 321 HANDLE hMainThread = NULL;
304 } 322 HANDLE hTabThread = NULL;
305 } 323
306 else 324 s_criticalSectionLocal.Lock();
307 { 325 {
308 // Unadvice 326 s_instances.erase(this);
309 Unadvice(); 327
310 328 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::Ge tCurrentThreadId());
311 // Destroy window 329 if (it != s_threadInstances.end())
312 if (m_pWndProcStatus) 330 {
313 { 331 s_threadInstances.erase(it);
314 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWndP rocStatus); 332 }
315 333 if (s_instances.empty())
316 m_pWndProcStatus = NULL; 334 {
317 } 335 // TODO: Explicitly releasing a resource when a container becomes empt y looks like a job better suited for shared_ptr
318 336 CPluginClientFactory::ReleaseMimeFilterClientInstance();
319 if (m_hPaneWnd) 337 }
320 { 338 }
321 DestroyWindow(m_hPaneWnd); 339 s_criticalSectionLocal.Unlock();
322 m_hPaneWnd = NULL; 340
323 } 341 m_data->webBrowser2 = nullptr;
324 342
325 m_hTabWnd = NULL; 343 DEBUG_GENERAL("=========================================================== =====================\nNEW TAB UI - END\n======================================= =========================================")
326 m_hStatusBarWnd = NULL; 344
327 345 ::CoUninitialize();
328 // Remove instance from the list, shutdown threads 346 }
329 HANDLE hMainThread = NULL; 347
330 HANDLE hTabThread = NULL; 348 }
331 349 catch (...)
332 s_criticalSectionLocal.Lock(); 350 {
333 { 351 }
334 s_instances.erase(this); 352 IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite);
335 353 return S_OK;
336 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetC urrentThreadId());
337 if (it != s_threadInstances.end())
338 {
339 s_threadInstances.erase(it);
340 }
341 if (s_instances.empty())
342 {
343 CPluginClientFactory::ReleaseMimeFilterClientInstance();
344 }
345 }
346 s_criticalSectionLocal.Unlock();
347
348 // Release browser interface
349 s_criticalSectionBrowser.Lock();
350 {
351 m_data->webBrowser2.Release();
352 }
353 s_criticalSectionBrowser.Unlock();
354
355 DEBUG_GENERAL("============================================================= ===================\nNEW TAB UI - END\n========================================= =======================================")
356
357 ::CoUninitialize();
358 }
359
360 return IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite);
361 } 354 }
362 355
363 bool CPluginClass::IsStatusBarEnabled() 356 bool CPluginClass::IsStatusBarEnabled()
364 { 357 {
365 DEBUG_GENERAL("IsStatusBarEnabled start"); 358 DEBUG_GENERAL("IsStatusBarEnabled start");
366 HKEY pHkey; 359 HKEY pHkey;
367 HKEY pHkeySub; 360 HKEY pHkeySub;
368 RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey); 361 RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey);
369 DWORD truth = 1; 362 DWORD truth = 1;
370 DWORD truthSize = sizeof(truth); 363 DWORD truthSize = sizeof(truth);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 } 459 }
467 } 460 }
468 else 461 else
469 { 462 {
470 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_STATUSBAR, "Class ::Get statusbar state"); 463 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_GET_STATUSBAR, "Class ::Get statusbar state");
471 } 464 }
472 } 465 }
473 DEBUG_GENERAL("ShowStatusBar end"); 466 DEBUG_GENERAL("ShowStatusBar end");
474 } 467 }
475 468
469 // Entry point
476 void STDMETHODCALLTYPE CPluginClass::OnBeforeNavigate2( 470 void STDMETHODCALLTYPE CPluginClass::OnBeforeNavigate2(
477 /* [in] */ IDispatch* frameBrowserDisp, 471 IDispatch* frameBrowserDisp /**< [in] */,
478 /* [in] */ VARIANT* urlVariant, 472 VARIANT* urlVariant /**< [in] */,
479 /* [in] */ VARIANT* /*Flags*/, 473 VARIANT* /**< [in] Flags*/,
480 /* [in] */ VARIANT* /*TargetFrameName*/, 474 VARIANT* /**< [in] TargetFrameName*/,
481 /* [in] */ VARIANT* /*PostData*/, 475 VARIANT* /**< [in] PostData*/,
482 /* [in] */ VARIANT* /*Headers*/, 476 VARIANT* /**< [in] Headers*/,
483 /* [in, out] */ VARIANT_BOOL* /*Cancel*/) 477 VARIANT_BOOL* /**< [in, out] Cancel*/)
484 { 478 {
485 ATL::CComQIPtr<IWebBrowser2> webBrowser = frameBrowserDisp; 479 try
486 if (!webBrowser) 480 {
487 { 481 ATL::CComQIPtr<IWebBrowser2> webBrowser = frameBrowserDisp;
488 return; 482 if (!webBrowser)
489 } 483 {
490 484 return;
491 if (!urlVariant || urlVariant->vt != VT_BSTR) 485 }
492 { 486 if (!urlVariant || urlVariant->vt != VT_BSTR)
493 return; 487 {
494 } 488 return;
495 std::wstring url(V_BSTR(urlVariant), SysStringLen(V_BSTR(urlVariant))); 489 }
496 UnescapeUrl(url); 490 std::wstring url = ToWstring(urlVariant->bstrVal);
497 491 EnsureWebBrowserConnected(webBrowser);
498 { 492
Oleksandr 2015/02/04 20:59:57 I would prefer for this to be a separate function
sergei 2015/04/13 08:06:58 I've extracted it into CPluginClass::EnsureWebBrow
sergei 2015/04/13 08:06:58 I guess here and below instead of CPluginClientFac
499 auto it = m_data->connectedWebBrowsersCache.find(webBrowser); 493 // If webbrowser2 is equal to top level browser (as set in SetSite), we are
500 if (m_data->connectedWebBrowsersCache.end() == it) 494 // navigating new page
Oleksandr 2015/02/04 20:59:57 This is Yoda condition, IMO
sergei 2015/04/13 08:06:58 fixed
501 { 495 CPluginClient* client = CPluginClient::GetInstance();
502 ATL::CComObject<WebBrowserEventsListener>* listenerImpl = nullptr; 496 if (url.find(L"javascript") == 0)
503 if (FAILED(ATL::CComObject<WebBrowserEventsListener>::CreateInstance(&list enerImpl))) 497 {
504 { 498 }
505 return; 499 else if (IsRootBrowser(webBrowser))
506 } 500 {
507 ATL::CComPtr<IUnknown> listnerRefCounterGuard(listenerImpl->GetUnknown()); 501 m_data->tab->OnNavigate(url);
Oleksandr 2015/02/04 20:59:57 missing 'e'? listenerRefCounterGuard
sergei 2015/04/13 08:06:58 fixed
508 std::weak_ptr<Data> dataForCapturing = m_data; 502 DEBUG_GENERAL(
509 auto onListenerDestroy = [webBrowser, dataForCapturing] 503 L"======================================================================== ========\n"
Oleksandr 2015/02/04 20:59:57 If this whole block is moved to CPluginClientFacto
sergei 2015/04/13 08:06:58 I think it will complicate the code because it is
510 { 504 L"Begin main navigation url:" + url + L"\n"
511 if (auto data = dataForCapturing.lock()) 505 L"======================================================================== ========")
512 {
513 data->connectedWebBrowsersCache.erase(webBrowser);
514 }
515 };
516 if (FAILED(listenerImpl->Init(webBrowser, onListenerDestroy)))
517 {
518 return;
519 }
520 listenerImpl->reloaded = [webBrowser, dataForCapturing]
521 {
522 if (auto data = dataForCapturing.lock())
523 {
524 auto frameSrc = GetLocationUrl(*webBrowser);
525 UnescapeUrl(frameSrc);
526 data->tab->OnDocumentComplete(webBrowser, ToCString(frameSrc), data->w ebBrowser2.IsEqualObject(webBrowser));
527 }
528 };
529 m_data->connectedWebBrowsersCache.emplace(webBrowser, listenerImpl);
530 }
531 }
532
533 //Register a mime filter if it's not registered yet
534 if (s_mimeFilter == NULL)
535 {
536 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance();
537 }
538
539 CString urlCString = ToCString(url);
540
541 // If webbrowser2 is equal to top level browser (as set in SetSite), we are na vigating new page
542 CPluginClient* client = CPluginClient::GetInstance();
543
544 if (urlCString.Find(L"javascript") == 0)
545 {
546 }
547 else if (GetBrowser().IsEqualObject(webBrowser))
548 {
549 m_data->tab->OnNavigate(urlCString);
550
551 DEBUG_GENERAL(L"============================================================ ====================\nBegin main navigation url:" + urlCString + "\n============ ====================================================================")
552 506
553 #ifdef ENABLE_DEBUG_RESULT 507 #ifdef ENABLE_DEBUG_RESULT
554 CPluginDebug::DebugResultDomain(urlCString); 508 CPluginDebug::DebugResultDomain(url);
555 #endif 509 #endif
556 510 UpdateStatusBar();
557 UpdateStatusBar(); 511 }
558 } 512 else
559 else 513 {
560 { 514 DEBUG_NAVI(L"Navi::Begin navigation url:" + url)
561 DEBUG_NAVI(L"Navi::Begin navigation url:" + urlCString) 515 m_data->tab->CacheFrame(url);
562 m_data->tab->CacheFrame(urlCString); 516 }
563 } 517 }
564 } 518 catch (...)
565 519 {
566 void STDMETHODCALLTYPE CPluginClass::OnDownloadBegin() 520 }
567 { 521 }
568 DEBUG_NAVI("Navi::Download Begin") 522
569 } 523 // Entry point
570
571 void STDMETHODCALLTYPE CPluginClass::OnDownloadComplete() 524 void STDMETHODCALLTYPE CPluginClass::OnDownloadComplete()
572 { 525 {
573 DEBUG_NAVI("Navi::Download Complete") 526 try
574 ATL::CComPtr<IWebBrowser2> browser = GetBrowser(); 527 {
575 if (browser) 528 if (!m_data->webBrowser2)
576 { 529 {
577 m_data->tab->OnDownloadComplete(browser); 530 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::OnDownloadComplete - Reached with webBrowser2 == nullptr");
578 } 531 return;
579 } 532 }
580 533 DEBUG_NAVI(L"Navi::Download Complete")
581 void STDMETHODCALLTYPE CPluginClass::OnDocumentComplete(IDispatch* frameBrowserD isp, VARIANT* /*urlOrPidl*/) 534 m_data->tab->OnDownloadComplete(m_data->webBrowser2);
582 { 535 }
583 } 536 catch (...)
584 537 {
538 }
539 }
540
541 // Entry point
585 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u nsigned long validFlagsMask) 542 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u nsigned long validFlagsMask)
586 { 543 {
587 DEBUG_GENERAL("Tab changed"); 544 try
588 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLEC MDIDF_WINDOWSTATE_ENABLED) 545 {
589 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WIN DOWSTATE_ENABLED); 546 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)");
590 if (newtabshown) 547 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL ECMDIDF_WINDOWSTATE_ENABLED)
591 { 548 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA BLED);
592 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(Ge tCurrentThreadId()); 549 if (newtabshown)
593 if (it == s_threadInstances.end()) 550 {
594 { 551 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find( GetCurrentThreadId());
595 s_threadInstances[::GetCurrentThreadId()] = this; 552 if (it == s_threadInstances.end())
596 if (!m_isInitializedOk) 553 {
597 { 554 s_threadInstances[::GetCurrentThreadId()] = this;
598 m_isInitializedOk = true; 555 if (!m_isInitializedOk)
599 if (!InitObject(true)) 556 {
600 { 557 m_isInitializedOk = true;
601 //» » » » » Unadvice(); 558 InitObject();
602 } 559 UpdateStatusBar();
603 UpdateStatusBar(); 560 }
604 } 561 }
605 } 562 }
606 } 563 notificationMessage.Hide();
607 notificationMessage.Hide(); 564 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end");
608 DEBUG_GENERAL("Tab change end"); 565 }
609 } 566 catch (...)
610 567 {
568 }
569 }
570
571 // Entry point
611 void STDMETHODCALLTYPE CPluginClass::OnCommandStateChange(long /*command*/, VARI ANT_BOOL /*enable*/) 572 void STDMETHODCALLTYPE CPluginClass::OnCommandStateChange(long /*command*/, VARI ANT_BOOL /*enable*/)
612 { 573 {
613 if (m_hPaneWnd == NULL) 574 try
614 { 575 {
615 CreateStatusBarPane(); 576 if (m_hPaneWnd == NULL)
616 } 577 {
617 else 578 CreateStatusBarPane();
618 { 579 }
619 if (CPluginClient::GetInstance()->GetIEVersion() > 6) 580 else
620 { 581 {
621 RECT rect; 582 if (AdblockPlus::IE::InstalledMajorVersion() > 6)
622 BOOL rectRes = GetClientRect(m_hStatusBarWnd, &rect); 583 {
623 if (rectRes == TRUE) 584 RECT rect;
624 { 585 //Get the RECT for the leftmost pane (the status text pane)
625 MoveWindow(m_hPaneWnd, rect.right - 200, 0, m_nPaneWidth, rect.bottom - rect.top, TRUE); 586 BOOL rectRes = ::SendMessage(m_hStatusBarWnd, SB_GETRECT, 0, (LPARAM)&re ct);
626 } 587 if (rectRes == TRUE)
627 } 588 {
628 } 589 MoveWindow(m_hPaneWnd, rect.right - m_nPaneWidth, 0, m_nPaneWidth, rec t.bottom - rect.top, TRUE);
629 } 590 }
630 591 }
631 bool CPluginClass::InitObject(bool bBHO) 592 }
632 { 593 }
633 DEBUG_GENERAL("InitObject"); 594 catch (...)
595 {
596 }
597 }
598
599 // Entry point
600 void STDMETHODCALLTYPE CPluginClass::OnOnQuit()
601 {
602 try
603 {
604 Unadvise();
605 }
606 catch (...)
607 {
608 }
609 }
610
611 bool CPluginClass::InitObject()
612 {
613 DEBUG_GENERAL("InitObject - begin");
634 CPluginSettings* settings = CPluginSettings::GetInstance(); 614 CPluginSettings* settings = CPluginSettings::GetInstance();
635 615
636 if (!settings->GetPluginEnabled()) 616 if (!settings->GetPluginEnabled())
637 { 617 {
638 s_mimeFilter->Unregister(); 618 s_mimeFilter->Unregister();
639 } 619 }
640 620
641 // Load theme module 621 // Load theme module
642 s_criticalSectionLocal.Lock(); 622 s_criticalSectionLocal.Lock();
643 { 623 {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 } 676 }
697 s_criticalSectionLocal.Unlock(); 677 s_criticalSectionLocal.Unlock();
698 678
699 if (!GetAtomPaneClass()) 679 if (!GetAtomPaneClass())
700 { 680 {
701 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_REGISTE R_PANE_CLASS, "Class::InitObject - RegisterClassEx"); 681 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_REGISTE R_PANE_CLASS, "Class::InitObject - RegisterClassEx");
702 return false; 682 return false;
703 } 683 }
704 } 684 }
705 685
706 686 int ieVersion = AdblockPlus::IE::InstalledMajorVersion();
707 int ieVersion = CPluginClient::GetInstance()->GetIEVersion();
708 // Create status pane 687 // Create status pane
709 if (bBHO && ieVersion > 6 && !CreateStatusBarPane()) 688 if (ieVersion > 6 && !CreateStatusBarPane())
710 { 689 {
711 return false; 690 return false;
712 } 691 }
713 692
714 s_criticalSectionLocal.Lock(); 693 s_criticalSectionLocal.Lock();
715 int versionCompRes = CPluginClient::GetInstance()->CompareVersions(CPluginClie nt::GetInstance()->GetPref(L"currentVersion", L"0.0"), L"1.2"); 694 int versionCompRes = CPluginClient::GetInstance()->CompareVersions(CPluginClie nt::GetInstance()->GetPref(L"currentVersion", L"0.0"), L"1.2");
716 695
717 bool isFirstRun = CPluginClient::GetInstance()->IsFirstRun(); 696 bool isFirstRun = CPluginClient::GetInstance()->IsFirstRun();
718 CPluginClient::GetInstance()->SetPref(L"currentVersion", std::wstring(IEPLUGIN _VERSION)); 697 CPluginClient::GetInstance()->SetPref(L"currentVersion", std::wstring(IEPLUGIN _VERSION));
719 // This is the first time ABP was installed 698 // This is the first time ABP was installed
(...skipping 17 matching lines...) Expand all
737 if (((m_hPaneWnd == NULL) || !IsStatusBarEnabled()) && isFirstRun) 716 if (((m_hPaneWnd == NULL) || !IsStatusBarEnabled()) && isFirstRun)
738 { 717 {
739 ShowStatusBar(); 718 ShowStatusBar();
740 } 719 }
741 720
742 // Enable acceptable ads by default 721 // Enable acceptable ads by default
743 std::wstring aaUrl = CPluginClient::GetInstance()->GetPref(L"subscriptions_e xceptionsurl", L""); 722 std::wstring aaUrl = CPluginClient::GetInstance()->GetPref(L"subscriptions_e xceptionsurl", L"");
744 CPluginClient::GetInstance()->AddSubscription(aaUrl); 723 CPluginClient::GetInstance()->AddSubscription(aaUrl);
745 } 724 }
746 s_criticalSectionLocal.Unlock(); 725 s_criticalSectionLocal.Unlock();
726
727 DEBUG_GENERAL("InitObject - end");
747 return true; 728 return true;
748 } 729 }
749 730
750 bool CPluginClass::CreateStatusBarPane() 731 bool CPluginClass::CreateStatusBarPane()
751 { 732 {
752 CriticalSection::Lock lock(m_csStatusBar); 733 CriticalSection::Lock lock(m_csStatusBar);
753 734
754 CPluginClient* client = CPluginClient::GetInstance(); 735 CPluginClient* client = CPluginClient::GetInstance();
755 736
756 std::array<wchar_t, MAX_PATH> className; 737 std::array<wchar_t, MAX_PATH> className;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_WIN, "Class ::CreateStatusBarPane - No status bar") 824 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_WIN, "Class ::CreateStatusBarPane - No status bar")
844 return true; 825 return true;
845 } 826 }
846 827
847 // Calculate pane height 828 // Calculate pane height
848 AdblockPlus::Rectangle rcStatusBar; 829 AdblockPlus::Rectangle rcStatusBar;
849 ::GetClientRect(hWndStatusBar, &rcStatusBar); 830 ::GetClientRect(hWndStatusBar, &rcStatusBar);
850 831
851 if (rcStatusBar.Height() > 0) 832 if (rcStatusBar.Height() > 0)
852 { 833 {
834 if (rcStatusBar.Height() < iconWidth)
835 {
836 iconWidth = 19;
837 iconHeight = 19;
838 }
839
853 #ifdef _DEBUG 840 #ifdef _DEBUG
854 m_nPaneWidth = 70; 841 m_nPaneWidth = 70;
855 #else 842 #else
856 m_nPaneWidth = min(rcStatusBar.Height(), 22); 843 m_nPaneWidth = min(rcStatusBar.Height(), iconWidth);
857 #endif 844 #endif
858 } 845 }
859 else 846 else
860 { 847 {
861 #ifdef _DEBUG 848 #ifdef _DEBUG
862 m_nPaneWidth = 70; 849 m_nPaneWidth = 70;
863 #else 850 #else
864 m_nPaneWidth = 22; 851 m_nPaneWidth = iconWidth;
865 #endif 852 #endif
866 } 853 }
867 // Create pane window 854 // Create pane window
868 HWND hWndNewPane = ::CreateWindowEx( 855 HWND hWndNewPane = ::CreateWindowEx(
869 NULL, 856 NULL,
870 MAKEINTATOM(GetAtomPaneClass()), 857 MAKEINTATOM(GetAtomPaneClass()),
871 L"", 858 L"",
872 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 859 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
873 rcStatusBar.Width() - 500,0,m_nPaneWidth,rcStatusBar.Height(), 860 rcStatusBar.Width() - 500, 0, m_nPaneWidth, rcStatusBar.Height(),
874 hWndStatusBar, 861 hWndStatusBar,
875 (HMENU)3671, 862 (HMENU)3671,
876 _Module.m_hInst, 863 _Module.m_hInst,
877 NULL); 864 NULL);
878 865
879 if (!hWndNewPane) 866 if (!hWndNewPane)
880 { 867 {
881 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_CREATE_ST ATUSBAR_PANE, "Class::CreateStatusBarPane - CreateWindowEx") 868 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_CREATE_ST ATUSBAR_PANE, "Class::CreateStatusBarPane - CreateWindowEx")
882 return false; 869 return false;
883 } 870 }
(...skipping 23 matching lines...) Expand all
907 894
908 HDC hdc = GetWindowDC(m_hStatusBarWnd); 895 HDC hdc = GetWindowDC(m_hStatusBarWnd);
909 SendMessage(m_hStatusBarWnd, WM_PAINT, (WPARAM)hdc, 0); 896 SendMessage(m_hStatusBarWnd, WM_PAINT, (WPARAM)hdc, 0);
910 ReleaseDC(m_hStatusBarWnd, hdc); 897 ReleaseDC(m_hStatusBarWnd, hdc);
911 898
912 return true; 899 return true;
913 } 900 }
914 901
915 void CPluginClass::FirstRunThread() 902 void CPluginClass::FirstRunThread()
916 { 903 {
904 // Just return if the First Run Page should be suppressed
905 if (CPluginClient::GetInstance()->GetPref(L"suppress_first_run_page", false))
906 return;
907
917 CoInitialize(NULL); 908 CoInitialize(NULL);
918 VARIANT vFlags; 909 VARIANT vFlags;
919 vFlags.vt = VT_I4; 910 vFlags.vt = VT_I4;
920 vFlags.intVal = navOpenInNewTab; 911 vFlags.intVal = navOpenInNewTab;
921 912
922 CComBSTR navigatePath = CComBSTR(FirstRunPageFileUrl().c_str()); 913 CComBSTR navigatePath = CComBSTR(FirstRunPageFileUrl().c_str());
923 914
924 HRESULT hr = GetAsyncBrowser()->Navigate(navigatePath, &vFlags, NULL, NULL, NU LL); 915 HRESULT hr = GetAsyncBrowser()->Navigate(navigatePath, &vFlags, NULL, NULL, NU LL);
925 if (FAILED(hr)) 916 if (FAILED(hr))
926 { 917 {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 if (it != s_threadInstances.end()) 986 if (it != s_threadInstances.end())
996 { 987 {
997 tab = it->second->m_data->tab.get(); 988 tab = it->second->m_data->tab.get();
998 } 989 }
999 } 990 }
1000 s_criticalSectionLocal.Unlock(); 991 s_criticalSectionLocal.Unlock();
1001 992
1002 return tab; 993 return tab;
1003 } 994 }
1004 995
1005 996 // Entry point
1006 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O LECMD prgCmds[], OLECMDTEXT* pCmdText) 997 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O LECMD prgCmds[], OLECMDTEXT* pCmdText)
1007 { 998 {
1008 if (cCmds == 0) return E_INVALIDARG; 999 try
1009 if (prgCmds == 0) return E_POINTER; 1000 {
1010 1001 if (cCmds == 0) return E_INVALIDARG;
1011 prgCmds[0].cmdf = OLECMDF_ENABLED; 1002 if (prgCmds == 0) return E_POINTER;
1012 1003
1004 prgCmds[0].cmdf = OLECMDF_ENABLED;
1005 }
1006 catch (...)
1007 {
1008 DEBUG_GENERAL(L"CPluginClass::QueryStatus - exception");
1009 return E_FAIL;
1010 }
1013 return S_OK; 1011 return S_OK;
1014 } 1012 }
1015 1013
1016 HMENU CPluginClass::CreatePluginMenu(const CString& url) 1014 HMENU CPluginClass::CreatePluginMenu(const std::wstring& url)
1017 { 1015 {
1018 DEBUG_GENERAL("CreatePluginMenu"); 1016 DEBUG_GENERAL("CreatePluginMenu");
1019 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance(); 1017 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance();
1020 1018
1021 HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); 1019 HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
1022 1020
1023 HMENU hMenuTrackPopup = GetSubMenu(hMenu, 0); 1021 HMENU hMenuTrackPopup = GetSubMenu(hMenu, 0);
1024 1022
1025 SetMenuBar(hMenuTrackPopup, url); 1023 SetMenuBar(hMenuTrackPopup, url);
1026 1024
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 case ID_MENU_SETTINGS: 1094 case ID_MENU_SETTINGS:
1097 { 1095 {
1098 CComQIPtr<IWebBrowser2> browser = GetAsyncBrowser(); 1096 CComQIPtr<IWebBrowser2> browser = GetAsyncBrowser();
1099 if (browser) 1097 if (browser)
1100 { 1098 {
1101 VARIANT vFlags; 1099 VARIANT vFlags;
1102 vFlags.vt = VT_I4; 1100 vFlags.vt = VT_I4;
1103 vFlags.intVal = navOpenInNewTab; 1101 vFlags.intVal = navOpenInNewTab;
1104 1102
1105 auto userSettingsFileUrl = UserSettingsFileUrl(); 1103 auto userSettingsFileUrl = UserSettingsFileUrl();
1106 ATL::CComBSTR urlToNavigate(userSettingsFileUrl.length(), userSettingsFi leUrl.c_str()); 1104 ATL::CComBSTR urlToNavigate(static_cast<int>(userSettingsFileUrl.length( )), userSettingsFileUrl.c_str());
1107 HRESULT hr = browser->Navigate(urlToNavigate, &vFlags, NULL, NULL, NULL) ; 1105 HRESULT hr = browser->Navigate(urlToNavigate, &vFlags, NULL, NULL, NULL) ;
1108 if (FAILED(hr)) 1106 if (FAILED(hr))
1109 { 1107 {
1110 vFlags.intVal = navOpenInNewWindow; 1108 vFlags.intVal = navOpenInNewWindow;
1111 1109
1112 hr = browser->Navigate(urlToNavigate, &vFlags, NULL, NULL, NULL); 1110 hr = browser->Navigate(urlToNavigate, &vFlags, NULL, NULL, NULL);
1113 if (FAILED(hr)) 1111 if (FAILED(hr))
1114 { 1112 {
1115 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION _SETTINGS, "Navigation::Failed") 1113 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_NAVIGATION, PLUGIN_ERROR_NAVIGATION _SETTINGS, "Navigation::Failed")
1116 } 1114 }
1117 } 1115 }
1118 } 1116 }
1119 break; 1117 break;
1120 } 1118 }
1121 case ID_MENU_DISABLE_ON_SITE: 1119 case ID_MENU_DISABLE_ON_SITE:
1122 { 1120 {
1123 CPluginSettings* settings = CPluginSettings::GetInstance(); 1121 std::wstring urlString = GetTab()->GetDocumentUrl();
1124 CString urlString = GetTab()->GetDocumentUrl(); 1122 std::string filterText = client->GetWhitelistingFilter(urlString);
1125 if (client->IsWhitelistedUrl(to_wstring(urlString))) 1123 if (!filterText.empty())
1126 { 1124 {
1127 settings->RemoveWhiteListedDomain(to_CString(client->GetHostFromUrl(to_w string(urlString)))); 1125 client->RemoveFilter(filterText);
1128 } 1126 }
1129 else 1127 else
1130 { 1128 {
1131 settings->AddWhiteListedDomain(to_CString(client->GetHostFromUrl(to_wstr ing(urlString)))); 1129 CPluginSettings::GetInstance()->AddWhiteListedDomain(client->GetHostFrom Url(urlString));
1132 } 1130 }
1133 GetBrowser()->Refresh();
1134 } 1131 }
1135 default: 1132 default:
1136 break; 1133 break;
1137 } 1134 }
1138 1135
1139 // Invalidate and redraw the control 1136 // Invalidate and redraw the control
1140 UpdateStatusBar(); 1137 UpdateStatusBar();
1141 } 1138 }
1142 1139
1143 1140
1144 bool CPluginClass::SetMenuBar(HMENU hMenu, const CString& url) 1141 bool CPluginClass::SetMenuBar(HMENU hMenu, const std::wstring& url)
1145 { 1142 {
1146 DEBUG_GENERAL("SetMenuBar"); 1143 DEBUG_GENERAL("SetMenuBar");
1147 1144
1148 std::wstring ctext; 1145 std::wstring ctext;
1149
1150 s_criticalSectionLocal.Lock();
1151 {
1152 s_menuDomains.clear();
1153 }
1154 s_criticalSectionLocal.Unlock();
1155
1156 Dictionary* dictionary = Dictionary::GetInstance(); 1146 Dictionary* dictionary = Dictionary::GetInstance();
1157 1147
1158 MENUITEMINFOW fmii = {}; 1148 MENUITEMINFOW fmii = {};
1159 fmii.cbSize = sizeof(fmii); 1149 fmii.cbSize = sizeof(fmii);
1160 1150
1161 MENUITEMINFOW miiSep = {}; 1151 MENUITEMINFOW miiSep = {};
1162 miiSep.cbSize = sizeof(miiSep); 1152 miiSep.cbSize = sizeof(miiSep);
1163 miiSep.fMask = MIIM_TYPE | MIIM_FTYPE; 1153 miiSep.fMask = MIIM_TYPE | MIIM_FTYPE;
1164 miiSep.fType = MFT_SEPARATOR; 1154 miiSep.fType = MFT_SEPARATOR;
1165 1155
1166 CPluginClient* client = CPluginClient::GetInstance(); 1156 CPluginClient* client = CPluginClient::GetInstance();
1167 CPluginSettings* settings = CPluginSettings::GetInstance(); 1157 CPluginSettings* settings = CPluginSettings::GetInstance();
1168 { 1158 {
1169 ctext = dictionary->Lookup("menu", "menu-disable-on-site"); 1159 ctext = dictionary->Lookup("menu", "menu-disable-on-site");
1170 // Is domain in white list? 1160 ReplaceString(ctext, L"?1?", client->GetHostFromUrl(url));
1171 ReplaceString(ctext, L"?1?", client->GetHostFromUrl(to_wstring(url))); 1161 /*
1172 if (client->IsWhitelistedUrl(to_wstring(GetTab()->GetDocumentUrl()))) 1162 * The display state of the "disable on this site" menu item depends upon ta b content
1173 { 1163 */
1164 if (!GetTab()->IsPossibleToDisableOnSite())
1165 {
1166 // Since we can't disable the present content,
1167 // it makes no sense to offer the user an option to block it.
1168 fmii.fState = MFS_UNCHECKED | MFS_DISABLED;
1169 }
1170 else if (client->IsWhitelistedUrl(GetTab()->GetDocumentUrl()))
1171 {
1172 // Domain is in white list, indicated by a check mark
1174 fmii.fState = MFS_CHECKED | MFS_ENABLED; 1173 fmii.fState = MFS_CHECKED | MFS_ENABLED;
1175 } 1174 }
1176 else 1175 else
1177 { 1176 {
1178 fmii.fState = MFS_UNCHECKED | MFS_ENABLED; 1177 fmii.fState = MFS_UNCHECKED | MFS_ENABLED;
1179 } 1178 }
1180 fmii.fMask = MIIM_STRING | MIIM_STATE; 1179 fmii.fMask = MIIM_STRING | MIIM_STATE;
1181 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); 1180 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str());
1182 fmii.cch = static_cast<UINT>(ctext.size()); 1181 fmii.cch = static_cast<UINT>(ctext.size());
1183 1182
(...skipping 28 matching lines...) Expand all
1212 ctext = dictionary->Lookup("menu", "menu-settings"); 1211 ctext = dictionary->Lookup("menu", "menu-settings");
1213 fmii.fMask = MIIM_STATE | MIIM_STRING; 1212 fmii.fMask = MIIM_STATE | MIIM_STRING;
1214 fmii.fState = MFS_ENABLED; 1213 fmii.fState = MFS_ENABLED;
1215 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); 1214 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str());
1216 fmii.cch = static_cast<UINT>(ctext.size()); 1215 fmii.cch = static_cast<UINT>(ctext.size());
1217 ::SetMenuItemInfoW(hMenu, ID_MENU_SETTINGS, FALSE, &fmii); 1216 ::SetMenuItemInfoW(hMenu, ID_MENU_SETTINGS, FALSE, &fmii);
1218 1217
1219 return true; 1218 return true;
1220 } 1219 }
1221 1220
1222 1221 // Entry point
1223 STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V ARIANTARG*) 1222 STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V ARIANTARG*)
1224 { 1223 {
1225 HWND hBrowserWnd = GetBrowserHWND(); 1224 try
1226 if (!hBrowserWnd) 1225 {
1227 { 1226 HWND hBrowserWnd = GetBrowserHWND();
1228 return E_FAIL; 1227 if (!hBrowserWnd)
1229 } 1228 {
1230 1229 return E_FAIL;
1231 // Create menu 1230 }
1232 HMENU hMenu = CreatePluginMenu(m_data->tab->GetDocumentUrl()); 1231
1233 if (!hMenu) 1232 // Create menu
1234 { 1233 HMENU hMenu = CreatePluginMenu(m_data->tab->GetDocumentUrl());
1235 return E_FAIL; 1234 if (!hMenu)
1236 } 1235 {
1237 1236 return E_FAIL;
1238 // Check if button in toolbar was pressed 1237 }
1239 int nIDCommand = -1; 1238
1240 BOOL bRightAlign = FALSE; 1239 // Check if button in toolbar was pressed
1241 1240 int nIDCommand = -1;
1242 POINT pt; 1241 BOOL bRightAlign = FALSE;
1243 GetCursorPos(&pt); 1242
1244 1243 POINT pt;
1245 HWND hWndToolBar = ::WindowFromPoint(pt); 1244 GetCursorPos(&pt);
1246 1245
1247 DWORD nProcessId; 1246 HWND hWndToolBar = ::WindowFromPoint(pt);
1248 ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); 1247
1249 1248 DWORD nProcessId;
1250 if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) 1249 ::GetWindowThreadProcessId(hWndToolBar, &nProcessId);
1251 { 1250
1252 ::ScreenToClient(hWndToolBar, &pt); 1251 if (hWndToolBar && ::GetCurrentProcessId() == nProcessId)
1253 int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); 1252 {
1254 1253 ::ScreenToClient(hWndToolBar, &pt);
1255 if (nButton > 0) 1254 int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt);
1256 { 1255
1257 TBBUTTON pTBBtn = {}; 1256 if (nButton > 0)
1258 1257 {
1259 if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) 1258 TBBUTTON pTBBtn = {};
1260 { 1259
1261 RECT rcButton; 1260 if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn))
1262 nIDCommand = pTBBtn.idCommand; 1261 {
1263 1262 RECT rcButton;
1264 if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton)) 1263 nIDCommand = pTBBtn.idCommand;
1265 { 1264
1266 pt.x = rcButton.left; 1265 if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton ))
1267 pt.y = rcButton.bottom;
1268 ClientToScreen(hWndToolBar, &pt);
1269
1270 RECT rcWorkArea;
1271 SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0);
1272 if (rcWorkArea.right - pt.x < 150)
1273 { 1266 {
1274 bRightAlign = TRUE; 1267 pt.x = rcButton.left;
1275 pt.x = rcButton.right;
1276 pt.y = rcButton.bottom; 1268 pt.y = rcButton.bottom;
1277 ClientToScreen(hWndToolBar, &pt); 1269 ClientToScreen(hWndToolBar, &pt);
1270
1271 RECT rcWorkArea;
1272 SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0);
1273 if (rcWorkArea.right - pt.x < 150)
1274 {
1275 bRightAlign = TRUE;
1276 pt.x = rcButton.right;
1277 pt.y = rcButton.bottom;
1278 ClientToScreen(hWndToolBar, &pt);
1279 }
1278 } 1280 }
1279 } 1281 }
1280 } 1282 }
1283 else
1284 {
1285 GetCursorPos(&pt);
1286 }
1287 }
1288
1289 // Display menu
1290 UINT nFlags = 0;
1291 if (bRightAlign)
1292 {
1293 nFlags |= TPM_RIGHTALIGN;
1281 } 1294 }
1282 else 1295 else
1283 { 1296 {
1284 GetCursorPos(&pt); 1297 nFlags |= TPM_LEFTALIGN;
1285 } 1298 }
1286 } 1299
1287 1300 DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags);
1288 // Display menu 1301 }
1289 UINT nFlags = 0; 1302 catch (...)
1290 if (bRightAlign) 1303 {
1291 { 1304 // Suppress exception, log only
1292 nFlags |= TPM_RIGHTALIGN; 1305 DEBUG_GENERAL(L"CPluginClass::Exec - exception");
1293 } 1306 return E_FAIL;
1294 else 1307 }
1295 {
1296 nFlags |= TPM_LEFTALIGN;
1297 }
1298
1299 DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags);
1300 1308
1301 return S_OK; 1309 return S_OK;
1302 } 1310 }
1303 1311
1304 ///////////////////////////////////////////////////////////////////////////// 1312 // Entry point
1305 // Window procedures
1306
1307 LRESULT CALLBACK CPluginClass::NewStatusProc(HWND hWnd, UINT message, WPARAM wPa ram, LPARAM lParam) 1313 LRESULT CALLBACK CPluginClass::NewStatusProc(HWND hWnd, UINT message, WPARAM wPa ram, LPARAM lParam)
1308 { 1314 {
1309 // Find tab 1315 CPluginClass *pClass;
1310 CPluginClass *pClass = FindInstance(hWnd); 1316 try
1311 if (!pClass) 1317 {
1312 { 1318 // Find tab
1313 return DefWindowProc(hWnd, message, wParam, lParam); 1319 pClass = FindInstance(hWnd);
1314 } 1320 if (!pClass)
1315 1321 {
1316 // Process message 1322 /*
1317 switch (message) 1323 * Race condition if reached.
1318 { 1324 * We did not unhook the window procedure for the status bar when the last BHO instance using it terminated.
1319 case SB_SIMPLE: 1325 * The next best thing is to call the system default window function.
1320 { 1326 */
1321 ShowWindow(pClass->m_hPaneWnd, !wParam); 1327 return DefWindowProc(hWnd, message, wParam, lParam);
1328 }
1329
1330 // Process message
1331 switch (message)
1332 {
1333 case SB_SIMPLE:
1334 {
1335 ShowWindow(pClass->m_hPaneWnd, !wParam);
1336 break;
1337 }
1338
1339 case WM_SYSCOLORCHANGE:
1340 {
1341 pClass->UpdateTheme();
1342 break;
1343 }
1344
1345 case SB_SETPARTS:
1346 {
1347 if (!lParam || !wParam || wParam > 30 || !IsWindow(pClass->m_hPaneWnd))
1348 {
1349 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lParam);
1350 }
1351
1352 WPARAM nParts = wParam;
1353 if (STATUSBAR_PANE_NUMBER >= nParts)
1354 {
1355 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lParam);
1356 }
1357
1358 HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts + 1));
1359 LPINT lpParts = (LPINT)LocalLock(hLocal);
1360 memcpy(lpParts, (void*)lParam, wParam*sizeof(int));
1361
1362 for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++)
1363 {
1364 lpParts[i] -= pClass->m_nPaneWidth;
1365 }
1366 LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, w Param, (LPARAM)lpParts);
1367
1368 AdblockPlus::Rectangle rcPane;
1369 ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane);
1370
1371 AdblockPlus::Rectangle rcClient;
1372 ::GetClientRect(hWnd, &rcClient);
1373
1374 ::MoveWindow(
1375 pClass->m_hPaneWnd,
1376 lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth,
1377 0,
1378 pClass->m_nPaneWidth,
1379 rcClient.Height(),
1380 TRUE);
1381
1382 ::LocalFree(hLocal);
1383 return hRet;
1384 }
1385
1386 default:
1322 break; 1387 break;
1323 } 1388 }
1324 1389 }
1325 case WM_SYSCOLORCHANGE: 1390 catch (...)
1326 { 1391 {
1327 pClass->UpdateTheme(); 1392 // Suppress exception. Fall through to default handler.
1328 break; 1393 DEBUG_GENERAL(L"CPluginClass::NewStatusProc - exception");
1329 } 1394 }
1330 1395 return ::CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lPara m);
1331 case SB_SETPARTS: 1396 }
1332 { 1397
1333 if (!lParam || !wParam || wParam > 30 || !IsWindow(pClass->m_hPaneWnd)) 1398
1334 { 1399 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url)
1335 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, l Param);
1336 }
1337
1338 WPARAM nParts = wParam;
1339 if (STATUSBAR_PANE_NUMBER >= nParts)
1340 {
1341 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, l Param);
1342 }
1343
1344 HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts+1));
1345 LPINT lpParts = (LPINT)LocalLock(hLocal);
1346 memcpy(lpParts, (void*)lParam, wParam*sizeof(int));
1347
1348 for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++)
1349 {
1350 lpParts[i] -= pClass->m_nPaneWidth;
1351 }
1352 LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wPa ram, (LPARAM)lpParts);
1353
1354 AdblockPlus::Rectangle rcPane;
1355 ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane);
1356
1357 AdblockPlus::Rectangle rcClient;
1358 ::GetClientRect(hWnd, &rcClient);
1359
1360 ::MoveWindow(
1361 pClass->m_hPaneWnd,
1362 lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth,
1363 0,
1364 pClass->m_nPaneWidth,
1365 rcClient.Height(),
1366 TRUE);
1367
1368 ::LocalFree(hLocal);
1369
1370
1371 return hRet;
1372 }
1373
1374 default:
1375 break;
1376 }
1377
1378 LRESULT result = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wPara m, lParam);
1379
1380
1381 return result;
1382
1383 }
1384
1385
1386 HICON CPluginClass::GetStatusBarIcon(const CString& url)
1387 { 1400 {
1388 // use the disable icon as defualt, if the client doesn't exists 1401 // use the disable icon as defualt, if the client doesn't exists
1389 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); 1402 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED);
1390 1403
1391 CPluginTab* tab = GetTab(::GetCurrentThreadId()); 1404 CPluginTab* tab = GetTab(::GetCurrentThreadId());
1392 if (tab) 1405 if (tab)
1393 { 1406 {
1394 CPluginClient* client = CPluginClient::GetInstance(); 1407 CPluginClient* client = CPluginClient::GetInstance();
1395 if (!CPluginSettings::GetInstance()->IsPluginEnabled()) 1408 if (CPluginSettings::GetInstance()->IsPluginEnabled())
1396 { 1409 {
1397 } 1410 if (client->IsWhitelistedUrl(url))
1398 else if (client->IsWhitelistedUrl(to_wstring(url))) 1411 {
1399 { 1412 hIcon = GetIcon(ICON_PLUGIN_DISABLED);
1400 hIcon = GetIcon(ICON_PLUGIN_DISABLED); 1413 }
1401 } 1414 else
1402 else 1415 {
1403 { 1416 CPluginSettings* settings = CPluginSettings::GetInstance();
1404 CPluginSettings* settings = CPluginSettings::GetInstance(); 1417 hIcon = GetIcon(ICON_PLUGIN_ENABLED);
1405 hIcon = GetIcon(ICON_PLUGIN_ENABLED); 1418 }
1406 } 1419 }
1407 } 1420 }
1408 return hIcon; 1421 return hIcon;
1409 } 1422 }
1410 1423
1411 1424 // Entry point
1412 LRESULT CALLBACK CPluginClass::PaneWindowProc(HWND hWnd, UINT message, WPARAM wP aram, LPARAM lParam) 1425 LRESULT CALLBACK CPluginClass::PaneWindowProc(HWND hWnd, UINT message, WPARAM wP aram, LPARAM lParam)
1413 { 1426 {
1414 // Find tab 1427 try
1415 CPluginClass *pClass = FindInstance(GetParent(hWnd)); 1428 {
1416 if (!pClass) 1429 // Find tab
1417 { 1430 CPluginClass *pClass = FindInstance(GetParent(hWnd));
1418 return ::DefWindowProc(hWnd, message, wParam, lParam); 1431 if (!pClass)
1419 } 1432 {
1420 1433 return ::DefWindowProc(hWnd, message, wParam, lParam);
1421 // Process message 1434 }
1422 switch (message) 1435
1423 { 1436 // Process message
1424 1437 switch (message)
1425 case WM_SETCURSOR: 1438 {
1426 { 1439 case WM_SETCURSOR:
1427 ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); 1440 {
1428 return TRUE; 1441 ::SetCursor(::LoadCursor(NULL, IDC_ARROW));
1429 } 1442 return TRUE;
1430 case WM_PAINT: 1443 }
1431 { 1444 case WM_PAINT:
1432 PAINTSTRUCT ps; 1445 {
1433 HDC hDC = ::BeginPaint(hWnd, &ps); 1446 PAINTSTRUCT ps;
1434 1447 HDC hDC = ::BeginPaint(hWnd, &ps);
1435 AdblockPlus::Rectangle rcClient; 1448
1436 ::GetClientRect(hWnd, &rcClient); 1449 AdblockPlus::Rectangle rcClient;
1437 1450 ::GetClientRect(hWnd, &rcClient);
1438 int nDrawEdge = 0; 1451
1439 1452 int nDrawEdge = 0;
1440 // Old Windows background drawing 1453
1441 if (pClass->m_hTheme == NULL) 1454 // Old Windows background drawing
1442 { 1455 if (pClass->m_hTheme == NULL)
1443 ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); 1456 {
1444 ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT); 1457 ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1));
1445 1458 ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT);
1446 nDrawEdge = 3; 1459
1447 rcClient.left += 3; 1460 nDrawEdge = 3;
1448 1461 rcClient.left += 3;
1449 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); 1462
1450 } 1463 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT);
1451 // Themed background drawing 1464 }
1452 else 1465 // Themed background drawing
1453 { 1466 else
1454 // Draw background 1467 {
1455 if (pfnDrawThemeBackground) 1468 // Draw background
1456 { 1469 if (pfnDrawThemeBackground)
1457 AdblockPlus::Rectangle rc = rcClient;
1458 rc.right -= 2;
1459 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL);
1460 }
1461
1462 // Copy separator picture to left side
1463 int nHeight = rcClient.Height();
1464 int nWidth = rcClient.Width() - 2;
1465
1466 for (int i = 0; i < 2; i++)
1467 {
1468 for (int j = 0; j < nHeight; j++)
1469 { 1470 {
1470 COLORREF clr = ::GetPixel(hDC, i + nWidth, j); 1471 AdblockPlus::Rectangle rc = rcClient;
1471 1472 rc.right -= 2;
1472 // Ignore black boxes (if source is obscured by other windows) 1473 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL);
1473 if (clr != -1 && (GetRValue(clr) > 8 || GetGValue(clr) > 8 || GetBVa lue(clr) > 8)) 1474 }
1475
1476 // Copy separator picture to left side
1477 int nHeight = rcClient.Height();
1478 int nWidth = rcClient.Width() - 2;
1479
1480 for (int i = 0; i < 2; i++)
1481 {
1482 for (int j = 0; j < nHeight; j++)
1474 { 1483 {
1475 ::SetPixel(hDC, i, j, clr); 1484 COLORREF clr = ::GetPixel(hDC, i + nWidth, j);
1476 } 1485
1477 } 1486 // Ignore black boxes (if source is obscured by other windows)
1478 } 1487 if (clr != -1 && (GetRValue(clr) > 8 || GetGValue(clr) > 8 || GetB Value(clr) > 8))
1479 }
1480
1481 // Draw icon
1482 if (CPluginClient::GetInstance())
1483 {
1484 HICON hIcon = GetStatusBarIcon(pClass->GetTab()->GetDocumentUrl());
1485
1486 int offx = (rcClient.Height() - 16)/2 + nDrawEdge;
1487 if (hIcon)
1488 {
1489 ::DrawIconEx(hDC, offx, (rcClient.Height() - 16)/2 + 2, hIcon, 16, 16, NULL, NULL, DI_NORMAL);
1490 offx += 22;
1491 }
1492 #ifdef _DEBUG
1493 // Display version
1494 HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT, 0, 0);
1495 HGDIOBJ hOldFont = ::SelectObject(hDC,hFont);
1496
1497 AdblockPlus::Rectangle rcText = rcClient;
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 CString strURL = pClass->GetBrowserUrl();
1516 if (strURL != pClass->GetTab()->GetDocumentUrl())
1517 {
1518 pClass->GetTab()->SetDocumentUrl(strURL);
1519 }
1520
1521 // Create menu
1522 HMENU hMenu = pClass->CreatePluginMenu(strURL);
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 {
1554 tab->OnActivate();
1555 RECT rect;
1556 GetWindowRect(pClass->m_hPaneWnd, &rect);
1557 pClass->notificationMessage.Move(rect.left + (rect.right - rect.left) / 2, rect.top + (rect.bottom - rect.top) / 2);
1558 }
1559 if (LOWORD(wParam) == UIS_CLEAR)
1560 {
1561 pClass->notificationMessage.Hide();
1562 }
1563 }
1564 break;
1565 case WM_WINDOWPOSCHANGING:
1566 {
1567 RECT rect;
1568 GetWindowRect(pClass->m_hPaneWnd, &rect);
1569 if (pClass->notificationMessage.IsVisible())
1570 {
1571 pClass->notificationMessage.Move(rect.left + (rect.right - rect.left) / 2, rect.top + (rect.bottom - rect.top) / 2);
1572 }
1573 }
1574 break;
1575 case WM_WINDOWPOSCHANGED:
1576 {
1577 WINDOWPOS* wndPos = reinterpret_cast<WINDOWPOS*>(lParam);
1578 if (wndPos->flags & SWP_HIDEWINDOW)
1579 {
1580 pClass->notificationMessage.Hide();
1581 }
1582 }
1583 break;
1584 case WM_ALREADY_UP_TO_DATE:
1585 {
1586 Dictionary* dictionary = Dictionary::GetInstance();
1587 std::wstring upToDateText = dictionary->Lookup("updater", "update-already- up-to-date-text");
1588 std::wstring upToDateTitle = dictionary->Lookup("updater", "update-already -up-to-date-title");
1589 pClass->notificationMessage.SetTextAndIcon(upToDateText, upToDateTitle, TT I_INFO);
1590 }
1591 break;
1592 case WM_UPDATE_CHECK_ERROR:
1593 {
1594 Dictionary* dictionary = Dictionary::GetInstance();
1595 std::wstring errorText = dictionary->Lookup("updater", "update-error-text" );
1596 std::wstring errorTitle = dictionary->Lookup("updater", "update-error-titl e");
1597 pClass->notificationMessage.SetTextAndIcon(errorText, errorText, TTI_ERROR );
1598 }
1599 break;
1600 case WM_DOWNLOADING_UPDATE:
1601 {
1602 Dictionary* dictionary = Dictionary::GetInstance();
1603 std::wstring downloadingText = dictionary->Lookup("updater", "downloading- update-text");
1604 std::wstring downloadingTitle = dictionary->Lookup("updater", "downloading -update-title");
1605 pClass->notificationMessage.SetTextAndIcon(downloadingText, downloadingTit le, TTI_INFO);
1606 }
1607 break;
1608 }
1609
1610 return DefWindowProc(hWnd, message, wParam, lParam);
1611 }
1612
1613
1614 void CPluginClass::UpdateStatusBar()
1615 {
1616 DEBUG_GENERAL("*** Updating statusbar")
1617 if (m_hPaneWnd == NULL)
1618 {
1619 CreateStatusBarPane();
1620 }
1621 if ((m_hPaneWnd != NULL) && !::InvalidateRect(m_hPaneWnd, NULL, FALSE))
1622 {
1623 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_INVALID ATE_STATUSBAR, "Class::Invalidate statusbar");
1624 }
1625 }
1626
1627
1628 void STDMETHODCALLTYPE CPluginClass::Unadvice()
1629 {
1630 s_criticalSectionLocal.Lock();
1631 {
1632 if (m_isAdviced)
1633 {
1634 HRESULT hr = DispEventUnadvise(GetBrowser());
1635 if (FAILED(hr))
1636 {
1637 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_UNADVIC E, "Class::Unadvice - Unadvise");
1638 }
1639 m_isAdviced = false;
1640 }
1641 }
1642 s_criticalSectionLocal.Unlock();
1643 }
1644
1645 HICON CPluginClass::GetIcon(int type)
1646 {
1647 HICON icon = NULL;
1648
1649 s_criticalSectionLocal.Lock();
1650 {
1651 if (!s_hIcons[type])
1652 {
1653 s_hIcons[type] = ::LoadIcon(_Module.m_hInst, MAKEINTRESOURCE(s_hIconTypes[ type]));
1654 if (!s_hIcons[type])
1655 {
1656 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_LOAD_ ICON, "Class::GetIcon - LoadIcon")
1657 }
1658 }
1659
1660 icon = s_hIcons[type];
1661 }
1662 s_criticalSectionLocal.Unlock();
1663
1664 return icon;
1665 }
1666
1667 ATOM CPluginClass::GetAtomPaneClass()
1668 {
1669 return s_atomPaneClass;
1670 }
1671
1672 HWND CPluginClass::GetTabHWND() const
1673 {
1674 std::array<wchar_t, MAX_PATH> className;
1675 // Get browser window and url
1676 HWND hBrowserWnd = GetBrowserHWND();
1677 if (!hBrowserWnd)
1678 {
1679 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_BROWSER, "C lass::GetTabWindow - No tab window")
1680 s_criticalSectionWindow.Unlock();
1681
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 { 1488 {
1716 bExistingTab = true; 1489 ::SetPixel(hDC, i, j, clr);
1717 break;
1718 } 1490 }
1719 } 1491 }
1720 } 1492 }
1721 1493 }
1722 if (!bExistingTab) 1494
1495 // Draw icon
1496 if (CPluginClient::GetInstance())
1497 {
1498 HICON hIcon = GetStatusBarIcon(pClass->GetTab()->GetDocumentUrl());
1499
1500 int offx = nDrawEdge;
1501 if (hIcon)
1723 { 1502 {
1724 hBrowserWnd = hTabWnd2; 1503 //Get the RECT for the leftmost pane (the status text pane)
1725 hTabWnd = hTabWnd2; 1504 RECT rect;
1726 s_criticalSectionLocal.Unlock(); 1505 BOOL rectRes = ::SendMessage(pClass->m_hStatusBarWnd, SB_GETRECT, 0, (LPARAM)&rect);
1727 break; 1506 ::DrawIconEx(hDC, 0, rect.bottom - rect.top - iconHeight, hIcon, ico nWidth, iconHeight, NULL, NULL, DI_NORMAL);
1507 offx += iconWidth;
1728 } 1508 }
1729 s_criticalSectionLocal.Unlock(); 1509 #ifdef _DEBUG
1730 1510 // Display version
1731 } 1511 HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT , 0, 0);
1732 } 1512 HGDIOBJ hOldFont = ::SelectObject(hDC, hFont);
1733 } 1513
1734 1514 AdblockPlus::Rectangle rcText = rcClient;
1735 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); 1515 rcText.left += offx;
1736 } 1516 ::SetBkMode(hDC, TRANSPARENT);
1737 1517 ::DrawTextW(hDC, IEPLUGIN_VERSION, -1, &rcText, DT_WORD_ELLIPSIS | DT_ LEFT | DT_SINGLELINE | DT_VCENTER);
1738 return hTabWnd; 1518
1739 1519 ::SelectObject(hDC, hOldFont);
1740 } 1520 #endif // _DEBUG
1521 }
1522
1523 // Done!
1524 EndPaint(hWnd, &ps);
1525
1526 return 0;
1527 }
1528
1529 case WM_LBUTTONUP:
1530 case WM_RBUTTONUP:
1531 {
1532 std::wstring url = pClass->GetBrowserUrl();
1533 if (url != pClass->GetTab()->GetDocumentUrl())
1534 {
1535 pClass->GetTab()->SetDocumentUrl(url);
1536 }
1537
1538 // Create menu
1539 HMENU hMenu = pClass->CreatePluginMenu(url);
1540 if (!hMenu)
1541 {
1542 return 0;
1543 }
1544
1545 // Display menu
1546 POINT pt;
1547 ::GetCursorPos(&pt);
1548
1549 RECT rc;
1550 ::GetWindowRect(hWnd, &rc);
1551
1552 if (rc.left >= 0 && rc.top >= 0)
1553 {
1554 pt.x = rc.left;
1555 pt.y = rc.top;
1556 }
1557
1558 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN | TPM_BOTTOMALIGN );
1559 break;
1560 }
1561 case WM_DESTROY:
1562 break;
1563 case SC_CLOSE:
1564 break;
1565
1566 case WM_UPDATEUISTATE:
1567 {
1568 CPluginTab* tab = GetTab(::GetCurrentThreadId());
1569 if (tab)
1570 {
1571 tab->OnActivate();
1572 RECT rect;
1573 GetWindowRect(pClass->m_hPaneWnd, &rect);
1574 pClass->notificationMessage.MoveToCenter(rect);
1575 }
1576 if (LOWORD(wParam) == UIS_CLEAR)
1577 {
1578 pClass->notificationMessage.Hide();
1579 }
1580 break;
1581 }
1582 case WM_WINDOWPOSCHANGING:
1583 {
1584 RECT rect;
1585 GetWindowRect(pClass->m_hPaneWnd, &rect);
1586 if (pClass->notificationMessage.IsVisible())
1587 {
1588 pClass->notificationMessage.MoveToCenter(rect);
1589 }
1590 break;
1591 }
1592 case WM_WINDOWPOSCHANGED:
1593 {
1594 WINDOWPOS* wndPos = reinterpret_cast<WINDOWPOS*>(lParam);
1595 if (wndPos->flags & SWP_HIDEWINDOW)
1596 {
1597 pClass->notificationMessage.Hide();
1598 }
1599 break;
1600 }
1601 case WM_ALREADY_UP_TO_DATE:
1602 {
1603 Dictionary* dictionary = Dictionary::GetInstance();
1604 std::wstring upToDateText = dictionary->Lookup("updater", "update-alread y-up-to-date-text");
1605 std::wstring upToDateTitle = dictionary->Lookup("updater", "update-alrea dy-up-to-date-title");
1606 pClass->notificationMessage.SetTextAndIcon(upToDateText, upToDateTitle, TTI_INFO);
1607 break;
1608 }
1609 case WM_UPDATE_CHECK_ERROR:
1610 {
1611 Dictionary* dictionary = Dictionary::GetInstance();
1612 std::wstring errorText = dictionary->Lookup("updater", "update-error-tex t");
1613 std::wstring errorTitle = dictionary->Lookup("updater", "update-error-ti tle");
1614 pClass->notificationMessage.SetTextAndIcon(errorText, errorTitle, TTI_ER ROR);
1615 break;
1616 }
1617 case WM_DOWNLOADING_UPDATE:
1618 {
1619 Dictionary* dictionary = Dictionary::GetInstance();
1620 std::wstring downloadingText = dictionary->Lookup("updater", "downloadin g-update-text");
1621 std::wstring downloadingTitle = dictionary->Lookup("updater", "downloadi ng-update-title");
1622 pClass->notificationMessage.SetTextAndIcon(downloadingText, downloadingT itle, TTI_INFO);
1623 break;
1624 }
1625 }
1626 }
1627 catch (...)
1628 {
1629 // Suppress exception. Fall through to default handler.
1630 DEBUG_GENERAL(L"CPluginClass::PaneWindowProc - exception");
1631 }
1632 return ::DefWindowProc(hWnd, message, wParam, lParam);
1633 }
1634
1635
1636 void CPluginClass::UpdateStatusBar()
1637 {
1638 DEBUG_GENERAL("*** Updating statusbar")
1639 if (m_hPaneWnd == NULL)
1640 {
1641 CreateStatusBarPane();
1642 }
1643 if ((m_hPaneWnd != NULL) && !::InvalidateRect(m_hPaneWnd, NULL, FALSE))
1644 {
1645 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_INVALID ATE_STATUSBAR, "Class::Invalidate statusbar");
1646 }
1647 }
1648
1649 void CPluginClass::Unadvise()
1650 {
1651 if (!m_data->webBrowser2)
1652 {
1653 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::Unadvise - Reached with webBrowser2 == nullptr");
1654 return;
1655 }
1656 s_criticalSectionLocal.Lock();
1657 {
1658 if (m_isAdvised)
1659 {
1660 HRESULT hr = DispEventUnadvise(m_data->webBrowser2);
1661 if (FAILED(hr))
1662 {
1663 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_UNADVIS E, "Class::Unadvise - Unadvise");
1664 }
1665 m_isAdvised = false;
1666 }
1667 }
1668 s_criticalSectionLocal.Unlock();
1669 }
1670
1671 void CPluginClass::EnsureWebBrowserConnected(const ATL::CComPtr<IWebBrowser2>& w ebBrowser)
1672 {
1673 auto it = m_data->connectedWebBrowsersCache.find(webBrowser);
1674 if (it != m_data->connectedWebBrowsersCache.end())
1675 {
1676 return;
1677 }
1678 ATL::CComObject<WebBrowserEventsListener>* listenerImpl = nullptr;
1679 if (FAILED(ATL::CComObject<WebBrowserEventsListener>::CreateInstance(&listener Impl)))
1680 {
1681 return;
1682 }
1683 ATL::CComPtr<IUnknown> listenerRefCounterGuard(listenerImpl->GetUnknown());
1684 std::weak_ptr<Data> dataForCapturing = m_data;
1685 auto onListenerDestroy = [webBrowser, dataForCapturing]
1686 {
1687 if (auto data = dataForCapturing.lock())
1688 {
1689 data->connectedWebBrowsersCache.erase(webBrowser);
1690 }
1691 };
1692 auto onReloaded = [webBrowser, dataForCapturing]
1693 {
1694 if (auto data = dataForCapturing.lock())
1695 {
1696 auto frameSrc = GetLocationUrl(*webBrowser);
1697 data->tab->OnDocumentComplete(webBrowser, frameSrc, data->webBrowser2.IsEq ualObject(webBrowser));
1698 }
1699 };
1700 if (FAILED(listenerImpl->Init(webBrowser, onListenerDestroy, onReloaded)))
1701 {
1702 return;
1703 }
1704 m_data->connectedWebBrowsersCache.emplace(webBrowser, listenerImpl);
1705 }
1706
1707 HICON CPluginClass::GetIcon(int type)
1708 {
1709 HICON icon = NULL;
1710
1711 s_criticalSectionLocal.Lock();
1712 {
1713 if (!s_hIcons[type])
1714 {
1715 std::wstring imageToLoad = L"#";
1716 imageToLoad += std::to_wstring(s_hIconTypes[type]);
1717 s_hIcons[type] = (HICON)::LoadImage(_Module.m_hInst, imageToLoad.c_str(), IMAGE_ICON, iconWidth, iconHeight, LR_SHARED);
1718 if (!s_hIcons[type])
1719 {
1720 DEBUG_ERROR_LOG(::GetLastError(), PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_LOAD_ ICON, "Class::GetIcon - LoadIcon");
1721 }
1722 }
1723
1724 icon = s_hIcons[type];
1725 }
1726 s_criticalSectionLocal.Unlock();
1727
1728 return icon;
1729 }
1730
1731 ATOM CPluginClass::GetAtomPaneClass()
1732 {
1733 return s_atomPaneClass;
1734 }
1735
LEFTRIGHT

Powered by Google App Engine
This is Rietveld