https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ad181d892cc5349bba1ac74378a71d7d3d5258cf

commit ad181d892cc5349bba1ac74378a71d7d3d5258cf
Author: Mark Jansen <[email protected]>
AuthorDate: Sun Dec 17 15:29:30 2017 +0100

    [BROWSEUI] Implement ACLCustomMRU.
    CORE-9281
---
 dll/win32/browseui/ACLCustomMRU.cpp  | 133 +++++++++++++++++++++++++++++++++++
 dll/win32/browseui/ACLCustomMRU.h    |  41 +++++++++++
 dll/win32/browseui/CMakeLists.txt    |   5 ++
 dll/win32/browseui/browseui.cpp      |   1 +
 dll/win32/browseui/browseui.rc       |   1 +
 dll/win32/browseui/precomp.h         |   2 +
 dll/win32/browseui/res/custommru.rgs |  13 ++++
 dll/win32/browseui/resource.h        |   1 +
 sdk/include/reactos/browseui_undoc.h |  15 ++++
 sdk/include/reactos/shlguid_undoc.h  |   2 +
 10 files changed, 214 insertions(+)

diff --git a/dll/win32/browseui/ACLCustomMRU.cpp 
b/dll/win32/browseui/ACLCustomMRU.cpp
new file mode 100644
index 0000000000..1f0f03f29e
--- /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 ([email protected])
+ */
+
+#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 0000000000..7aa9c9b2e6
--- /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 ([email protected])
+ */
+
+#pragma once
+
+class CACLCustomMRU :
+    public CComCoClass<CACLCustomMRU, &CLSID_ACLCustomMRU>,
+    public CComObjectRootEx<CComMultiThreadModelNoCS>,
+    public IACLCustomMRU
+{
+private:
+    CRegKey m_Key;
+    CStringW m_MRUList;
+    CSimpleArray<CStringW> 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 45afa685c4..161c45fb59 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 68326784ba..98a94c2369 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 6badbc9fb0..bece75e0c5 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 <reactos/manifest_dll.rc>
 
diff --git a/dll/win32/browseui/precomp.h b/dll/win32/browseui/precomp.h
index 3303834b13..5ee3ee0745 100644
--- a/dll/win32/browseui/precomp.h
+++ b/dll/win32/browseui/precomp.h
@@ -22,6 +22,7 @@
 #include <atlcom.h>
 #include <atlwin.h>
 #include <atlsimpcoll.h>
+#include <atlstr.h>
 #include <undocuser.h>
 #include <perhist.h>
 #include <exdispid.h>
@@ -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 0000000000..a5d12faf5d
--- /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 24303de229..b974515bf2 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 bd6d6fbc81..4ea2dcf605 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 99dc9ec8e9..aaca7a5f42 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);

Reply via email to