From: Mark Jansen Date: Sun, 17 Dec 2017 14:29:30 +0000 (+0100) Subject: [BROWSEUI] Implement ACLCustomMRU. X-Git-Tag: 0.4.9-dev~629 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=ad181d892cc5349bba1ac74378a71d7d3d5258cf;ds=sidebyside [BROWSEUI] Implement ACLCustomMRU. CORE-9281 --- diff --git a/dll/win32/browseui/ACLCustomMRU.cpp b/dll/win32/browseui/ACLCustomMRU.cpp new file mode 100644 index 00000000000..1f0f03f29e1 --- /dev/null +++ b/dll/win32/browseui/ACLCustomMRU.cpp @@ -0,0 +1,133 @@ +/* + * PROJECT: ReactOS browseui + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Custom MRU AutoComplete List + * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org) + */ + +#include "precomp.h" + +CACLCustomMRU::CACLCustomMRU() + :m_bDirty(false) +{ +} + +CACLCustomMRU::~CACLCustomMRU() +{ + PersistMRU(); + m_Key.Close(); +} + +void CACLCustomMRU::PersistMRU() +{ + WCHAR Key[2] = { 0, 0 }; + + if (!m_bDirty) + return; + m_bDirty = false; + + if (m_Key.m_hKey) + { + m_Key.SetStringValue(L"MRUList", m_MRUList); + for (int Index = 0; Index < m_MRUList.GetLength(); ++Index) + { + Key[0] = Index + 'a'; + m_Key.SetStringValue(Key, m_MRUData[Index]); + } + } +} + +// *** IACLCustomMRU methods *** +HRESULT STDMETHODCALLTYPE CACLCustomMRU::Initialize(LPCWSTR pwszMRURegKey, DWORD dwMax) +{ + LSTATUS Status = m_Key.Create(HKEY_CURRENT_USER, pwszMRURegKey); + if (Status != ERROR_SUCCESS) + return HRESULT_FROM_WIN32(Status); + + m_MRUData.RemoveAll(); + dwMax = max(0, dwMax); + dwMax = min(29, dwMax); + while (dwMax--) + m_MRUData.Add(CStringW()); + + WCHAR MRUList[40]; + ULONG nChars = _countof(MRUList); + + Status = m_Key.QueryStringValue(L"MRUList", MRUList, &nChars); + if (Status != ERROR_SUCCESS) + return S_OK; + + if (nChars > 0 && MRUList[nChars-1] == '\0') + nChars--; + + if (nChars > (ULONG)m_MRUData.GetSize()) + return S_OK; + + for (ULONG n = 0; n < nChars; ++n) + { + if (MRUList[n] >= 'a' && MRUList[n] <= '}' && m_MRUList.Find(MRUList[n]) < 0) + { + WCHAR Key[2] = { MRUList[n], NULL }; + WCHAR Value[MAX_PATH * 2]; + ULONG nValueChars = _countof(Value); + + m_MRUList += MRUList[n]; + int Index = MRUList[n] - 'a'; + + if (Index < m_MRUData.GetSize()) + { + Status = m_Key.QueryStringValue(Key, Value, &nValueChars); + if (Status == ERROR_SUCCESS) + { + m_MRUData[Index] = CStringW(Value, nValueChars); + } + } + } + } + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CACLCustomMRU::AddMRUString(LPCWSTR pwszEntry) +{ + ATLASSERT(m_MRUData.GetSize() <= m_MRUList.GetLength()); + + m_bDirty = true; + + CStringW NewElement = pwszEntry; + WCHAR Key[2] = { 0, 0 }; + int Index = m_MRUData.Find(NewElement); + if (Index >= 0) + { + /* Move the key to the front */ + Key[0] = Index + 'a'; + m_MRUList.Replace(Key, L""); + m_MRUList = Key + m_MRUList; + return S_OK; + } + + int TotalLen = m_MRUList.GetLength(); + if (m_MRUData.GetSize() == TotalLen) + { + /* Find oldest element, move that to the front */ + Key[0] = m_MRUList[TotalLen-1]; + m_MRUList = Key + m_MRUList.Left(TotalLen-1); + Index = Key[0] - 'a'; + } + else + { + /* Find the first empty entry */ + for (Index = 0; Index < m_MRUData.GetSize(); ++Index) + { + if (m_MRUData[Index].IsEmpty()) + break; + } + Key[0] = Index + 'a'; + m_MRUList = Key + m_MRUList; + } + m_MRUData[Index] = NewElement; + + PersistMRU(); + return S_OK; +} + diff --git a/dll/win32/browseui/ACLCustomMRU.h b/dll/win32/browseui/ACLCustomMRU.h new file mode 100644 index 00000000000..7aa9c9b2e68 --- /dev/null +++ b/dll/win32/browseui/ACLCustomMRU.h @@ -0,0 +1,41 @@ +/* + * PROJECT: ReactOS browseui + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Custom MRU AutoComplete List + * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org) + */ + +#pragma once + +class CACLCustomMRU : + public CComCoClass, + public CComObjectRootEx, + public IACLCustomMRU +{ +private: + CRegKey m_Key; + CStringW m_MRUList; + CSimpleArray m_MRUData; + bool m_bDirty; + + void PersistMRU(); + +public: + CACLCustomMRU(); + ~CACLCustomMRU(); + + // *** IACLCustomMRU methods *** + virtual HRESULT STDMETHODCALLTYPE Initialize(LPCWSTR pwszMRURegKey, DWORD dwMax); + virtual HRESULT STDMETHODCALLTYPE AddMRUString(LPCWSTR pwszEntry); + +public: + + DECLARE_REGISTRY_RESOURCEID(IDR_ACLCUSTOMMRU) + DECLARE_NOT_AGGREGATABLE(CACLCustomMRU) + + DECLARE_PROTECT_FINAL_CONSTRUCT() + + BEGIN_COM_MAP(CACLCustomMRU) + COM_INTERFACE_ENTRY_IID(IID_IACLCustomMRU, IACLCustomMRU) + END_COM_MAP() +}; diff --git a/dll/win32/browseui/CMakeLists.txt b/dll/win32/browseui/CMakeLists.txt index 45afa685c41..161c45fb599 100644 --- a/dll/win32/browseui/CMakeLists.txt +++ b/dll/win32/browseui/CMakeLists.txt @@ -4,10 +4,15 @@ add_subdirectory(shellbars) set_cpp(WITH_RUNTIME) +add_definitions( + -D_ATL_NO_EXCEPTIONS) + include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl) spec2def(browseui.dll browseui.spec ADD_IMPORTLIB) list(APPEND SOURCE + ACLCustomMRU.cpp + ACLCustomMRU.h aclistisf.cpp aclmulti.cpp addressband.cpp diff --git a/dll/win32/browseui/browseui.cpp b/dll/win32/browseui/browseui.cpp index 68326784ba4..98a94c23696 100644 --- a/dll/win32/browseui/browseui.cpp +++ b/dll/win32/browseui/browseui.cpp @@ -127,6 +127,7 @@ public: BEGIN_OBJECT_MAP(ObjectMap) +OBJECT_ENTRY(CLSID_ACLCustomMRU, CACLCustomMRU) OBJECT_ENTRY(CLSID_AutoComplete, CAutoComplete) OBJECT_ENTRY(CLSID_ACLMulti, CACLMulti) OBJECT_ENTRY(CLSID_ACListISF, CACListISF) diff --git a/dll/win32/browseui/browseui.rc b/dll/win32/browseui/browseui.rc index 6badbc9fb09..bece75e0c5d 100644 --- a/dll/win32/browseui/browseui.rc +++ b/dll/win32/browseui/browseui.rc @@ -46,6 +46,7 @@ IDR_PROGRESSDIALOG REGISTRY "res/progressdialog.rgs" IDR_AUTOCOMPLETE REGISTRY "res/autocomplete.rgs" IDR_ACLISTISF REGISTRY "res/shellautocomplete.rgs" IDR_ISFBAND REGISTRY "res/isfband.rgs" +IDR_ACLCUSTOMMRU REGISTRY "res/custommru.rgs" #include diff --git a/dll/win32/browseui/precomp.h b/dll/win32/browseui/precomp.h index 3303834b139..5ee3ee0745b 100644 --- a/dll/win32/browseui/precomp.h +++ b/dll/win32/browseui/precomp.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ #include "resource.h" +#include "ACLCustomMRU.h" #include "aclistisf.h" #include "aclmulti.h" #include "addressband.h" diff --git a/dll/win32/browseui/res/custommru.rgs b/dll/win32/browseui/res/custommru.rgs new file mode 100644 index 00000000000..a5d12faf5d9 --- /dev/null +++ b/dll/win32/browseui/res/custommru.rgs @@ -0,0 +1,13 @@ +HKCR +{ + NoRemove CLSID + { + ForceRemove {6935DB93-21E8-4CCC-BEB9-9FE3C77A297A} = s 'Custom MRU AutoComplete List' + { + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Apartment' + } + } + } +} diff --git a/dll/win32/browseui/resource.h b/dll/win32/browseui/resource.h index 24303de2290..b974515bf2b 100644 --- a/dll/win32/browseui/resource.h +++ b/dll/win32/browseui/resource.h @@ -103,6 +103,7 @@ #define IDR_AUTOCOMPLETE 141 #define IDR_ACLISTISF 142 #define IDR_ISFBAND 143 +#define IDR_ACLCUSTOMMRU 144 #define IDS_SMALLICONS 12301 #define IDS_LARGEICONS 12302 diff --git a/sdk/include/reactos/browseui_undoc.h b/sdk/include/reactos/browseui_undoc.h index bd6d6fbc81f..4ea2dcf6057 100644 --- a/sdk/include/reactos/browseui_undoc.h +++ b/sdk/include/reactos/browseui_undoc.h @@ -129,6 +129,21 @@ HRESULT WINAPI SHWriteClassesOfCategories(long param8, long paramC, long param10 BOOL WINAPI SHIsExplorerBrowser(void); HRESULT WINAPI SHOpenNewFrame(LPITEMIDLIST pidl, IUnknown *paramC, long param10, DWORD dwFlags); + +#define INTERFACE IACLCustomMRU +DECLARE_INTERFACE_IID_(IACLCustomMRU, IUnknown, "F729FC5E-8769-4F3E-BDB2-D7B50FD2275B") +{ + // *** IUnknown methods *** + STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE; + STDMETHOD_(ULONG, AddRef) (THIS)PURE; + STDMETHOD_(ULONG, Release) (THIS)PURE; + + // *** IACLCustomMRU specific methods *** + STDMETHOD(Initialize) (THIS_ LPCWSTR pwszMRURegKey, DWORD dwMax) PURE; + STDMETHOD(AddMRUString) (THIS_ LPCWSTR pwszEntry) PURE; +}; +#undef INTERFACE + #ifdef __cplusplus } /* extern "C" */ #endif /* defined(__cplusplus) */ diff --git a/sdk/include/reactos/shlguid_undoc.h b/sdk/include/reactos/shlguid_undoc.h index 99dc9ec8e90..aaca7a5f421 100644 --- a/sdk/include/reactos/shlguid_undoc.h +++ b/sdk/include/reactos/shlguid_undoc.h @@ -47,6 +47,8 @@ DEFINE_GUID(CLSID_BrowserBar, 0x9581015C, 0xD08E, 0x11D0, 0x8D, 0x3 DEFINE_GUID(CGID_DefViewFrame, 0x710EB7A1, 0x45ED, 0x11D0, 0x92, 0x4A, 0x00, 0x20, 0xAF, 0xC7, 0xAC, 0x4D); // browseui.dll +DEFINE_GUID(IID_IACLCustomMRU, 0xf729fc5e, 0x8769, 0x4f3e, 0xbd, 0xb2, 0xd7, 0xb5, 0x0f, 0xd2, 0x27, 0x5b); + DEFINE_GUID(CLSID_SH_AddressBand, 0x01E04581, 0x4EEE, 0x11D0, 0xBF, 0xE9, 0x00, 0xAA, 0x00, 0x5B, 0x43, 0x83); DEFINE_GUID(CLSID_AddressEditBox, 0xA08C11D2, 0xA228, 0x11D0, 0x82, 0x5B, 0x00, 0xAA, 0x00, 0x5B, 0x43, 0x83); DEFINE_GUID(IID_IAddressEditBox, 0xA08C11D1, 0xA228, 0x11D0, 0x82, 0x5B, 0x00, 0xAA, 0x00, 0x5B, 0x43, 0x83);