xref: /reactos/dll/win32/comdlg32/autocomp.cpp (revision 9393fc32)
1 /*
2  * PROJECT:     ReactOS Common Dialogs
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Implement auto-completion for comdlg32
5  * COPYRIGHT:   Copyright 2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6  */
7 #include "precomp.h"
8 
9 WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
10 
11 EXTERN_C HRESULT
12 DoInitAutoCompleteWithCWD(FileOpenDlgInfos *pInfo, HWND hwndEdit)
13 {
14     pInfo->pvCWD = pInfo->pvDropDown = pInfo->pvACList = NULL;
15 
16     WCHAR szClass[32];
17     GetClassNameW(hwndEdit, szClass, _countof(szClass));
18     if (lstrcmpiW(szClass, WC_COMBOBOXW) == 0)
19     {
20         COMBOBOXINFO info = { sizeof(info) };
21         GetComboBoxInfo(hwndEdit, &info);
22         hwndEdit = info.hwndItem;
23     }
24     else if (lstrcmpiW(szClass, WC_COMBOBOXEXW) == 0)
25     {
26         hwndEdit = (HWND)SendMessageW(hwndEdit, CBEM_GETEDITCONTROL, 0, 0);
27     }
28 
29     IACList2 *pACList = NULL;
30     HRESULT hr = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_INPROC_SERVER,
31                                   IID_IACList2, reinterpret_cast<LPVOID *>(&pACList));
32     if (FAILED(hr))
33     {
34         TRACE("CoCreateInstance(CLSID_ACListISF): 0x%08lX\n", hr);
35         return hr;
36     }
37     pInfo->pvACList = static_cast<LPVOID>(pACList);
38 
39     IAutoComplete2 *pAC = NULL;
40     hr = CoCreateInstance(CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER,
41                           IID_IAutoComplete2, reinterpret_cast<LPVOID *>(&pAC));
42     if (SUCCEEDED(hr))
43     {
44         pAC->Init(hwndEdit, pACList, NULL, NULL);
45         pAC->SetOptions(ACO_AUTOSUGGEST);
46         pAC->QueryInterface(IID_IAutoCompleteDropDown, &pInfo->pvDropDown);
47         pAC->Release();
48     }
49     else
50     {
51         TRACE("CoCreateInstance(CLSID_AutoComplete): 0x%08lX\n", hr);
52         pACList->Release();
53         pInfo->pvACList = NULL;
54         return hr;
55     }
56 
57     pACList->QueryInterface(IID_ICurrentWorkingDirectory, &pInfo->pvCWD);
58 
59     return hr;
60 }
61 
62 EXTERN_C HRESULT
63 DoUpdateAutoCompleteWithCWD(const FileOpenDlgInfos *info, LPCITEMIDLIST pidl)
64 {
65     FileOpenDlgInfos *pInfo = const_cast<FileOpenDlgInfos*>(info);
66     if (!pInfo)
67         return E_POINTER;
68 
69     ICurrentWorkingDirectory* pCWD =
70         reinterpret_cast<ICurrentWorkingDirectory*>(pInfo->pvCWD);
71 
72     IAutoCompleteDropDown* pDropDown =
73         reinterpret_cast<IAutoCompleteDropDown*>(pInfo->pvDropDown);
74 
75     IACList2* pACList = static_cast<IACList2*>(pInfo->pvACList);
76 
77     WCHAR szPath[MAX_PATH];
78     if (!pidl || !SHGetPathFromIDListW(pidl, szPath))
79     {
80         GetCurrentDirectoryW(_countof(szPath), szPath);
81     }
82 
83     if (pCWD)
84         pCWD->SetDirectory(szPath);
85     if (pDropDown)
86         pDropDown->ResetEnumerator();
87     if (pACList)
88         pACList->Expand(L"");
89 
90     return S_OK;
91 }
92 
93 EXTERN_C HRESULT
94 DoReleaseAutoCompleteWithCWD(FileOpenDlgInfos *pInfo)
95 {
96     if (!pInfo)
97         return E_POINTER;
98 
99     ICurrentWorkingDirectory* pCWD =
100         reinterpret_cast<ICurrentWorkingDirectory*>(pInfo->pvCWD);
101     if (pCWD)
102         pCWD->Release();
103 
104     IAutoCompleteDropDown* pDropDown =
105         reinterpret_cast<IAutoCompleteDropDown*>(pInfo->pvDropDown);
106     if (pDropDown)
107         pDropDown->Release();
108 
109     IACList2 *pACList = static_cast<IACList2*>(pInfo->pvACList);
110     if (pACList)
111         pACList->Release();
112 
113     pInfo->pvCWD = pInfo->pvDropDown = pInfo->pvACList = NULL;
114     return S_OK;
115 }
116