| 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 |