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