From e64d993fa2892d0b710678d854d6a814f2075498 Mon Sep 17 00:00:00 2001 From: "Minha, Jeong" Date: Tue, 9 Jan 2024 00:02:48 +0900 Subject: [PATCH] Feat/ignore annoying cfdib (#599) * add IGNORE_ANNOYING_CF_DIB advanced feature * fix to call GetAvailableTypes only if needed * fix oleacc.dll loading to be once explicitly. --- AdvGeneral.cpp | 13 ++++++++--- Clip.cpp | 5 +++-- CopyThread.cpp | 15 +++++-------- ExternalWindowTracker.cpp | 20 ++++++++++------- ExternalWindowTracker.h | 4 ++++ Options.cpp | 47 ++++++++++++++++++++++++++++----------- Options.h | 10 +++++---- 7 files changed, 75 insertions(+), 39 deletions(-) diff --git a/AdvGeneral.cpp b/AdvGeneral.cpp index caebfc67..dbc6aa44 100644 --- a/AdvGeneral.cpp +++ b/AdvGeneral.cpp @@ -142,6 +142,7 @@ END_MESSAGE_MAP() #define SETTING_FAST_THUMBNAIL_MODE 91 #define SETTING_CLIPBOARD_RESTORE_AFTER_COPY_BUFFER_DELAY 92 #define SETTING_SUPPORT_ALL_TYPES 93 +#define SETTING_IGNORE_ANNOYING_CF_DIB 94 BOOL CAdvGeneral::OnInitDialog() { @@ -181,7 +182,7 @@ BOOL CAdvGeneral::OnInitDialog() AddTrueFalse(pGroupTest, _T("Always show scroll bar"), CGetSetOptions::GetShowScrollBar(), SETTING_ALWAYS_SHOW_SCROLL_BAR); pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Amount of text to save for description"), g_Opt.m_bDescTextSize, _T(""), SETTING_DESC_SIZE)); pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Copy and save clipboard delay (ms)"), (long)CGetSetOptions::GetCopyAndSveDelay(), _T(""), SETTING_COPY_SAVE_DELAY)); - pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Clipboard restore delay after copy buffer sent paste (ms, default: 750))"), (long)(CGetSetOptions::GetDittoRestoreClipboardDelay()), _T(""), SETTING_CLIPBOARD_RESTORE_AFTER_COPY_BUFFER_DELAY)); + pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Clipboard restore delay after copy buffer sent paste (ms, default: 750)"), (long)(CGetSetOptions::GetDittoRestoreClipboardDelay()), _T(""), SETTING_CLIPBOARD_RESTORE_AFTER_COPY_BUFFER_DELAY)); pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Default paste string"), CGetSetOptions::GetDefaultPasteString(), _T(""), SETTING_DEFAULT_PASTE_STRING)); pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Default copy string"), CGetSetOptions::GetDefaultCopyString(), _T(""), SETTING_DEFAULT_COPY_STRING)); @@ -213,6 +214,7 @@ BOOL CAdvGeneral::OnInitDialog() AddTrueFalse(pGroupTest, _T("Hide Ditto on hot key if Ditto is visible"), CGetSetOptions::GetHideDittoOnHotKeyIfAlreadyShown(), SETTING_HIDE_ON_HOTKEY_IF_VISIBLE); pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Ignore copies faster than (ms) (default: 500)"), (long)CGetSetOptions::GetSaveClipDelay(), _T(""), SETTING_IGNORE_FALSE_COPIES_DELAY)); + pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Ignore annoying CF_DIB when a clip is detected as text content"), CGetSetOptions::GetIgnoreAnnoyingCFDIB(), _T("Case insensitive. Recommended option is \"excel.exe; onenote.exe; powerpnt.exe\" "), SETTING_IGNORE_ANNOYING_CF_DIB)); pGroupTest->AddSubItem( new CMFCPropertyGridProperty(_T("Maximum clip size in bytes (0 for no limit)"), g_Opt.m_lMaxClipSizeInBytes, _T(""), SETTING_MAX_CLIP_SIZE)); @@ -240,7 +242,7 @@ BOOL CAdvGeneral::OnInitDialog() AddTrueFalse(pGroupTest, _T("Refresh view after paste"), CGetSetOptions::GetRefreshViewAfterPasting(), SETTING_REFRESH_VIEW_AFTER_PASTE); - pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Save clipboard delay (ms, default: 100))"), (long)(CGetSetOptions::GetProcessDrawClipboardDelay()), _T(""), SETTING_CLIPBOARD_SAVE_DELAY)); + pGroupTest->AddSubItem(new CMFCPropertyGridProperty(_T("Save clipboard delay (ms, default: 100)"), (long)(CGetSetOptions::GetProcessDrawClipboardDelay()), _T(""), SETTING_CLIPBOARD_SAVE_DELAY)); AddTrueFalse(pGroupTest, _T("Save multi-pastes"), CGetSetOptions::GetSaveMultiPaste(), SETTING_SAVE_MULTI_PASTE); @@ -821,7 +823,12 @@ void CAdvGeneral::OnBnClickedOk() CGetSetOptions::SetSupportAllTypes(val); } break; - + case SETTING_IGNORE_ANNOYING_CF_DIB: + if (wcscmp(pNewValue->bstrVal, pOrigValue->bstrVal) != 0) + { + CGetSetOptions::SetIgnoreAnnoyingCFDIB(pNewValue->bstrVal); + } + break; } } } diff --git a/Clip.cpp b/Clip.cpp index da5c9c3f..c4ab81d9 100644 --- a/Clip.cpp +++ b/Clip.cpp @@ -453,9 +453,10 @@ int CClip::LoadFromClipboard(CClipTypes* pClipTypes, bool checkClipboardIgnore, cf.m_cfType = pTypes->ElementAt(i); if (cf.m_cfType == CF_DIB && - g_Opt.m_excludeCF_DIBInExcel && - activeApp.MakeLower() == _T("excel.exe")) + oleData.IsDataAvailable(CF_TEXT) && + g_Opt.GetIgnoreAnnoyingCFDIBSet(TRUE).count(activeApp.MakeLower())) { + Log(StrF(_T("Ignore CF_DIB from %s"), activeApp)); continue; } diff --git a/CopyThread.cpp b/CopyThread.cpp index 8b0812cb..e204c3ac 100644 --- a/CopyThread.cpp +++ b/CopyThread.cpp @@ -71,18 +71,15 @@ void CCopyThread::OnClipboardChange(CString activeWindow, CString activeWindowTi pClip->m_copyReason = theApp.GetCopyReason(); COleDataObjectEx oleData; - std::shared_ptr availableTypes = oleData.GetAvailableTypes(); CClipTypes* pSupportedTypes = m_LocalConfig.m_pSupportedTypes; - //If we are copying from a Ditto Buffer then save all to the database, so when we paste this it will paste - //just like you were using Ctrl-V - if(theApp.m_CopyBuffer.Active()) + // If we are copying from a Ditto Buffer or use advanced option + // then save all to the database, so when we paste this it will paste + // just like you were using Ctrl-V + std::shared_ptr availableTypes; + if (theApp.m_CopyBuffer.Active() || CGetSetOptions::GetSupportAllTypes()) { - Log(_T("LoadFromClipboard - Copy buffer Active Start")); - pSupportedTypes = availableTypes.get(); - Log(_T("LoadFromClipboard - Copy buffer Active End")); - } - else if (CGetSetOptions::GetSupportAllTypes()) { + availableTypes = oleData.GetAvailableTypes(); pSupportedTypes = availableTypes.get(); } diff --git a/ExternalWindowTracker.cpp b/ExternalWindowTracker.cpp index 73a3394a..0a26b60a 100644 --- a/ExternalWindowTracker.cpp +++ b/ExternalWindowTracker.cpp @@ -12,10 +12,20 @@ ExternalWindowTracker::ExternalWindowTracker(void) m_focusWnd = NULL; m_dittoHasFocus = false; m_desktopHasFocus = false; + + m_hOleacc = LoadLibrary(_T("oleacc.dll")); + if (m_hOleacc) + m_AccessibleObjectFromWindow = (AccessibleObjectFromWindow)GetProcAddress(m_hOleacc, "AccessibleObjectFromWindow"); } ExternalWindowTracker::~ExternalWindowTracker(void) { + if (m_hOleacc) + { + FreeLibrary(m_hOleacc); + m_hOleacc = NULL; + m_AccessibleObjectFromWindow = NULL; + } } bool ExternalWindowTracker::TrackActiveWnd(bool force) @@ -479,17 +489,11 @@ CPoint ExternalWindowTracker::FocusCaret() return pt; // trying to get caret for some hard applications like Chrome. - HMODULE hOleacc = LoadLibrary(_T("oleacc.dll")); - if (!hOleacc) - return pt; - - typedef HRESULT(__stdcall *AccessibleObjectFromWindow)(_In_ HWND hwnd, _In_ DWORD dwId, _In_ REFIID riid, _Outptr_ void** ppvObject); - AccessibleObjectFromWindow getObject = (AccessibleObjectFromWindow)GetProcAddress(hOleacc, "AccessibleObjectFromWindow"); - if (!getObject) + if (!m_AccessibleObjectFromWindow) return pt; IAccessible* pIAccessible = NULL; - HRESULT hr = getObject(m_activeWnd, OBJID_CARET, __uuidof(IAccessible), (void**)&pIAccessible); + HRESULT hr = m_AccessibleObjectFromWindow(m_activeWnd, OBJID_CARET, __uuidof(IAccessible), (void**)&pIAccessible); if(hr != S_OK) return pt; diff --git a/ExternalWindowTracker.h b/ExternalWindowTracker.h index 5ba828f8..d8fbe9c4 100644 --- a/ExternalWindowTracker.h +++ b/ExternalWindowTracker.h @@ -27,10 +27,14 @@ class ExternalWindowTracker bool NotifyTrayhWnd(HWND hWnd); protected: + typedef HRESULT(__stdcall *AccessibleObjectFromWindow)(_In_ HWND hwnd, _In_ DWORD dwId, _In_ REFIID riid, _Outptr_ void** ppvObject); + HWND m_activeWnd; HWND m_focusWnd; bool m_dittoHasFocus; bool m_desktopHasFocus; + HMODULE m_hOleacc; + AccessibleObjectFromWindow m_AccessibleObjectFromWindow; protected: bool WaitForActiveWnd(HWND hwndToHaveFocus, int timeout); diff --git a/Options.cpp b/Options.cpp index 980bc8a3..f2df34af 100644 --- a/Options.cpp +++ b/Options.cpp @@ -7,6 +7,8 @@ #include "Path.h" #include "CP_Main.h" #include "ActionEnums.h" +#include "Shared/Tokenizer.h" +#include using namespace nsPath; @@ -69,7 +71,7 @@ BOOL CGetSetOptions::m_showScrollBar = false; CGetSetOptions g_Opt; BOOL CGetSetOptions::m_bShowAlwaysOnTopWarning = TRUE; CRegExFilterHelper CGetSetOptions::m_regexHelper; -BOOL CGetSetOptions::m_excludeCF_DIBInExcel = TRUE; +CString CGetSetOptions::m_ignoreAnnoyingCFDIB = ""; CChaiScriptXml CGetSetOptions::m_copyScripts; CChaiScriptXml CGetSetOptions::m_pasteScripts; long CGetSetOptions::m_tooltipTimeout; @@ -204,7 +206,7 @@ void CGetSetOptions::LoadSettings() m_bEnsureConnectToClipboard = GetEnsureConnectToClipboard(); m_showScrollBar = GetShowScrollBar(); m_bShowAlwaysOnTopWarning = GetShowAlwaysOnTopWarning(); - m_excludeCF_DIBInExcel = GetExcludeCF_DIBInExcel(); + m_ignoreAnnoyingCFDIB = GetIgnoreAnnoyingCFDIB(); m_doubleKeyStrokeTimeout = GetDoubleKeyStrokeTimeout(); m_firstTenHotKeysStart = GetFirstTenHotKeysStart(); m_firstTenHotKeysFontSize = GetFirstTenHotKeysFontSize(); @@ -2700,17 +2702,6 @@ void CGetSetOptions::SetOpenToGroupByActiveExe(int val) SetProfileLong(_T("OpenToGroupByActiveExe"), val); } -BOOL CGetSetOptions::GetExcludeCF_DIBInExcel() -{ - return GetProfileLong(_T("ExcludeCF_DIBInExcel"), TRUE); -} - -void CGetSetOptions::SetExcludeCF_DIBInExcel(int val) -{ - m_excludeCF_DIBInExcel = val; - SetProfileLong(_T("ExcludeCF_DIBInExcel"), val); -} - BOOL CGetSetOptions::GetShowStartupMessage() { return GetProfileLong(_T("ShowStartupMessage"), TRUE); @@ -2993,3 +2984,33 @@ void CGetSetOptions::SetSupportAllTypes(BOOL val) m_refreshViewAfterPasting = val; SetProfileLong("SupportAllTypes", val); } + +CString CGetSetOptions::GetIgnoreAnnoyingCFDIB(BOOL useCache) +{ + if (useCache) + return m_ignoreAnnoyingCFDIB; + else + return GetProfileString("IgnoreAnnoyingCFDIB", _T("")); +} + +void CGetSetOptions::SetIgnoreAnnoyingCFDIB(CString val) +{ + m_ignoreAnnoyingCFDIB = val; + SetProfileString("IgnoreAnnoyingCFDIB", val); +} + +std::set CGetSetOptions::GetIgnoreAnnoyingCFDIBSet(BOOL useCache) +{ + CString rawString = CGetSetOptions::GetIgnoreAnnoyingCFDIB(useCache); + std:set processSet; + CTokenizer token(rawString, _T(";")); + CString process; + while (token.Next(process)) + { + if (process == "") + continue; + processSet.insert(process.MakeLower()); + } + + return processSet; +} diff --git a/Options.h b/Options.h index 8082ccbb..0e4b4533 100644 --- a/Options.h +++ b/Options.h @@ -3,6 +3,7 @@ #include "Theme.h" #include "RegExFilterHelper.h" #include "ChaiScriptXml.h" +#include #define MAX_SEND_CLIENTS 15 class CSendClients @@ -585,10 +586,6 @@ class CGetSetOptions static BOOL GetOpenToGroupByActiveExe(); static void SetOpenToGroupByActiveExe(int val); - static BOOL m_excludeCF_DIBInExcel; - static BOOL GetExcludeCF_DIBInExcel(); - static void SetExcludeCF_DIBInExcel(int val); - static BOOL GetShowStartupMessage(); static void SetShowStartupMessage(int val); @@ -680,6 +677,11 @@ class CGetSetOptions static BOOL m_supportAllTypes; static BOOL GetSupportAllTypes(); static void SetSupportAllTypes(BOOL val); + + static CString GetIgnoreAnnoyingCFDIB(BOOL useCache = FALSE); + static CString m_ignoreAnnoyingCFDIB; + static void SetIgnoreAnnoyingCFDIB(CString val); + static std::set GetIgnoreAnnoyingCFDIBSet(BOOL useCache = FALSE); }; // global for easy access and for initialization of fast access variables