ReactOS 0.4.15-dev-5666-gc548b97
autocomp.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS shlwapi
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Implement SHAutoComplete
5 * COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6 */
7#include <windef.h>
8#include <shlobj.h>
9#include <shlwapi.h>
10#include <browseui_undoc.h>
11#include <shlwapi_undoc.h>
12#include <shlguid_undoc.h>
13#include <atlbase.h>
14#include <atlcom.h>
15#include <wine/debug.h>
16
18
19static HRESULT
20AutoComplete_AddMRU(CComPtr<IObjMgr> pManager, LPCWSTR pszKey)
21{
22 CComPtr<IACLCustomMRU> pMRU; // Create an MRU list
23 HRESULT hr = CoCreateInstance(CLSID_ACLCustomMRU, NULL, CLSCTX_INPROC_SERVER,
24 IID_IACLCustomMRU, (LPVOID *)&pMRU);
25 if (FAILED(hr))
26 {
27 ERR("CoCreateInstance(CLSID_ACLMRU) failed with 0x%08lX\n", hr);
28 return hr;
29 }
30
31 hr = pMRU->Initialize(pszKey, 'z' - 'a' + 1); // Load the list from registry
32 if (FAILED(hr))
33 {
34 ERR("pMRU->Initialize(%ls) failed with 0x%08lX\n", pszKey, hr);
35 return hr;
36 }
37
38 hr = pManager->Append(pMRU); // Add to the manager
39 if (FAILED(hr))
40 ERR("pManager->Append for '%ls' failed with 0x%08lX\n", pszKey, hr);
41 return hr;
42}
43
44static HRESULT
45IUnknown_AddOptions(CComPtr<IUnknown> punk, DWORD dwACLO)
46{
47 CComPtr<IACList2> pList;
48 HRESULT hr = punk->QueryInterface(IID_IACList2, (LPVOID *)&pList);
49 if (FAILED(hr))
50 {
51 ERR("punk->QueryInterface failed: 0x%08lX\n", hr);
52 return hr;
53 }
54
55 DWORD dwOptions = 0;
56 pList->GetOptions(&dwOptions);
57 dwOptions |= dwACLO;
58 hr = pList->SetOptions(dwOptions);
59 if (FAILED(hr))
60 ERR("pList->SetOptions failed: 0x%08lX\n", hr);
61 return hr;
62}
63
64static CComPtr<IUnknown>
66{
67 // Create a multiple list (with IEnumString interface)
68 CComPtr<IUnknown> pList;
69 HRESULT hr = CoCreateInstance(CLSID_ACLMulti, NULL, CLSCTX_INPROC_SERVER,
71 if (FAILED(hr)) // Failed to create the list
72 {
73 ERR("CoCreateInstance(CLSID_ACLMulti) failed with 0x%08lX\n", hr);
74 return NULL;
75 }
76
77 CComPtr<IObjMgr> pManager; // This is the manager of the multiple list
78 hr = pList->QueryInterface(IID_IObjMgr, (LPVOID *)&pManager);
79 if (FAILED(hr)) // Failed to get interface
80 {
81 ERR("pList->QueryInterface failed: 0x%08lX\n", hr);
82 return NULL;
83 }
84
85 if (dwSHACF & SHACF_URLMRU)
86 {
87 // The MRU (Most-Recently-Used) lists (with IEnumString interface)
88#define RUN_MRU_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU"
89#define TYPED_URLS_KEY L"Software\\Microsoft\\Internet Explorer\\TypedURLs"
92 }
93
94 if (dwSHACF & SHACF_URLHISTORY)
95 {
96 // The history list (with IEnumString interface)
97 CComPtr<IUnknown> pHistory;
98 hr = CoCreateInstance(CLSID_ACLHistory, NULL, CLSCTX_INPROC_SERVER,
99 IID_IUnknown, (LPVOID *)&pHistory);
100 if (SUCCEEDED(hr))
101 {
102 pManager->Append(pHistory); // Add to the manager
103 // Add ACLO_* options
104 IUnknown_AddOptions(pHistory, dwACLO);
105 }
106 else
107 {
108 ERR("CLSID_ACLHistory hr:%08lX\n", hr);
109 }
110 }
111
113 {
114 // The filesystem list (with IEnumString interface)
115 CComPtr<IUnknown> pISF;
116 hr = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_INPROC_SERVER,
117 IID_IUnknown, (LPVOID *)&pISF);
118 if (SUCCEEDED(hr))
119 {
120 pManager->Append(pISF); // Add to the manager
121 // Add ACLO_* options
122 IUnknown_AddOptions(pISF, dwACLO);
123 }
124 else
125 {
126 ERR("CLSID_ACListISF hr:%08lX\n", hr);
127 }
128 }
129
130 return pList; // The list
131}
132
133static VOID
135 IN OUT LPDWORD pdwSHACF,
136 OUT LPDWORD pdwACO,
137 OUT LPDWORD pdwACLO)
138{
139#define AUTOCOMPLETE_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoComplete"
140 DWORD dwSHACF = *pdwSHACF, dwACO = 0, dwACLO = 0;
141 if (dwSHACF == SHACF_DEFAULT)
142 dwSHACF = SHACF_FILESYSTEM | SHACF_URLALL;
143
144 if (!(dwSHACF & SHACF_AUTOAPPEND_FORCE_OFF) &&
145 ((dwSHACF & SHACF_AUTOAPPEND_FORCE_ON) ||
146 SHRegGetBoolUSValueW(AUTOCOMPLETE_KEY, L"Append Completion", FALSE, FALSE)))
147 {
148 dwACO |= ACO_AUTOAPPEND;
149 }
150
151 if (!(dwSHACF & SHACF_AUTOSUGGEST_FORCE_OFF) &&
152 ((dwSHACF & SHACF_AUTOSUGGEST_FORCE_ON) ||
154 {
155 dwACO |= ACO_AUTOSUGGEST;
156 }
157
158 if (dwSHACF & SHACF_FILESYS_DIRS)
159 dwACLO |= ACLO_FILESYSDIRS;
160 if (dwSHACF & SHACF_FILESYS_ONLY)
161 dwACLO |= ACLO_FILESYSONLY;
162
163 static BOOL s_bAlwaysUseTab = 99;
164 if (s_bAlwaysUseTab == 99)
165 s_bAlwaysUseTab = SHRegGetBoolUSValueW(AUTOCOMPLETE_KEY, L"Always Use Tab", FALSE, FALSE);
166
167 if (s_bAlwaysUseTab || (dwSHACF & SHACF_USETAB))
168 dwACO |= ACO_USETAB;
169
171 dwACO |= ACO_RTLREADING;
172
173 *pdwSHACF = dwSHACF;
174 *pdwACO = dwACO;
175 *pdwACLO = dwACLO;
176}
177
178/*************************************************************************
179 * SHAutoComplete [SHLWAPI.@]
180 *
181 * Enable auto-completion for an edit control.
182 *
183 * PARAMS
184 * hwndEdit [I] Handle of control to enable auto-completion for
185 * dwFlags [I] SHACF_ flags from "shlwapi.h"
186 *
187 * RETURNS
188 * Success: S_OK. Auto-completion is enabled for the control.
189 * Failure: An HRESULT error code indicating the error.
190 */
192{
193 TRACE("SHAutoComplete(%p, 0x%lX)\n", hwndEdit, dwFlags);
194
195 DWORD dwSHACF = dwFlags, dwACO = 0, dwACLO = 0;
196 AutoComplete_AdaptFlags(hwndEdit, &dwSHACF, &dwACO, &dwACLO);
197
198 // Load the list (with IEnumString interface)
199 CComPtr<IUnknown> pList = AutoComplete_LoadList(dwSHACF, dwACLO);
200 if (!pList)
201 {
202 ERR("Out of memory\n");
203 return E_OUTOFMEMORY;
204 }
205
206 // Create an auto-completion (IAutoComplete2)
207 CComPtr<IAutoComplete2> pAC2;
208 HRESULT hr = CoCreateInstance(CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER,
209 IID_IAutoComplete2, (LPVOID *)&pAC2);
210 if (FAILED(hr))
211 {
212 ERR("CoCreateInstance(CLSID_AutoComplete) failed: 0x%lX\n", hr);
213 return hr;
214 }
215
216 // Keep the DLLs of CLSID_ACListISF and CLSID_AutoComplete loaded
217 hr = E_FAIL;
218 if (SHPinDllOfCLSID(CLSID_ACListISF) && SHPinDllOfCLSID(CLSID_AutoComplete))
219 {
220 // Initialize IAutoComplete2 for auto-completion
221 hr = pAC2->Init(hwndEdit, pList, NULL, NULL);
222 if (SUCCEEDED(hr))
223 pAC2->SetOptions(dwACO); // Set ACO_* flags
224 else
225 ERR("IAutoComplete2::Init failed: 0x%lX\n", hr);
226 }
227
228 return hr;
229}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
const GUID IID_IUnknown
#define ERR(fmt,...)
Definition: debug.h:110
virtual _Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
Definition: fxobject.cpp:255
HWND hwndEdit
Definition: combotst.c:65
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HMODULE WINAPI SHPinDllOfCLSID(REFIID refiid)
Definition: ordinal.c:2488
BOOL WINAPI SHRegGetBoolUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, BOOL fIgnoreHKCU, BOOL fDefault)
Definition: reg.c:770
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxChildList * pList
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define L(x)
Definition: ntvdm.h:50
HRESULT hr
Definition: shlfolder.c:183
#define ACLO_FILESYSDIRS
Definition: shlobj.h:745
#define ACLO_FILESYSONLY
Definition: shlobj.h:744
HRESULT WINAPI SHAutoComplete(HWND hwndEdit, DWORD dwFlags)
Definition: autocomp.cpp:191
#define AUTOCOMPLETE_KEY
#define RUN_MRU_KEY
#define TYPED_URLS_KEY
static VOID AutoComplete_AdaptFlags(IN HWND hwndEdit, IN OUT LPDWORD pdwSHACF, OUT LPDWORD pdwACO, OUT LPDWORD pdwACLO)
Definition: autocomp.cpp:134
static HRESULT IUnknown_AddOptions(CComPtr< IUnknown > punk, DWORD dwACLO)
Definition: autocomp.cpp:45
static CComPtr< IUnknown > AutoComplete_LoadList(DWORD dwSHACF, DWORD dwACLO)
Definition: autocomp.cpp:65
static HRESULT AutoComplete_AddMRU(CComPtr< IObjMgr > pManager, LPCWSTR pszKey)
Definition: autocomp.cpp:20
#define SHACF_FILESYSTEM
Definition: shlwapi.h:1912
#define SHACF_AUTOSUGGEST_FORCE_ON
Definition: shlwapi.h:1919
#define SHACF_URLMRU
Definition: shlwapi.h:1914
#define SHACF_URLHISTORY
Definition: shlwapi.h:1913
#define SHACF_AUTOAPPEND_FORCE_ON
Definition: shlwapi.h:1921
#define SHACF_DEFAULT
Definition: shlwapi.h:1911
#define SHACF_FILESYS_ONLY
Definition: shlwapi.h:1917
#define SHACF_FILESYS_DIRS
Definition: shlwapi.h:1918
#define SHACF_AUTOAPPEND_FORCE_OFF
Definition: shlwapi.h:1922
#define SHACF_USETAB
Definition: shlwapi.h:1916
#define SHACF_URLALL
Definition: shlwapi.h:1915
#define SHACF_AUTOSUGGEST_FORCE_OFF
Definition: shlwapi.h:1920
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwOptions
Definition: solitaire.cpp:24
uint32_t * LPDWORD
Definition: typedefs.h:59
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define WINAPI
Definition: msvc.h:6
#define WS_EX_LAYOUTRTL
Definition: winuser.h:390
#define GetWindowLongPtrW
Definition: winuser.h:4819
#define GWL_EXSTYLE
Definition: winuser.h:845
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185