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