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 } | 213 } |
191 } | 214 } |
192 else | 215 else |
| 216 { |
| 217 DEBUG_GENERAL(L"CPluginClass::GetBrowserUrl - Reached with m_webBrowser2 ==
nullptr (probable invariant violation)"); |
| 218 } |
| 219 if (url.empty()) |
193 { | 220 { |
194 url = m_tab->GetDocumentUrl(); | 221 url = m_tab->GetDocumentUrl(); |
195 } | 222 } |
196 return url; | 223 return url; |
197 } | 224 } |
198 | 225 |
199 DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr) | 226 DWORD WINAPI CPluginClass::StartInitObject(LPVOID thisPtr) |
200 { | 227 { |
201 if (thisPtr == NULL) | 228 if (thisPtr == NULL) |
202 return 0; | 229 return 0; |
(...skipping 14 matching lines...) Expand all Loading... |
217 * '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 |
218 * 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, |
219 * but it is not a proper substitute for one. | 246 * but it is not a proper substitute for one. |
220 */ | 247 */ |
221 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) | 248 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) |
222 { | 249 { |
223 try | 250 try |
224 { | 251 { |
225 if (unknownSite) | 252 if (unknownSite) |
226 { | 253 { |
227 | 254 DEBUG_GENERAL(L"==========================================================
======================\nNEW TAB UI\n============================================
===================================="); |
228 DEBUG_GENERAL(L"==========================================================
======================\nNEW TAB UI\n============================================
====================================") | |
229 | 255 |
230 HRESULT hr = ::CoInitialize(NULL); | 256 HRESULT hr = ::CoInitialize(NULL); |
231 if (FAILED(hr)) | 257 if (FAILED(hr)) |
232 { | 258 { |
233 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"); |
234 } | 260 } |
235 | 261 |
236 s_criticalSectionBrowser.Lock(); | 262 /* |
237 { | 263 * We were instantiated as a BHO, so our site is always of type IWebBrowse
r2. |
238 m_webBrowser2 = unknownSite; | 264 */ |
239 } | 265 m_webBrowser2 = ATL::CComQIPtr<IWebBrowser2>(unknownSite); |
240 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 } |
241 | 285 |
242 //register the mimefilter | 286 //register the mimefilter |
243 //and only mimefilter | 287 //and only mimefilter |
244 //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 |
245 | |
246 s_criticalSectionLocal.Lock(); | 289 s_criticalSectionLocal.Lock(); |
247 { | 290 { |
248 // 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 |
249 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); | 292 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
250 s_asyncWebBrowser2 = unknownSite; | 293 s_asyncWebBrowser2 = unknownSite; |
251 s_instances.insert(this); | 294 s_instances.insert(this); |
252 } | 295 } |
253 s_criticalSectionLocal.Unlock(); | 296 s_criticalSectionLocal.Unlock(); |
254 | 297 |
255 try | 298 try |
256 { | 299 { |
257 auto webBrowser = GetBrowser(); | 300 HRESULT hr = DispEventAdvise(m_webBrowser2); |
258 if (webBrowser) | 301 if (SUCCEEDED(hr)) |
259 { | 302 { |
260 DEBUG_GENERAL("Loaded as BHO"); | 303 m_isAdvised = true; |
261 HRESULT hr = DispEventAdvise(webBrowser); | 304 try |
262 if (SUCCEEDED(hr)) | |
263 { | 305 { |
264 m_isAdvised = true; | 306 std::thread startInitObjectThread(StartInitObject, this); |
265 try | 307 startInitObjectThread.detach(); // TODO: but actually we should wait
for the thread in the dtr. |
266 { | |
267 std::thread startInitObjectThread(StartInitObject, this); | |
268 startInitObjectThread.detach(); // TODO: but actually we should wa
it for the thread in the dtr. | |
269 } | |
270 catch (const std::system_error& ex) | |
271 { | |
272 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_
THREAD_CREATE_PROCESS, | |
273 "Class::Thread - Failed to create StartInitObject thread"); | |
274 } | |
275 } | 308 } |
276 else | 309 catch (const std::system_error& ex) |
277 { | 310 { |
278 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"); |
279 } | 313 } |
| 314 } |
| 315 else |
| 316 { |
| 317 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVIC
E, "Class::SetSite - Advise"); |
280 } | 318 } |
281 } | 319 } |
282 catch (const std::runtime_error& ex) | 320 catch (const std::runtime_error& ex) |
283 { | 321 { |
284 DEBUG_EXCEPTION(ex); | 322 DEBUG_EXCEPTION(ex); |
285 Unadvise(); | 323 Unadvise(); |
286 } | 324 } |
287 } | 325 } |
288 else | 326 else |
289 { | 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 |
290 Unadvise(); | 336 Unadvise(); |
291 | 337 |
292 // Destroy window | 338 // Destroy window |
293 if (m_pWndProcStatus) | 339 if (m_pWndProcStatus) |
294 { | 340 { |
295 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWn
dProcStatus); | 341 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWn
dProcStatus); |
296 | 342 |
297 m_pWndProcStatus = NULL; | 343 m_pWndProcStatus = NULL; |
298 } | 344 } |
299 | 345 |
300 if (m_hPaneWnd) | 346 if (m_hPaneWnd) |
301 { | 347 { |
302 DestroyWindow(m_hPaneWnd); | 348 DestroyWindow(m_hPaneWnd); |
303 m_hPaneWnd = NULL; | 349 m_hPaneWnd = NULL; |
304 } | 350 } |
305 | 351 |
306 m_hTabWnd = NULL; | 352 m_hTabWnd = NULL; |
307 m_hStatusBarWnd = NULL; | 353 m_hStatusBarWnd = NULL; |
308 | 354 |
309 // Remove instance from the list, shutdown threads | 355 // Remove instance from the list, shutdown threads |
310 HANDLE hMainThread = NULL; | 356 HANDLE hMainThread = NULL; |
311 HANDLE hTabThread = NULL; | 357 HANDLE hTabThread = NULL; |
312 | 358 |
| 359 if (!threadMap.RemoveAndCheck()) |
| 360 { |
| 361 throw std::logic_error("CPluginClass::SetSite - Missing entry in thread
map"); |
| 362 } |
| 363 |
313 s_criticalSectionLocal.Lock(); | 364 s_criticalSectionLocal.Lock(); |
314 { | 365 { |
315 s_instances.erase(this); | 366 s_instances.erase(this); |
316 | |
317 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::Ge
tCurrentThreadId()); | |
318 if (it != s_threadInstances.end()) | |
319 { | |
320 s_threadInstances.erase(it); | |
321 } | |
322 if (s_instances.empty()) | 367 if (s_instances.empty()) |
323 { | 368 { |
324 // 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 |
325 CPluginClientFactory::ReleaseMimeFilterClientInstance(); | 370 CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
326 } | 371 } |
327 } | 372 } |
328 s_criticalSectionLocal.Unlock(); | 373 s_criticalSectionLocal.Unlock(); |
329 | 374 |
330 // Release browser interface | 375 m_webBrowser2 = nullptr; |
331 s_criticalSectionBrowser.Lock(); | |
332 { | |
333 m_webBrowser2.Release(); | |
334 } | |
335 s_criticalSectionBrowser.Unlock(); | |
336 | 376 |
337 DEBUG_GENERAL("===========================================================
=====================\nNEW TAB UI - END\n=======================================
=========================================") | 377 DEBUG_GENERAL("===========================================================
=====================\nNEW TAB UI - END\n=======================================
=========================================") |
338 | 378 |
339 ::CoUninitialize(); | 379 ::CoUninitialize(); |
340 } | 380 } |
341 | 381 |
342 IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite); | |
343 } | 382 } |
344 catch (...) | 383 catch (...) |
345 { | 384 { |
346 } | 385 } |
| 386 IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite); |
347 return S_OK; | 387 return S_OK; |
348 } | 388 } |
349 | 389 |
350 bool CPluginClass::IsStatusBarEnabled() | 390 bool CPluginClass::IsStatusBarEnabled() |
351 { | 391 { |
352 DEBUG_GENERAL("IsStatusBarEnabled start"); | 392 DEBUG_GENERAL("IsStatusBarEnabled start"); |
353 HKEY pHkey; | 393 HKEY pHkey; |
354 HKEY pHkeySub; | 394 HKEY pHkeySub; |
355 RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey); | 395 RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey); |
356 DWORD truth = 1; | 396 DWORD truth = 1; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 { | 514 { |
475 ATL::CComQIPtr<IWebBrowser2> webBrowser = frameBrowserDisp; | 515 ATL::CComQIPtr<IWebBrowser2> webBrowser = frameBrowserDisp; |
476 if (!webBrowser) | 516 if (!webBrowser) |
477 { | 517 { |
478 return; | 518 return; |
479 } | 519 } |
480 if (!urlVariant || urlVariant->vt != VT_BSTR) | 520 if (!urlVariant || urlVariant->vt != VT_BSTR) |
481 { | 521 { |
482 return; | 522 return; |
483 } | 523 } |
484 std::wstring url(urlVariant->bstrVal, SysStringLen(urlVariant->bstrVal)); | 524 std::wstring url = ToWstring(urlVariant->bstrVal); |
485 | 525 |
486 // 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 |
487 // navigating new page | 527 // navigating new page |
488 CPluginClient* client = CPluginClient::GetInstance(); | 528 CPluginClient* client = CPluginClient::GetInstance(); |
489 if (url.find(L"javascript") == 0) | 529 if (url.find(L"javascript") == 0) |
490 { | 530 { |
491 } | 531 } |
492 else if (GetBrowser().IsEqualObject(webBrowser)) | 532 else if (IsRootBrowser(webBrowser)) |
493 { | 533 { |
494 m_tab->OnNavigate(url); | 534 m_tab->OnNavigate(url); |
495 DEBUG_GENERAL( | 535 DEBUG_GENERAL( |
496 L"========================================================================
========\n" | 536 L"========================================================================
========\n" |
497 L"Begin main navigation url:" + url + L"\n" | 537 L"Begin main navigation url:" + url + L"\n" |
498 L"========================================================================
========") | 538 L"========================================================================
========") |
499 | 539 |
500 #ifdef ENABLE_DEBUG_RESULT | 540 #ifdef ENABLE_DEBUG_RESULT |
501 CPluginDebug::DebugResultDomain(url); | 541 CPluginDebug::DebugResultDomain(url); |
502 #endif | 542 #endif |
503 UpdateStatusBar(); | 543 UpdateStatusBar(); |
504 } | 544 } |
505 else | 545 else |
506 { | 546 { |
507 DEBUG_NAVI(L"Navi::Begin navigation url:" + url) | 547 DEBUG_NAVI(L"Navi::Begin navigation url:" + url) |
508 m_tab->CacheFrame(url); | 548 m_tab->CacheFrame(url); |
509 } | 549 } |
510 } | 550 } |
511 catch (...) | 551 catch (...) |
512 { | 552 { |
513 } | 553 } |
514 } | 554 } |
515 | 555 |
516 // Entry point | 556 // Entry point |
517 void STDMETHODCALLTYPE CPluginClass::OnDownloadComplete() | 557 void STDMETHODCALLTYPE CPluginClass::OnDownloadComplete() |
518 { | 558 { |
519 try | 559 try |
520 { | 560 { |
| 561 if (!m_webBrowser2) |
| 562 { |
| 563 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::OnDownloadComplete - Reached with
m_webBrowser2 == nullptr"); |
| 564 return; |
| 565 } |
521 DEBUG_NAVI(L"Navi::Download Complete") | 566 DEBUG_NAVI(L"Navi::Download Complete") |
522 ATL::CComPtr<IWebBrowser2> browser = GetBrowser(); | 567 m_tab->OnDownloadComplete(m_webBrowser2); |
523 if (browser) | |
524 { | |
525 m_tab->OnDownloadComplete(browser); | |
526 } | |
527 } | 568 } |
528 catch (...) | 569 catch (...) |
529 { | 570 { |
530 } | 571 } |
531 } | 572 } |
532 | 573 |
533 // Entry point | 574 // Entry point |
534 void STDMETHODCALLTYPE CPluginClass::OnDocumentComplete(IDispatch* frameBrowserD
isp, VARIANT* /*urlOrPidl*/) | 575 void STDMETHODCALLTYPE CPluginClass::OnDocumentComplete(IDispatch* frameBrowserD
isp, VARIANT* /*urlOrPidl*/) |
535 { | 576 { |
536 try | 577 try |
537 { | 578 { |
538 DEBUG_NAVI(L"Navi::Document Complete"); | 579 DEBUG_NAVI(L"Navi::Document Complete"); |
539 ATL::CComQIPtr<IWebBrowser2> webBrowser2 = frameBrowserDisp; | 580 ATL::CComQIPtr<IWebBrowser2> webBrowser2 = frameBrowserDisp; |
540 if (!webBrowser2) | 581 if (!webBrowser2) |
541 { | 582 { |
542 return; | 583 return; |
543 } | 584 } |
544 std::wstring frameSrc = GetLocationUrl(*webBrowser2); | 585 std::wstring frameSrc = GetLocationUrl(*webBrowser2); |
545 bool isRootPageBrowser = GetBrowser().IsEqualObject(webBrowser2); | 586 m_tab->OnDocumentComplete(webBrowser2, frameSrc, IsRootBrowser(webBrowser2))
; |
546 m_tab->OnDocumentComplete(webBrowser2, frameSrc, isRootPageBrowser); | |
547 } | 587 } |
548 catch (...) | 588 catch (...) |
549 { | 589 { |
550 } | 590 } |
551 } | 591 } |
552 | 592 |
553 // Entry point | 593 // Entry point |
554 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u
nsigned long validFlagsMask) | 594 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u
nsigned long validFlagsMask) |
555 { | 595 { |
556 try | 596 try |
557 { | 597 { |
558 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); | 598 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); |
559 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL
ECMDIDF_WINDOWSTATE_ENABLED) | 599 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL
ECMDIDF_WINDOWSTATE_ENABLED) |
560 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA
BLED); | 600 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA
BLED); |
561 if (newtabshown) | 601 if (newtabshown) |
562 { | 602 { |
563 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(
GetCurrentThreadId()); | 603 if (!m_isInitializedOk) |
564 if (it == s_threadInstances.end()) | 604 { |
565 { | 605 m_isInitializedOk = true; |
566 s_threadInstances[::GetCurrentThreadId()] = this; | 606 InitObject(); |
567 if (!m_isInitializedOk) | 607 UpdateStatusBar(); |
568 { | |
569 m_isInitializedOk = true; | |
570 InitObject(); | |
571 UpdateStatusBar(); | |
572 } | |
573 } | 608 } |
574 } | 609 } |
575 notificationMessage.Hide(); | 610 notificationMessage.Hide(); |
576 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end"); | 611 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end"); |
577 } | 612 } |
578 catch (...) | 613 catch (...) |
579 { | 614 { |
580 } | 615 } |
581 } | 616 } |
582 | 617 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 { | 650 { |
616 Unadvise(); | 651 Unadvise(); |
617 } | 652 } |
618 catch (...) | 653 catch (...) |
619 { | 654 { |
620 } | 655 } |
621 } | 656 } |
622 | 657 |
623 bool CPluginClass::InitObject() | 658 bool CPluginClass::InitObject() |
624 { | 659 { |
625 DEBUG_GENERAL("InitObject"); | 660 DEBUG_GENERAL("InitObject - begin"); |
626 CPluginSettings* settings = CPluginSettings::GetInstance(); | 661 CPluginSettings* settings = CPluginSettings::GetInstance(); |
627 | 662 |
628 if (!settings->GetPluginEnabled()) | 663 if (!settings->GetPluginEnabled()) |
629 { | 664 { |
630 s_mimeFilter->Unregister(); | 665 s_mimeFilter->Unregister(); |
631 } | 666 } |
632 | 667 |
633 // Load theme module | 668 // Load theme module |
634 s_criticalSectionLocal.Lock(); | 669 s_criticalSectionLocal.Lock(); |
635 { | 670 { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 if (((m_hPaneWnd == NULL) || !IsStatusBarEnabled()) && isFirstRun) | 763 if (((m_hPaneWnd == NULL) || !IsStatusBarEnabled()) && isFirstRun) |
729 { | 764 { |
730 ShowStatusBar(); | 765 ShowStatusBar(); |
731 } | 766 } |
732 | 767 |
733 // Enable acceptable ads by default | 768 // Enable acceptable ads by default |
734 std::wstring aaUrl = CPluginClient::GetInstance()->GetPref(L"subscriptions_e
xceptionsurl", L""); | 769 std::wstring aaUrl = CPluginClient::GetInstance()->GetPref(L"subscriptions_e
xceptionsurl", L""); |
735 CPluginClient::GetInstance()->AddSubscription(aaUrl); | 770 CPluginClient::GetInstance()->AddSubscription(aaUrl); |
736 } | 771 } |
737 s_criticalSectionLocal.Unlock(); | 772 s_criticalSectionLocal.Unlock(); |
| 773 |
| 774 DEBUG_GENERAL("InitObject - end"); |
738 return true; | 775 return true; |
739 } | 776 } |
740 | 777 |
741 bool CPluginClass::CreateStatusBarPane() | 778 bool CPluginClass::CreateStatusBarPane() |
742 { | 779 { |
743 CriticalSection::Lock lock(m_csStatusBar); | 780 CriticalSection::Lock lock(m_csStatusBar); |
744 | 781 |
745 CPluginClient* client = CPluginClient::GetInstance(); | 782 CPluginClient* client = CPluginClient::GetInstance(); |
746 | 783 |
747 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... |
979 s_criticalSectionLocal.Unlock(); | 1016 s_criticalSectionLocal.Unlock(); |
980 | 1017 |
981 return result; | 1018 return result; |
982 } | 1019 } |
983 | 1020 |
984 CPluginTab* CPluginClass::GetTab() | 1021 CPluginTab* CPluginClass::GetTab() |
985 { | 1022 { |
986 return m_tab; | 1023 return m_tab; |
987 } | 1024 } |
988 | 1025 |
989 CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) | 1026 CPluginTab* CPluginClass::GetTabForCurrentThread() |
990 { | 1027 { |
991 CPluginTab* tab = NULL; | 1028 auto p = threadMap.Locate(); |
992 | 1029 return p ? p->m_tab : nullptr; |
993 s_criticalSectionLocal.Lock(); | 1030 } |
994 { | 1031 |
995 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(dw
ThreadId); | 1032 // Entry point |
996 if (it != s_threadInstances.end()) | |
997 { | |
998 tab = it->second->m_tab; | |
999 } | |
1000 } | |
1001 s_criticalSectionLocal.Unlock(); | |
1002 | |
1003 return tab; | |
1004 } | |
1005 | |
1006 | |
1007 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) |
1008 { | 1034 { |
1009 if (cCmds == 0) return E_INVALIDARG; | 1035 try |
1010 if (prgCmds == 0) return E_POINTER; | 1036 { |
1011 | 1037 if (cCmds == 0) return E_INVALIDARG; |
1012 prgCmds[0].cmdf = OLECMDF_ENABLED; | 1038 if (prgCmds == 0) return E_POINTER; |
1013 | 1039 |
| 1040 prgCmds[0].cmdf = OLECMDF_ENABLED; |
| 1041 } |
| 1042 catch (...) |
| 1043 { |
| 1044 DEBUG_GENERAL(L"CPluginClass::QueryStatus - exception"); |
| 1045 return E_FAIL; |
| 1046 } |
1014 return S_OK; | 1047 return S_OK; |
1015 } | 1048 } |
1016 | 1049 |
1017 HMENU CPluginClass::CreatePluginMenu(const std::wstring& url) | 1050 HMENU CPluginClass::CreatePluginMenu(const std::wstring& url) |
1018 { | 1051 { |
1019 DEBUG_GENERAL("CreatePluginMenu"); | 1052 DEBUG_GENERAL("CreatePluginMenu"); |
1020 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance(); | 1053 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance(); |
1021 | 1054 |
1022 HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); | 1055 HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); |
1023 | 1056 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1153 | 1186 |
1154 MENUITEMINFOW miiSep = {}; | 1187 MENUITEMINFOW miiSep = {}; |
1155 miiSep.cbSize = sizeof(miiSep); | 1188 miiSep.cbSize = sizeof(miiSep); |
1156 miiSep.fMask = MIIM_TYPE | MIIM_FTYPE; | 1189 miiSep.fMask = MIIM_TYPE | MIIM_FTYPE; |
1157 miiSep.fType = MFT_SEPARATOR; | 1190 miiSep.fType = MFT_SEPARATOR; |
1158 | 1191 |
1159 CPluginClient* client = CPluginClient::GetInstance(); | 1192 CPluginClient* client = CPluginClient::GetInstance(); |
1160 CPluginSettings* settings = CPluginSettings::GetInstance(); | 1193 CPluginSettings* settings = CPluginSettings::GetInstance(); |
1161 { | 1194 { |
1162 ctext = dictionary->Lookup("menu", "menu-disable-on-site"); | 1195 ctext = dictionary->Lookup("menu", "menu-disable-on-site"); |
1163 // Is domain in white list? | |
1164 ReplaceString(ctext, L"?1?", client->GetHostFromUrl(url)); | 1196 ReplaceString(ctext, L"?1?", client->GetHostFromUrl(url)); |
1165 if (client->IsWhitelistedUrl(GetTab()->GetDocumentUrl())) | 1197 /* |
1166 { | 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 |
1167 fmii.fState = MFS_CHECKED | MFS_ENABLED; | 1209 fmii.fState = MFS_CHECKED | MFS_ENABLED; |
1168 } | 1210 } |
1169 else | 1211 else |
1170 { | 1212 { |
1171 fmii.fState = MFS_UNCHECKED | MFS_ENABLED; | 1213 fmii.fState = MFS_UNCHECKED | MFS_ENABLED; |
1172 } | 1214 } |
1173 fmii.fMask = MIIM_STRING | MIIM_STATE; | 1215 fmii.fMask = MIIM_STRING | MIIM_STATE; |
1174 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); | 1216 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); |
1175 fmii.cch = static_cast<UINT>(ctext.size()); | 1217 fmii.cch = static_cast<UINT>(ctext.size()); |
1176 | 1218 |
(...skipping 28 matching lines...) Expand all Loading... |
1205 ctext = dictionary->Lookup("menu", "menu-settings"); | 1247 ctext = dictionary->Lookup("menu", "menu-settings"); |
1206 fmii.fMask = MIIM_STATE | MIIM_STRING; | 1248 fmii.fMask = MIIM_STATE | MIIM_STRING; |
1207 fmii.fState = MFS_ENABLED; | 1249 fmii.fState = MFS_ENABLED; |
1208 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); | 1250 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); |
1209 fmii.cch = static_cast<UINT>(ctext.size()); | 1251 fmii.cch = static_cast<UINT>(ctext.size()); |
1210 ::SetMenuItemInfoW(hMenu, ID_MENU_SETTINGS, FALSE, &fmii); | 1252 ::SetMenuItemInfoW(hMenu, ID_MENU_SETTINGS, FALSE, &fmii); |
1211 | 1253 |
1212 return true; | 1254 return true; |
1213 } | 1255 } |
1214 | 1256 |
1215 | 1257 // Entry point |
1216 STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V
ARIANTARG*) | 1258 STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V
ARIANTARG*) |
1217 { | 1259 { |
1218 HWND hBrowserWnd = GetBrowserHWND(); | 1260 try |
1219 if (!hBrowserWnd) | 1261 { |
1220 { | 1262 HWND hBrowserWnd = GetBrowserHWND(); |
1221 return E_FAIL; | 1263 if (!hBrowserWnd) |
1222 } | 1264 { |
1223 | 1265 return E_FAIL; |
1224 // Create menu | 1266 } |
1225 HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl()); | 1267 |
1226 if (!hMenu) | 1268 // Create menu |
1227 { | 1269 HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl()); |
1228 return E_FAIL; | 1270 if (!hMenu) |
1229 } | 1271 { |
1230 | 1272 return E_FAIL; |
1231 // Check if button in toolbar was pressed | 1273 } |
1232 int nIDCommand = -1; | 1274 |
1233 BOOL bRightAlign = FALSE; | 1275 // Check if button in toolbar was pressed |
1234 | 1276 int nIDCommand = -1; |
1235 POINT pt; | 1277 BOOL bRightAlign = FALSE; |
1236 GetCursorPos(&pt); | 1278 |
1237 | 1279 POINT pt; |
1238 HWND hWndToolBar = ::WindowFromPoint(pt); | 1280 GetCursorPos(&pt); |
1239 | 1281 |
1240 DWORD nProcessId; | 1282 HWND hWndToolBar = ::WindowFromPoint(pt); |
1241 ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); | 1283 |
1242 | 1284 DWORD nProcessId; |
1243 if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) | 1285 ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); |
1244 { | 1286 |
1245 ::ScreenToClient(hWndToolBar, &pt); | 1287 if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) |
1246 int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); | 1288 { |
1247 | 1289 ::ScreenToClient(hWndToolBar, &pt); |
1248 if (nButton > 0) | 1290 int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); |
1249 { | 1291 |
1250 TBBUTTON pTBBtn = {}; | 1292 if (nButton > 0) |
1251 | 1293 { |
1252 if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) | 1294 TBBUTTON pTBBtn = {}; |
1253 { | 1295 |
1254 RECT rcButton; | 1296 if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) |
1255 nIDCommand = pTBBtn.idCommand; | 1297 { |
1256 | 1298 RECT rcButton; |
1257 if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton)) | 1299 nIDCommand = pTBBtn.idCommand; |
1258 { | 1300 |
1259 pt.x = rcButton.left; | 1301 if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton
)) |
1260 pt.y = rcButton.bottom; | |
1261 ClientToScreen(hWndToolBar, &pt); | |
1262 | |
1263 RECT rcWorkArea; | |
1264 SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0); | |
1265 if (rcWorkArea.right - pt.x < 150) | |
1266 { | 1302 { |
1267 bRightAlign = TRUE; | 1303 pt.x = rcButton.left; |
1268 pt.x = rcButton.right; | |
1269 pt.y = rcButton.bottom; | 1304 pt.y = rcButton.bottom; |
1270 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 } |
1271 } | 1316 } |
1272 } | 1317 } |
1273 } | 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; |
1274 } | 1330 } |
1275 else | 1331 else |
1276 { | 1332 { |
1277 GetCursorPos(&pt); | 1333 nFlags |= TPM_LEFTALIGN; |
1278 } | 1334 } |
1279 } | 1335 |
1280 | 1336 DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags); |
1281 // Display menu | 1337 } |
1282 UINT nFlags = 0; | 1338 catch (...) |
1283 if (bRightAlign) | 1339 { |
1284 { | 1340 // Suppress exception, log only |
1285 nFlags |= TPM_RIGHTALIGN; | 1341 DEBUG_GENERAL(L"CPluginClass::Exec - exception"); |
1286 } | 1342 return E_FAIL; |
1287 else | 1343 } |
1288 { | |
1289 nFlags |= TPM_LEFTALIGN; | |
1290 } | |
1291 | |
1292 DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags); | |
1293 | 1344 |
1294 return S_OK; | 1345 return S_OK; |
1295 } | 1346 } |
1296 | 1347 |
1297 ///////////////////////////////////////////////////////////////////////////// | 1348 // Entry point |
1298 // Window procedures | |
1299 | |
1300 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) |
1301 { | 1350 { |
1302 // Find tab | 1351 CPluginClass *pClass; |
1303 CPluginClass *pClass = FindInstance(hWnd); | 1352 try |
1304 if (!pClass) | 1353 { |
1305 { | 1354 // Find tab |
1306 return DefWindowProc(hWnd, message, wParam, lParam); | 1355 pClass = FindInstance(hWnd); |
1307 } | 1356 if (!pClass) |
1308 | 1357 { |
1309 // Process message | 1358 /* |
1310 switch (message) | 1359 * Race condition if reached. |
1311 { | 1360 * We did not unhook the window procedure for the status bar when the last
BHO instance using it terminated. |
1312 case SB_SIMPLE: | 1361 * The next best thing is to call the system default window function. |
1313 { | 1362 */ |
1314 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: |
1315 break; | 1423 break; |
1316 } | 1424 } |
1317 | 1425 } |
1318 case WM_SYSCOLORCHANGE: | 1426 catch (...) |
1319 { | 1427 { |
1320 pClass->UpdateTheme(); | 1428 // Suppress exception. Fall through to default handler. |
1321 break; | 1429 DEBUG_GENERAL(L"CPluginClass::NewStatusProc - exception"); |
1322 } | 1430 } |
1323 | 1431 return ::CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lPara
m); |
1324 case SB_SETPARTS: | |
1325 { | |
1326 if (!lParam || !wParam || wParam > 30 || !IsWindow(pClass->m_hPaneWnd)) | |
1327 { | |
1328 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, l
Param); | |
1329 } | |
1330 | |
1331 WPARAM nParts = wParam; | |
1332 if (STATUSBAR_PANE_NUMBER >= nParts) | |
1333 { | |
1334 return CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, l
Param); | |
1335 } | |
1336 | |
1337 HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts+1)); | |
1338 LPINT lpParts = (LPINT)LocalLock(hLocal); | |
1339 memcpy(lpParts, (void*)lParam, wParam*sizeof(int)); | |
1340 | |
1341 for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++) | |
1342 { | |
1343 lpParts[i] -= pClass->m_nPaneWidth; | |
1344 } | |
1345 LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wPa
ram, (LPARAM)lpParts); | |
1346 | |
1347 AdblockPlus::Rectangle rcPane; | |
1348 ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane); | |
1349 | |
1350 AdblockPlus::Rectangle rcClient; | |
1351 ::GetClientRect(hWnd, &rcClient); | |
1352 | |
1353 ::MoveWindow( | |
1354 pClass->m_hPaneWnd, | |
1355 lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth, | |
1356 0, | |
1357 pClass->m_nPaneWidth, | |
1358 rcClient.Height(), | |
1359 TRUE); | |
1360 | |
1361 ::LocalFree(hLocal); | |
1362 | |
1363 | |
1364 return hRet; | |
1365 } | |
1366 | |
1367 default: | |
1368 break; | |
1369 } | |
1370 | |
1371 LRESULT result = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wPara
m, lParam); | |
1372 | |
1373 | |
1374 return result; | |
1375 | |
1376 } | 1432 } |
1377 | 1433 |
1378 | 1434 |
1379 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url) | 1435 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url) |
1380 { | 1436 { |
1381 // 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 |
1382 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); | 1438 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); |
1383 | 1439 |
1384 CPluginTab* tab = GetTab(::GetCurrentThreadId()); | 1440 CPluginTab* tab = GetTabForCurrentThread(); |
1385 if (tab) | 1441 if (tab) |
1386 { | 1442 { |
1387 CPluginClient* client = CPluginClient::GetInstance(); | 1443 CPluginClient* client = CPluginClient::GetInstance(); |
1388 if (CPluginSettings::GetInstance()->IsPluginEnabled()) | 1444 if (CPluginSettings::GetInstance()->IsPluginEnabled()) |
1389 { | 1445 { |
1390 if (client->IsWhitelistedUrl(url)) | 1446 if (client->IsWhitelistedUrl(url)) |
1391 { | 1447 { |
1392 hIcon = GetIcon(ICON_PLUGIN_DISABLED); | 1448 hIcon = GetIcon(ICON_PLUGIN_DISABLED); |
1393 } | 1449 } |
1394 else | 1450 else |
1395 { | 1451 { |
1396 CPluginSettings* settings = CPluginSettings::GetInstance(); | 1452 CPluginSettings* settings = CPluginSettings::GetInstance(); |
1397 hIcon = GetIcon(ICON_PLUGIN_ENABLED); | 1453 hIcon = GetIcon(ICON_PLUGIN_ENABLED); |
1398 } | 1454 } |
1399 } | 1455 } |
1400 } | 1456 } |
1401 return hIcon; | 1457 return hIcon; |
1402 } | 1458 } |
1403 | 1459 |
1404 | 1460 // Entry point |
1405 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) |
1406 { | 1462 { |
1407 // Find tab | 1463 try |
1408 CPluginClass *pClass = FindInstance(GetParent(hWnd)); | 1464 { |
1409 if (!pClass) | 1465 // Find tab |
1410 { | 1466 CPluginClass *pClass = FindInstance(GetParent(hWnd)); |
1411 return ::DefWindowProc(hWnd, message, wParam, lParam); | 1467 if (!pClass) |
1412 } | 1468 { |
1413 | 1469 return ::DefWindowProc(hWnd, message, wParam, lParam); |
1414 // Process message | 1470 } |
1415 switch (message) | 1471 |
1416 { | 1472 // Process message |
1417 | 1473 switch (message) |
1418 case WM_SETCURSOR: | 1474 { |
1419 { | 1475 case WM_SETCURSOR: |
1420 ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); | 1476 { |
1421 return TRUE; | 1477 ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); |
1422 } | 1478 return TRUE; |
1423 case WM_PAINT: | 1479 } |
1424 { | 1480 case WM_PAINT: |
1425 PAINTSTRUCT ps; | 1481 { |
1426 HDC hDC = ::BeginPaint(hWnd, &ps); | 1482 PAINTSTRUCT ps; |
1427 | 1483 HDC hDC = ::BeginPaint(hWnd, &ps); |
1428 AdblockPlus::Rectangle rcClient; | 1484 |
1429 ::GetClientRect(hWnd, &rcClient); | 1485 AdblockPlus::Rectangle rcClient; |
1430 | 1486 ::GetClientRect(hWnd, &rcClient); |
1431 int nDrawEdge = 0; | 1487 |
1432 | 1488 int nDrawEdge = 0; |
1433 // Old Windows background drawing | 1489 |
1434 if (pClass->m_hTheme == NULL) | 1490 // Old Windows background drawing |
1435 { | 1491 if (pClass->m_hTheme == NULL) |
1436 ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); | 1492 { |
1437 ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT); | 1493 ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); |
1438 | 1494 ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT); |
1439 nDrawEdge = 3; | 1495 |
1440 rcClient.left += 3; | 1496 nDrawEdge = 3; |
1441 | 1497 rcClient.left += 3; |
1442 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); | 1498 |
1443 } | 1499 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); |
1444 // Themed background drawing | 1500 } |
1445 else | 1501 // Themed background drawing |
1446 { | 1502 else |
1447 // Draw background | 1503 { |
1448 if (pfnDrawThemeBackground) | 1504 // Draw background |
1449 { | 1505 if (pfnDrawThemeBackground) |
1450 AdblockPlus::Rectangle rc = rcClient; | |
1451 rc.right -= 2; | |
1452 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL); | |
1453 } | |
1454 | |
1455 // Copy separator picture to left side | |
1456 int nHeight = rcClient.Height(); | |
1457 int nWidth = rcClient.Width() - 2; | |
1458 | |
1459 for (int i = 0; i < 2; i++) | |
1460 { | |
1461 for (int j = 0; j < nHeight; j++) | |
1462 { | 1506 { |
1463 COLORREF clr = ::GetPixel(hDC, i + nWidth, j); | 1507 AdblockPlus::Rectangle rc = rcClient; |
1464 | 1508 rc.right -= 2; |
1465 // Ignore black boxes (if source is obscured by other windows) | 1509 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL); |
1466 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++) |
1467 { | 1519 { |
1468 ::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 } |
1469 } | 1527 } |
1470 } | 1528 } |
1471 } | 1529 } |
1472 } | 1530 |
1473 | 1531 // Draw icon |
1474 // Draw icon | 1532 if (CPluginClient::GetInstance()) |
1475 if (CPluginClient::GetInstance()) | 1533 { |
1476 { | 1534 HICON hIcon = GetStatusBarIcon(pClass->GetTab()->GetDocumentUrl()); |
1477 HICON hIcon = GetStatusBarIcon(pClass->GetTab()->GetDocumentUrl()); | 1535 |
1478 | 1536 int offx = nDrawEdge; |
1479 int offx = nDrawEdge; | 1537 if (hIcon) |
1480 if (hIcon) | 1538 { |
1481 { | 1539 //Get the RECT for the leftmost pane (the status text pane) |
1482 //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(); |
1483 RECT rect; | 1608 RECT rect; |
1484 BOOL rectRes = ::SendMessage(pClass->m_hStatusBarWnd, SB_GETRECT, 0, (
LPARAM)&rect); | 1609 GetWindowRect(pClass->m_hPaneWnd, &rect); |
1485 ::DrawIconEx(hDC, 0, rect.bottom - rect.top - iconHeight, hIcon, iconW
idth, iconHeight, NULL, NULL, DI_NORMAL); | 1610 pClass->notificationMessage.MoveToCenter(rect); |
1486 offx += iconWidth; | 1611 } |
1487 } | 1612 if (LOWORD(wParam) == UIS_CLEAR) |
1488 #ifdef _DEBUG | 1613 { |
1489 // Display version | 1614 pClass->notificationMessage.Hide(); |
1490 HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT,
0, 0); | 1615 } |
1491 HGDIOBJ hOldFont = ::SelectObject(hDC,hFont); | 1616 break; |
1492 | 1617 } |
1493 AdblockPlus::Rectangle rcText = rcClient; | 1618 case WM_WINDOWPOSCHANGING: |
1494 rcText.left += offx; | |
1495 ::SetBkMode(hDC, TRANSPARENT); | |
1496 ::DrawTextW(hDC, IEPLUGIN_VERSION, -1, &rcText, DT_WORD_ELLIPSIS|DT_LEFT
|DT_SINGLELINE|DT_VCENTER); | |
1497 | |
1498 ::SelectObject(hDC, hOldFont); | |
1499 #endif // _DEBUG | |
1500 } | |
1501 | |
1502 // Done! | |
1503 EndPaint(hWnd, &ps); | |
1504 | |
1505 return 0; | |
1506 } | |
1507 | |
1508 case WM_LBUTTONUP: | |
1509 case WM_RBUTTONUP: | |
1510 { | |
1511 std::wstring url = pClass->GetBrowserUrl(); | |
1512 if (url != pClass->GetTab()->GetDocumentUrl()) | |
1513 { | |
1514 pClass->GetTab()->SetDocumentUrl(url); | |
1515 } | |
1516 | |
1517 // Create menu | |
1518 HMENU hMenu = pClass->CreatePluginMenu(url); | |
1519 if (!hMenu) | |
1520 { | |
1521 return 0; | |
1522 } | |
1523 | |
1524 // Display menu | |
1525 POINT pt; | |
1526 ::GetCursorPos(&pt); | |
1527 | |
1528 RECT rc; | |
1529 ::GetWindowRect(hWnd, &rc); | |
1530 | |
1531 if (rc.left >= 0 && rc.top >= 0) | |
1532 { | |
1533 pt.x = rc.left; | |
1534 pt.y = rc.top; | |
1535 } | |
1536 | |
1537 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN|TPM_BOTTOMALIGN); | |
1538 } | |
1539 break; | |
1540 case WM_DESTROY: | |
1541 break; | |
1542 case SC_CLOSE: | |
1543 break; | |
1544 | |
1545 case WM_UPDATEUISTATE: | |
1546 { | |
1547 CPluginTab* tab = GetTab(::GetCurrentThreadId()); | |
1548 if (tab) | |
1549 { | 1619 { |
1550 RECT rect; | 1620 RECT rect; |
1551 GetWindowRect(pClass->m_hPaneWnd, &rect); | 1621 GetWindowRect(pClass->m_hPaneWnd, &rect); |
1552 pClass->notificationMessage.Move(rect.left + (rect.right - rect.left) /
2, rect.top + (rect.bottom - rect.top) / 2); | 1622 if (pClass->notificationMessage.IsVisible()) |
1553 } | 1623 { |
1554 if (LOWORD(wParam) == UIS_CLEAR) | 1624 pClass->notificationMessage.MoveToCenter(rect); |
1555 { | 1625 } |
1556 pClass->notificationMessage.Hide(); | 1626 break; |
1557 } | 1627 } |
1558 } | 1628 case WM_WINDOWPOSCHANGED: |
1559 break; | 1629 { |
1560 case WM_WINDOWPOSCHANGING: | 1630 WINDOWPOS* wndPos = reinterpret_cast<WINDOWPOS*>(lParam); |
1561 { | 1631 if (wndPos->flags & SWP_HIDEWINDOW) |
1562 RECT rect; | 1632 { |
1563 GetWindowRect(pClass->m_hPaneWnd, &rect); | 1633 pClass->notificationMessage.Hide(); |
1564 if (pClass->notificationMessage.IsVisible()) | 1634 } |
1565 { | 1635 break; |
1566 pClass->notificationMessage.Move(rect.left + (rect.right - rect.left) /
2, rect.top + (rect.bottom - rect.top) / 2); | 1636 } |
1567 } | 1637 case WM_ALREADY_UP_TO_DATE: |
1568 } | 1638 { |
1569 break; | 1639 Dictionary* dictionary = Dictionary::GetInstance(); |
1570 case WM_WINDOWPOSCHANGED: | 1640 std::wstring upToDateText = dictionary->Lookup("updater", "update-alread
y-up-to-date-text"); |
1571 { | 1641 std::wstring upToDateTitle = dictionary->Lookup("updater", "update-alrea
dy-up-to-date-title"); |
1572 WINDOWPOS* wndPos = reinterpret_cast<WINDOWPOS*>(lParam); | 1642 pClass->notificationMessage.SetTextAndIcon(upToDateText, upToDateTitle,
TTI_INFO); |
1573 if (wndPos->flags & SWP_HIDEWINDOW) | 1643 break; |
1574 { | 1644 } |
1575 pClass->notificationMessage.Hide(); | 1645 case WM_UPDATE_CHECK_ERROR: |
1576 } | 1646 { |
1577 } | 1647 Dictionary* dictionary = Dictionary::GetInstance(); |
1578 break; | 1648 std::wstring errorText = dictionary->Lookup("updater", "update-error-tex
t"); |
1579 case WM_ALREADY_UP_TO_DATE: | 1649 std::wstring errorTitle = dictionary->Lookup("updater", "update-error-ti
tle"); |
1580 { | 1650 pClass->notificationMessage.SetTextAndIcon(errorText, errorTitle, TTI_ER
ROR); |
1581 Dictionary* dictionary = Dictionary::GetInstance(); | 1651 break; |
1582 std::wstring upToDateText = dictionary->Lookup("updater", "update-already-
up-to-date-text"); | 1652 } |
1583 std::wstring upToDateTitle = dictionary->Lookup("updater", "update-already
-up-to-date-title"); | 1653 case WM_DOWNLOADING_UPDATE: |
1584 pClass->notificationMessage.SetTextAndIcon(upToDateText, upToDateTitle, TT
I_INFO); | 1654 { |
1585 } | 1655 Dictionary* dictionary = Dictionary::GetInstance(); |
1586 break; | 1656 std::wstring downloadingText = dictionary->Lookup("updater", "downloadin
g-update-text"); |
1587 case WM_UPDATE_CHECK_ERROR: | 1657 std::wstring downloadingTitle = dictionary->Lookup("updater", "downloadi
ng-update-title"); |
1588 { | 1658 pClass->notificationMessage.SetTextAndIcon(downloadingText, downloadingT
itle, TTI_INFO); |
1589 Dictionary* dictionary = Dictionary::GetInstance(); | 1659 break; |
1590 std::wstring errorText = dictionary->Lookup("updater", "update-error-text"
); | 1660 } |
1591 std::wstring errorTitle = dictionary->Lookup("updater", "update-error-titl
e"); | 1661 } |
1592 pClass->notificationMessage.SetTextAndIcon(errorText, errorText, TTI_ERROR
); | 1662 } |
1593 } | 1663 catch (...) |
1594 break; | 1664 { |
1595 case WM_DOWNLOADING_UPDATE: | 1665 // Suppress exception. Fall through to default handler. |
1596 { | 1666 DEBUG_GENERAL(L"CPluginClass::PaneWindowProc - exception"); |
1597 Dictionary* dictionary = Dictionary::GetInstance(); | 1667 } |
1598 std::wstring downloadingText = dictionary->Lookup("updater", "downloading-
update-text"); | 1668 return ::DefWindowProc(hWnd, message, wParam, lParam); |
1599 std::wstring downloadingTitle = dictionary->Lookup("updater", "downloading
-update-title"); | |
1600 pClass->notificationMessage.SetTextAndIcon(downloadingText, downloadingTit
le, TTI_INFO); | |
1601 } | |
1602 break; | |
1603 } | |
1604 | |
1605 return DefWindowProc(hWnd, message, wParam, lParam); | |
1606 } | 1669 } |
1607 | 1670 |
1608 | 1671 |
1609 void CPluginClass::UpdateStatusBar() | 1672 void CPluginClass::UpdateStatusBar() |
1610 { | 1673 { |
1611 DEBUG_GENERAL("*** Updating statusbar") | 1674 DEBUG_GENERAL("*** Updating statusbar") |
1612 if (m_hPaneWnd == NULL) | 1675 if (m_hPaneWnd == NULL) |
1613 { | 1676 { |
1614 CreateStatusBarPane(); | 1677 CreateStatusBarPane(); |
1615 } | 1678 } |
1616 if ((m_hPaneWnd != NULL) && !::InvalidateRect(m_hPaneWnd, NULL, FALSE)) | 1679 if ((m_hPaneWnd != NULL) && !::InvalidateRect(m_hPaneWnd, NULL, FALSE)) |
1617 { | 1680 { |
1618 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"); |
1619 } | 1682 } |
1620 } | 1683 } |
1621 | 1684 |
1622 | 1685 |
1623 void CPluginClass::Unadvise() | 1686 void CPluginClass::Unadvise() |
1624 { | 1687 { |
| 1688 if (!m_webBrowser2) |
| 1689 { |
| 1690 DEBUG_ERROR_LOG(0, 0, 0, "CPluginClass::Unadvise - Reached with m_webBrowser
2 == nullptr"); |
| 1691 return; |
| 1692 } |
1625 s_criticalSectionLocal.Lock(); | 1693 s_criticalSectionLocal.Lock(); |
1626 { | 1694 { |
1627 if (m_isAdvised) | 1695 if (m_isAdvised) |
1628 { | 1696 { |
1629 HRESULT hr = DispEventUnadvise(GetBrowser()); | 1697 HRESULT hr = DispEventUnadvise(m_webBrowser2); |
1630 if (FAILED(hr)) | 1698 if (FAILED(hr)) |
1631 { | 1699 { |
1632 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"); |
1633 } | 1701 } |
1634 m_isAdvised = false; | 1702 m_isAdvised = false; |
1635 } | 1703 } |
1636 } | 1704 } |
1637 s_criticalSectionLocal.Unlock(); | 1705 s_criticalSectionLocal.Unlock(); |
1638 } | 1706 } |
1639 | 1707 |
(...skipping 19 matching lines...) Expand all Loading... |
1659 s_criticalSectionLocal.Unlock(); | 1727 s_criticalSectionLocal.Unlock(); |
1660 | 1728 |
1661 return icon; | 1729 return icon; |
1662 } | 1730 } |
1663 | 1731 |
1664 ATOM CPluginClass::GetAtomPaneClass() | 1732 ATOM CPluginClass::GetAtomPaneClass() |
1665 { | 1733 { |
1666 return s_atomPaneClass; | 1734 return s_atomPaneClass; |
1667 } | 1735 } |
1668 | 1736 |
1669 HWND CPluginClass::GetTabHWND() const | |
1670 { | |
1671 std::array<wchar_t, MAX_PATH> className; | |
1672 // Get browser window and url | |
1673 HWND hBrowserWnd = GetBrowserHWND(); | |
1674 if (!hBrowserWnd) | |
1675 { | |
1676 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_BROWSER, "C
lass::GetTabWindow - No tab window"); | |
1677 s_criticalSectionWindow.Unlock(); | |
1678 return false; | |
1679 } | |
1680 | |
1681 // Looking for a TabWindowClass window in IE7 | |
1682 | |
1683 HWND hTabWnd = ::GetWindow(hBrowserWnd, GW_CHILD); | |
1684 while (hTabWnd) | |
1685 { | |
1686 className[0] = L'\0'; | |
1687 int classNameLength = GetClassNameW(hTabWnd, className.data(), className.siz
e()); | |
1688 | |
1689 if (classNameLength && (wcscmp(className.data(), L"TabWindowClass") == 0 ||
wcscmp(className.data(), L"Frame Tab") == 0)) | |
1690 { | |
1691 // IE8 support | |
1692 HWND hTabWnd2 = hTabWnd; | |
1693 if (wcscmp(className.data(), L"Frame Tab") == 0) | |
1694 { | |
1695 hTabWnd2 = ::FindWindowEx(hTabWnd2, NULL, L"TabWindowClass", NULL); | |
1696 } | |
1697 | |
1698 if (hTabWnd2) | |
1699 { | |
1700 DWORD nProcessId; | |
1701 ::GetWindowThreadProcessId(hTabWnd2, &nProcessId); | |
1702 if (::GetCurrentProcessId() == nProcessId) | |
1703 { | |
1704 bool bExistingTab = false; | |
1705 s_criticalSectionLocal.Lock(); | |
1706 | |
1707 { | |
1708 for (auto instance : s_instances) | |
1709 { | |
1710 if (instance->m_hTabWnd == hTabWnd2) | |
1711 { | |
1712 bExistingTab = true; | |
1713 break; | |
1714 } | |
1715 } | |
1716 } | |
1717 | |
1718 if (!bExistingTab) | |
1719 { | |
1720 hBrowserWnd = hTabWnd2; | |
1721 hTabWnd = hTabWnd2; | |
1722 s_criticalSectionLocal.Unlock(); | |
1723 break; | |
1724 } | |
1725 s_criticalSectionLocal.Unlock(); | |
1726 | |
1727 } | |
1728 } | |
1729 } | |
1730 | |
1731 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); | |
1732 } | |
1733 return hTabWnd; | |
1734 } | |
LEFT | RIGHT |