LEFT | RIGHT |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2016 Eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 #include "PluginStdAfx.h" | 18 #include "PluginStdAfx.h" |
19 | 19 |
20 #include "PluginClass.h" | 20 #include "PluginClass.h" |
21 #include "PluginSettings.h" | 21 #include "PluginSettings.h" |
22 #include "PluginSystem.h" | 22 #include "PluginSystem.h" |
23 #include "PluginFilter.h" | 23 #include "PluginFilter.h" |
24 #include "PluginMimeFilterClient.h" | 24 #include "PluginMimeFilterClient.h" |
25 #include "AdblockPlusClient.h" | 25 #include "AdblockPlusClient.h" |
26 #include "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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } | |
LEFT | RIGHT |