OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 Eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 | 232 |
233 | 233 |
234 | 234 |
235 // This gets called when a new browser window is created (which also triggers th
e | 235 // This gets called when a new browser window is created (which also triggers th
e |
236 // creation of this object). The pointer passed in should be to a IWebBrowser2 | 236 // creation of this object). The pointer passed in should be to a IWebBrowser2 |
237 // interface that represents the browser for the window. | 237 // interface that represents the browser for the window. |
238 // it is also called when a tab is closed, this unknownSite will be null | 238 // it is also called when a tab is closed, this unknownSite will be null |
239 // so we should handle that it is called this way several times during a session | 239 // so we should handle that it is called this way several times during a session |
240 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) | 240 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) |
241 { | 241 { |
242 CPluginSettings* settings = CPluginSettings::GetInstance(); | 242 return EntryPointWithHResult([&]()->HRESULT |
| 243 { |
| 244 CPluginSettings* settings = CPluginSettings::GetInstance(); |
243 | 245 |
244 MULTIPLE_VERSIONS_CHECK(); | 246 MULTIPLE_VERSIONS_CHECK(); |
245 | 247 |
246 if (unknownSite) | 248 if (unknownSite) |
247 { | 249 { |
248 | 250 |
249 DEBUG_GENERAL(L"============================================================
====================\nNEW TAB UI\n==============================================
==================================") | 251 DEBUG_GENERAL(L"==========================================================
======================\nNEW TAB UI\n============================================
====================================") |
250 | 252 |
251 HRESULT hr = ::CoInitialize(NULL); | 253 HRESULT hr = ::CoInitialize(NULL); |
252 if (FAILED(hr)) | 254 if (FAILED(hr)) |
253 { | 255 { |
254 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT, "
Class::SetSite - CoInitialize"); | 256 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT,
"Class::SetSite - CoInitialize"); |
255 } | 257 } |
256 | 258 |
257 s_criticalSectionBrowser.Lock(); | 259 s_criticalSectionBrowser.Lock(); |
258 { | 260 { |
259 m_webBrowser2 = unknownSite; | 261 m_webBrowser2 = unknownSite; |
260 } | 262 } |
261 s_criticalSectionBrowser.Unlock(); | 263 s_criticalSectionBrowser.Unlock(); |
262 | 264 |
263 //register the mimefilter | 265 //register the mimefilter |
264 //and only mimefilter | 266 //and only mimefilter |
265 //on some few computers the mimefilter does not get properly registered when
it is done on another thread | 267 //on some few computers the mimefilter does not get properly registered wh
en it is done on another thread |
266 | 268 |
267 s_criticalSectionLocal.Lock(); | 269 s_criticalSectionLocal.Lock(); |
268 { | 270 { |
269 // Always register on startup, then check if we need to unregister in a se
parate thread | 271 // Always register on startup, then check if we need to unregister in a
separate thread |
270 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); | 272 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
271 s_asyncWebBrowser2 = unknownSite; | 273 s_asyncWebBrowser2 = unknownSite; |
272 s_instances.insert(this); | 274 s_instances.insert(this); |
273 } | 275 } |
274 s_criticalSectionLocal.Unlock(); | 276 s_criticalSectionLocal.Unlock(); |
275 | 277 |
276 try | 278 try |
277 { | |
278 // Check if loaded as BHO | |
279 if (GetBrowser()) | |
280 { | 279 { |
281 DEBUG_GENERAL("Loaded as BHO"); | 280 // Check if loaded as BHO |
282 CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); | 281 if (GetBrowser()) |
283 if (pPoint) | |
284 { | 282 { |
285 HRESULT hr = pPoint->Advise((IDispatch*)this, &m_nConnectionID); | 283 DEBUG_GENERAL("Loaded as BHO"); |
| 284 CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); |
| 285 if (pPoint) |
| 286 { |
| 287 HRESULT hr = pPoint->Advise((IDispatch*)this, &m_nConnectionID); |
| 288 if (SUCCEEDED(hr)) |
| 289 { |
| 290 m_isAdviced = true; |
| 291 |
| 292 try |
| 293 { |
| 294 std::thread startInitObjectThread(StartInitObject, this); |
| 295 startInitObjectThread.detach(); // TODO: but actually we should
wait for the thread in the dtr. |
| 296 } |
| 297 catch (const std::system_error& ex) |
| 298 { |
| 299 auto errDescription = std::string("Class::Thread - Failed to cre
ate StartInitObject thread, ") + |
| 300 ex.code().message() + ex.what(); |
| 301 DEBUG_ERROR_LOG(ex.code().value(), PLUGIN_ERROR_THREAD, PLUGIN_E
RROR_MAIN_THREAD_CREATE_PROCESS, errDescription.c_str()); |
| 302 } |
| 303 } |
| 304 else |
| 305 { |
| 306 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_A
DVICE, "Class::SetSite - Advice"); |
| 307 } |
| 308 } |
| 309 } |
| 310 else // Check if loaded as toolbar handler |
| 311 { |
| 312 DEBUG_GENERAL("Loaded as toolbar handler"); |
| 313 CComPtr<IServiceProvider> pServiceProvider; |
| 314 |
| 315 HRESULT hr = unknownSite->QueryInterface(&pServiceProvider); |
286 if (SUCCEEDED(hr)) | 316 if (SUCCEEDED(hr)) |
287 { | 317 { |
288 m_isAdviced = true; | 318 if (pServiceProvider) |
289 | |
290 try | |
291 { | 319 { |
292 std::thread startInitObjectThread(StartInitObject, this); | 320 s_criticalSectionBrowser.Lock(); |
293 startInitObjectThread.detach(); // TODO: but actually we should wa
it for the thread in the dtr. | 321 { |
294 } | 322 HRESULT hr = pServiceProvider->QueryService(IID_IWebBrowserApp,
&m_webBrowser2); |
295 catch (const std::system_error& ex) | 323 if (SUCCEEDED(hr)) |
296 { | 324 { |
297 auto errDescription = std::string("Class::Thread - Failed to creat
e StartInitObject thread, ") + | 325 if (m_webBrowser2) |
298 ex.code().message() + ex.what(); | 326 { |
299 DEBUG_ERROR_LOG(ex.code().value(), PLUGIN_ERROR_THREAD, PLUGIN_ERR
OR_MAIN_THREAD_CREATE_PROCESS, errDescription.c_str()); | 327 InitObject(false); |
| 328 } |
| 329 } |
| 330 else |
| 331 { |
| 332 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SI
TE_QUERY_BROWSER, "Class::SetSite - QueryService (IID_IWebBrowserApp)"); |
| 333 } |
| 334 } |
| 335 s_criticalSectionBrowser.Unlock(); |
300 } | 336 } |
301 } | 337 } |
302 else | 338 else |
303 { | 339 { |
304 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADV
ICE, "Class::SetSite - Advice"); | 340 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_QUE
RY_SERVICE_PROVIDER, "Class::SetSite - QueryInterface (service provider)"); |
305 } | 341 } |
306 } | 342 } |
307 } | 343 } |
308 else // Check if loaded as toolbar handler | 344 catch (std::runtime_error e) |
309 { | 345 { |
310 DEBUG_GENERAL("Loaded as toolbar handler"); | 346 DEBUG_ERROR(e.what()); |
311 CComPtr<IServiceProvider> pServiceProvider; | 347 Unadvice(); |
| 348 } |
| 349 } |
| 350 else |
| 351 { |
| 352 // Unadvice |
| 353 Unadvice(); |
312 | 354 |
313 HRESULT hr = unknownSite->QueryInterface(&pServiceProvider); | 355 // Destroy window |
314 if (SUCCEEDED(hr)) | 356 if (m_pWndProcStatus) |
| 357 { |
| 358 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWn
dProcStatus); |
| 359 |
| 360 m_pWndProcStatus = NULL; |
| 361 } |
| 362 |
| 363 if (m_hPaneWnd) |
| 364 { |
| 365 DestroyWindow(m_hPaneWnd); |
| 366 m_hPaneWnd = NULL; |
| 367 } |
| 368 |
| 369 m_hTabWnd = NULL; |
| 370 m_hStatusBarWnd = NULL; |
| 371 |
| 372 // Remove instance from the list, shutdown threads |
| 373 HANDLE hMainThread = NULL; |
| 374 HANDLE hTabThread = NULL; |
| 375 |
| 376 s_criticalSectionLocal.Lock(); |
| 377 { |
| 378 s_instances.erase(this); |
| 379 |
| 380 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::Ge
tCurrentThreadId()); |
| 381 if (it != s_threadInstances.end()) |
315 { | 382 { |
316 if (pServiceProvider) | 383 s_threadInstances.erase(it); |
317 { | |
318 s_criticalSectionBrowser.Lock(); | |
319 { | |
320 HRESULT hr = pServiceProvider->QueryService(IID_IWebBrowserApp, &m
_webBrowser2); | |
321 if (SUCCEEDED(hr)) | |
322 { | |
323 if (m_webBrowser2) | |
324 { | |
325 InitObject(false); | |
326 } | |
327 } | |
328 else | |
329 { | |
330 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE
_QUERY_BROWSER, "Class::SetSite - QueryService (IID_IWebBrowserApp)"); | |
331 } | |
332 } | |
333 s_criticalSectionBrowser.Unlock(); | |
334 } | |
335 } | 384 } |
336 else | 385 if (s_instances.empty()) |
337 { | 386 { |
338 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_QUERY
_SERVICE_PROVIDER, "Class::SetSite - QueryInterface (service provider)"); | 387 // TODO: Explicitly releasing a resource when a container becomes empt
y looks like a job better suited for shared_ptr |
| 388 CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
339 } | 389 } |
340 } | 390 } |
341 } | 391 s_criticalSectionLocal.Unlock(); |
342 catch (std::runtime_error e) | |
343 { | |
344 DEBUG_ERROR(e.what()); | |
345 Unadvice(); | |
346 } | |
347 } | |
348 else | |
349 { | |
350 // Unadvice | |
351 Unadvice(); | |
352 | 392 |
353 // Destroy window | 393 // Release browser interface |
354 if (m_pWndProcStatus) | 394 s_criticalSectionBrowser.Lock(); |
355 { | 395 { |
356 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWndP
rocStatus); | 396 m_webBrowser2.Release(); |
| 397 } |
| 398 s_criticalSectionBrowser.Unlock(); |
357 | 399 |
358 m_pWndProcStatus = NULL; | 400 DEBUG_GENERAL("===========================================================
=====================\nNEW TAB UI - END\n=======================================
=========================================") |
| 401 |
| 402 ::CoUninitialize(); |
359 } | 403 } |
360 | 404 |
361 if (m_hPaneWnd) | 405 return IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite); |
362 { | 406 }); |
363 DestroyWindow(m_hPaneWnd); | |
364 m_hPaneWnd = NULL; | |
365 } | |
366 | |
367 m_hTabWnd = NULL; | |
368 m_hStatusBarWnd = NULL; | |
369 | |
370 // Remove instance from the list, shutdown threads | |
371 HANDLE hMainThread = NULL; | |
372 HANDLE hTabThread = NULL; | |
373 | |
374 s_criticalSectionLocal.Lock(); | |
375 { | |
376 s_instances.erase(this); | |
377 | |
378 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetC
urrentThreadId()); | |
379 if (it != s_threadInstances.end()) | |
380 { | |
381 s_threadInstances.erase(it); | |
382 } | |
383 if (s_instances.empty()) | |
384 { | |
385 // TODO: Explicitly releasing a resource when a container becomes empty
looks like a job better suited for shared_ptr | |
386 CPluginClientFactory::ReleaseMimeFilterClientInstance(); | |
387 } | |
388 } | |
389 s_criticalSectionLocal.Unlock(); | |
390 | |
391 // Release browser interface | |
392 s_criticalSectionBrowser.Lock(); | |
393 { | |
394 m_webBrowser2.Release(); | |
395 } | |
396 s_criticalSectionBrowser.Unlock(); | |
397 | |
398 DEBUG_GENERAL("=============================================================
===================\nNEW TAB UI - END\n=========================================
=======================================") | |
399 | |
400 ::CoUninitialize(); | |
401 } | |
402 | |
403 return IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite); | |
404 } | 407 } |
405 | 408 |
406 bool CPluginClass::IsStatusBarEnabled() | 409 bool CPluginClass::IsStatusBarEnabled() |
407 { | 410 { |
408 DEBUG_GENERAL("IsStatusBarEnabled start"); | 411 DEBUG_GENERAL("IsStatusBarEnabled start"); |
409 HKEY pHkey; | 412 HKEY pHkey; |
410 HKEY pHkeySub; | 413 HKEY pHkeySub; |
411 RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey); | 414 RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey); |
412 DWORD truth = 1; | 415 DWORD truth = 1; |
413 DWORD truthSize = sizeof(truth); | 416 DWORD truthSize = sizeof(truth); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 InitObject(true); | 615 InitObject(true); |
613 UpdateStatusBar(); | 616 UpdateStatusBar(); |
614 } | 617 } |
615 } | 618 } |
616 } | 619 } |
617 notificationMessage.Hide(); | 620 notificationMessage.Hide(); |
618 DEBUG_GENERAL("Tab change end"); | 621 DEBUG_GENERAL("Tab change end"); |
619 return S_OK; | 622 return S_OK; |
620 } | 623 } |
621 | 624 |
622 // This gets called whenever there's a browser event | |
623 // ENTRY POINT | |
624 STDMETHODIMP CPluginClass::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, W
ORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO* pExcepInfo,
UINT* puArgErr) | 625 STDMETHODIMP CPluginClass::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, W
ORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO* pExcepInfo,
UINT* puArgErr) |
625 { | 626 { |
626 try | 627 return EntryPointWithHResult([&]()->HRESULT |
627 { | 628 { |
628 WCHAR tmp[256]; | 629 WCHAR tmp[256]; |
629 wsprintf(tmp, L"Invoke: %d\n", dispidMember); | 630 wsprintf(tmp, L"Invoke: %d\n", dispidMember); |
630 DEBUG_GENERAL(tmp); | 631 DEBUG_GENERAL(tmp); |
631 switch (dispidMember) | 632 switch (dispidMember) |
632 { | 633 { |
633 case DISPID_WINDOWSTATECHANGED: | 634 case DISPID_WINDOWSTATECHANGED: |
634 { | 635 { |
635 // #1163 should validate and convert arguments here | 636 // #1163 should validate and convert arguments here |
636 return OnTabChanged(pDispParams, wFlags); | 637 return OnTabChanged(pDispParams, wFlags); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 DEBUG_NAVI(L"Navi::Default " + did) | 755 DEBUG_NAVI(L"Navi::Default " + did) |
755 } | 756 } |
756 /* | 757 /* |
757 * Ordinarily a method not dispatched should return DISP_E_MEMBERNOTFOUND. | 758 * Ordinarily a method not dispatched should return DISP_E_MEMBERNOTFOUND. |
758 * As a conservative initial change, we leave it behaving as before, | 759 * As a conservative initial change, we leave it behaving as before, |
759 * which is to do nothing and return S_OK. | 760 * which is to do nothing and return S_OK. |
760 */ | 761 */ |
761 // do nothing | 762 // do nothing |
762 break; | 763 break; |
763 } | 764 } |
764 } | 765 }); |
765 catch(...) | |
766 { | |
767 DEBUG_GENERAL( "Caught unknown exception in CPluginClass::Invoke" ); | |
768 return E_FAIL; | |
769 } | |
770 return S_OK; | |
771 } | 766 } |
772 | 767 |
773 bool CPluginClass::InitObject(bool bBHO) | 768 bool CPluginClass::InitObject(bool bBHO) |
774 { | 769 { |
775 DEBUG_GENERAL("InitObject"); | 770 DEBUG_GENERAL("InitObject"); |
776 CPluginSettings* settings = CPluginSettings::GetInstance(); | 771 CPluginSettings* settings = CPluginSettings::GetInstance(); |
777 | 772 |
778 if (!settings->GetPluginEnabled()) | 773 if (!settings->GetPluginEnabled()) |
779 { | 774 { |
780 s_mimeFilter->Unregister(); | 775 s_mimeFilter->Unregister(); |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 } | 1134 } |
1140 } | 1135 } |
1141 s_criticalSectionLocal.Unlock(); | 1136 s_criticalSectionLocal.Unlock(); |
1142 | 1137 |
1143 return tab; | 1138 return tab; |
1144 } | 1139 } |
1145 | 1140 |
1146 | 1141 |
1147 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O
LECMD prgCmds[], OLECMDTEXT* pCmdText) | 1142 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O
LECMD prgCmds[], OLECMDTEXT* pCmdText) |
1148 { | 1143 { |
1149 if (cCmds == 0) return E_INVALIDARG; | 1144 return EntryPointWithHResult([&]()->HRESULT |
1150 if (prgCmds == 0) return E_POINTER; | 1145 { |
| 1146 if (cCmds == 0) return E_INVALIDARG; |
| 1147 if (prgCmds == 0) return E_POINTER; |
1151 | 1148 |
1152 prgCmds[0].cmdf = OLECMDF_ENABLED; | 1149 prgCmds[0].cmdf = OLECMDF_ENABLED; |
1153 | 1150 |
1154 return S_OK; | 1151 return S_OK; |
| 1152 }); |
1155 } | 1153 } |
1156 | 1154 |
1157 HMENU CPluginClass::CreatePluginMenu(const std::wstring& url) | 1155 HMENU CPluginClass::CreatePluginMenu(const std::wstring& url) |
1158 { | 1156 { |
1159 DEBUG_GENERAL("CreatePluginMenu"); | 1157 DEBUG_GENERAL("CreatePluginMenu"); |
1160 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance(); | 1158 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance(); |
1161 | 1159 |
1162 HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); | 1160 HMENU hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)); |
1163 | 1161 |
1164 HMENU hMenuTrackPopup = GetSubMenu(hMenu, 0); | 1162 HMENU hMenuTrackPopup = GetSubMenu(hMenu, 0); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); | 1347 fmii.dwTypeData = const_cast<LPWSTR>(ctext.c_str()); |
1350 fmii.cch = static_cast<UINT>(ctext.size()); | 1348 fmii.cch = static_cast<UINT>(ctext.size()); |
1351 ::SetMenuItemInfoW(hMenu, ID_MENU_SETTINGS, FALSE, &fmii); | 1349 ::SetMenuItemInfoW(hMenu, ID_MENU_SETTINGS, FALSE, &fmii); |
1352 | 1350 |
1353 return true; | 1351 return true; |
1354 } | 1352 } |
1355 | 1353 |
1356 | 1354 |
1357 STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V
ARIANTARG*) | 1355 STDMETHODIMP CPluginClass::Exec(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, V
ARIANTARG*) |
1358 { | 1356 { |
1359 HWND hBrowserWnd = GetBrowserHWND(); | 1357 return EntryPointWithHResult([&]()->HRESULT |
1360 if (!hBrowserWnd) | |
1361 { | 1358 { |
1362 return E_FAIL; | 1359 HWND hBrowserWnd = GetBrowserHWND(); |
1363 } | 1360 if (!hBrowserWnd) |
| 1361 { |
| 1362 return E_FAIL; |
| 1363 } |
1364 | 1364 |
1365 // Create menu | 1365 // Create menu |
1366 HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl()); | 1366 HMENU hMenu = CreatePluginMenu(m_tab->GetDocumentUrl()); |
1367 if (!hMenu) | 1367 if (!hMenu) |
1368 { | 1368 { |
1369 return E_FAIL; | 1369 return E_FAIL; |
1370 } | 1370 } |
1371 | 1371 |
1372 // Check if button in toolbar was pressed | 1372 // Check if button in toolbar was pressed |
1373 int nIDCommand = -1; | 1373 int nIDCommand = -1; |
1374 BOOL bRightAlign = FALSE; | 1374 BOOL bRightAlign = FALSE; |
1375 | 1375 |
1376 POINT pt; | 1376 POINT pt; |
1377 GetCursorPos(&pt); | 1377 GetCursorPos(&pt); |
1378 | 1378 |
1379 HWND hWndToolBar = ::WindowFromPoint(pt); | 1379 HWND hWndToolBar = ::WindowFromPoint(pt); |
1380 | 1380 |
1381 DWORD nProcessId; | 1381 DWORD nProcessId; |
1382 ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); | 1382 ::GetWindowThreadProcessId(hWndToolBar, &nProcessId); |
1383 | 1383 |
1384 if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) | 1384 if (hWndToolBar && ::GetCurrentProcessId() == nProcessId) |
1385 { | 1385 { |
1386 ::ScreenToClient(hWndToolBar, &pt); | 1386 ::ScreenToClient(hWndToolBar, &pt); |
1387 int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); | 1387 int nButton = (int)::SendMessage(hWndToolBar, TB_HITTEST, 0, (LPARAM)&pt); |
1388 | 1388 |
1389 if (nButton > 0) | 1389 if (nButton > 0) |
1390 { | 1390 { |
1391 TBBUTTON pTBBtn = {}; | 1391 TBBUTTON pTBBtn = {}; |
1392 | 1392 |
1393 if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) | 1393 if (SendMessage(hWndToolBar, TB_GETBUTTON, nButton, (LPARAM)&pTBBtn)) |
1394 { | 1394 { |
1395 RECT rcButton; | 1395 RECT rcButton; |
1396 nIDCommand = pTBBtn.idCommand; | 1396 nIDCommand = pTBBtn.idCommand; |
1397 | 1397 |
1398 if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton)) | 1398 if (SendMessage(hWndToolBar, TB_GETRECT, nIDCommand, (LPARAM)&rcButton
)) |
1399 { | |
1400 pt.x = rcButton.left; | |
1401 pt.y = rcButton.bottom; | |
1402 ClientToScreen(hWndToolBar, &pt); | |
1403 | |
1404 RECT rcWorkArea; | |
1405 SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0); | |
1406 if (rcWorkArea.right - pt.x < 150) | |
1407 { | 1399 { |
1408 bRightAlign = TRUE; | 1400 pt.x = rcButton.left; |
1409 pt.x = rcButton.right; | |
1410 pt.y = rcButton.bottom; | 1401 pt.y = rcButton.bottom; |
1411 ClientToScreen(hWndToolBar, &pt); | 1402 ClientToScreen(hWndToolBar, &pt); |
| 1403 |
| 1404 RECT rcWorkArea; |
| 1405 SystemParametersInfo(SPI_GETWORKAREA, 0, (LPVOID)&rcWorkArea, 0); |
| 1406 if (rcWorkArea.right - pt.x < 150) |
| 1407 { |
| 1408 bRightAlign = TRUE; |
| 1409 pt.x = rcButton.right; |
| 1410 pt.y = rcButton.bottom; |
| 1411 ClientToScreen(hWndToolBar, &pt); |
| 1412 } |
1412 } | 1413 } |
1413 } | 1414 } |
1414 } | 1415 } |
| 1416 else |
| 1417 { |
| 1418 GetCursorPos(&pt); |
| 1419 } |
| 1420 } |
| 1421 |
| 1422 // Display menu |
| 1423 UINT nFlags = 0; |
| 1424 if (bRightAlign) |
| 1425 { |
| 1426 nFlags |= TPM_RIGHTALIGN; |
1415 } | 1427 } |
1416 else | 1428 else |
1417 { | 1429 { |
1418 GetCursorPos(&pt); | 1430 nFlags |= TPM_LEFTALIGN; |
1419 } | 1431 } |
1420 } | |
1421 | 1432 |
1422 // Display menu | 1433 DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags); |
1423 UINT nFlags = 0; | |
1424 if (bRightAlign) | |
1425 { | |
1426 nFlags |= TPM_RIGHTALIGN; | |
1427 } | |
1428 else | |
1429 { | |
1430 nFlags |= TPM_LEFTALIGN; | |
1431 } | |
1432 | 1434 |
1433 DisplayPluginMenu(hMenu, nIDCommand, pt, nFlags); | 1435 return S_OK; |
1434 | 1436 }); |
1435 return S_OK; | |
1436 } | 1437 } |
1437 | 1438 |
1438 ///////////////////////////////////////////////////////////////////////////// | 1439 ///////////////////////////////////////////////////////////////////////////// |
1439 // Window procedures | 1440 // Window procedures |
1440 | 1441 |
1441 LRESULT CALLBACK CPluginClass::NewStatusProc(HWND hWnd, UINT message, WPARAM wPa
ram, LPARAM lParam) | 1442 LRESULT CALLBACK CPluginClass::NewStatusProc(HWND hWnd, UINT message, WPARAM wPa
ram, LPARAM lParam) |
1442 { | 1443 { |
1443 // Find tab | 1444 // Find tab |
1444 CPluginClass *pClass = FindInstance(hWnd); | 1445 CPluginClass *pClass = FindInstance(hWnd); |
1445 if (!pClass) | 1446 if (!pClass) |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1870 } | 1871 } |
1871 } | 1872 } |
1872 } | 1873 } |
1873 | 1874 |
1874 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); | 1875 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); |
1875 } | 1876 } |
1876 | 1877 |
1877 return hTabWnd; | 1878 return hTabWnd; |
1878 | 1879 |
1879 } | 1880 } |
OLD | NEW |