1 /* 2 * PROJECT: ReactOS browseui 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Custom MRU AutoComplete List 5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include "precomp.h" 9 10 CACLCustomMRU::CACLCustomMRU() 11 :m_bDirty(false) 12 { 13 } 14 15 CACLCustomMRU::~CACLCustomMRU() 16 { 17 PersistMRU(); 18 m_Key.Close(); 19 } 20 21 void CACLCustomMRU::PersistMRU() 22 { 23 WCHAR Key[2] = { 0, 0 }; 24 25 if (!m_bDirty) 26 return; 27 m_bDirty = false; 28 29 if (m_Key.m_hKey) 30 { 31 m_Key.SetStringValue(L"MRUList", m_MRUList); 32 for (int Index = 0; Index < m_MRUList.GetLength(); ++Index) 33 { 34 Key[0] = Index + 'a'; 35 m_Key.SetStringValue(Key, m_MRUData[Index]); 36 } 37 } 38 } 39 40 // *** IACLCustomMRU methods *** 41 HRESULT STDMETHODCALLTYPE CACLCustomMRU::Initialize(LPCWSTR pwszMRURegKey, DWORD dwMax) 42 { 43 LSTATUS Status = m_Key.Create(HKEY_CURRENT_USER, pwszMRURegKey); 44 if (Status != ERROR_SUCCESS) 45 return HRESULT_FROM_WIN32(Status); 46 47 m_MRUData.RemoveAll(); 48 dwMax = max(0, dwMax); 49 dwMax = min(29, dwMax); 50 while (dwMax--) 51 m_MRUData.Add(CStringW()); 52 53 WCHAR MRUList[40]; 54 ULONG nChars = _countof(MRUList); 55 56 Status = m_Key.QueryStringValue(L"MRUList", MRUList, &nChars); 57 if (Status != ERROR_SUCCESS) 58 return S_OK; 59 60 if (nChars > 0 && MRUList[nChars-1] == '\0') 61 nChars--; 62 63 if (nChars > (ULONG)m_MRUData.GetSize()) 64 return S_OK; 65 66 for (ULONG n = 0; n < nChars; ++n) 67 { 68 if (MRUList[n] >= 'a' && MRUList[n] <= '}' && m_MRUList.Find(MRUList[n]) < 0) 69 { 70 WCHAR Key[2] = { MRUList[n], NULL }; 71 WCHAR Value[MAX_PATH * 2]; 72 ULONG nValueChars = _countof(Value); 73 74 m_MRUList += MRUList[n]; 75 int Index = MRUList[n] - 'a'; 76 77 if (Index < m_MRUData.GetSize()) 78 { 79 Status = m_Key.QueryStringValue(Key, Value, &nValueChars); 80 if (Status == ERROR_SUCCESS) 81 { 82 m_MRUData[Index] = CStringW(Value, nValueChars); 83 } 84 } 85 } 86 } 87 88 return S_OK; 89 } 90 91 HRESULT STDMETHODCALLTYPE CACLCustomMRU::AddMRUString(LPCWSTR pwszEntry) 92 { 93 ATLASSERT(m_MRUData.GetSize() <= m_MRUList.GetLength()); 94 95 m_bDirty = true; 96 97 CStringW NewElement = pwszEntry; 98 WCHAR Key[2] = { 0, 0 }; 99 int Index = m_MRUData.Find(NewElement); 100 if (Index >= 0) 101 { 102 /* Move the key to the front */ 103 Key[0] = Index + 'a'; 104 m_MRUList.Replace(Key, L""); 105 m_MRUList = Key + m_MRUList; 106 return S_OK; 107 } 108 109 int TotalLen = m_MRUList.GetLength(); 110 if (m_MRUData.GetSize() == TotalLen) 111 { 112 /* Find oldest element, move that to the front */ 113 Key[0] = m_MRUList[TotalLen-1]; 114 m_MRUList = Key + m_MRUList.Left(TotalLen-1); 115 Index = Key[0] - 'a'; 116 } 117 else 118 { 119 /* Find the first empty entry */ 120 for (Index = 0; Index < m_MRUData.GetSize(); ++Index) 121 { 122 if (m_MRUData[Index].IsEmpty()) 123 break; 124 } 125 Key[0] = Index + 'a'; 126 m_MRUList = Key + m_MRUList; 127 } 128 m_MRUData[Index] = NewElement; 129 130 PersistMRU(); 131 return S_OK; 132 } 133 134