Monthly Archives: January 2014

Auto completion for current directory

Since Windows 200 it is possible to have auto completion for edit boxes which searches the file system and presents a drop down list with the current files. There is a simple helper function to enable this feature: SHAutoComplete

But this function only offers a simple interface to the more complex COM interface IAutoComplete.

While the “SHAutoComplete” is sufficent, it will not work if you want to have auto completion for files in the current directory. For this feature, you need to use the native COM interface:
For more info see also: Using Autocomplete

Here is an example of enabling auto completion for the file system, including the current directory:

AutoComplete01

HRESULT EnableAutoCompleteWithCurrentDirectory(HWND hWndEdit)
{
  AUTOCOMPLETELISTOPTIONS acloOptions = ACLO_NONE;
  AUTOCOMPLETEOPTIONS acoOptions = ACO_AUTOSUGGEST;

  IAutoComplete *pac;
  HRESULT hr = CoCreateInstance(
    CLSID_AutoComplete, NULL,  CLSCTX_INPROC_SERVER,
    __uuidof(pac), reinterpret_cast<void**>(&pac));
  if (FAILED(hr))
  {
    return hr;
  }

  IUnknown *punkSource;
  hr = CoCreateInstance(
    CLSID_ACListISF, NULL, CLSCTX_INPROC_SERVER,
    __uuidof(punkSource), reinterpret_cast<void**>(&punkSource));
  if (FAILED(hr))
  {
    pac->Release();
    return hr;
  }

  // Get current directory
  wchar_t szCurDir[MAX_PATH];
  GetCurrentDirectoryW(MAX_PATH, szCurDir);

  IACList2 *pal2;
  hr = punkSource->QueryInterface(__uuidof(pal2), reinterpret_cast<void**>(&pal2));
  if (SUCCEEDED(hr))
  {
    if (acloOptions != ACLO_NONE)
    {
      hr = pal2->SetOptions(acloOptions);
    }

    ICurrentWorkingDirectory *pcwd;
    hr = pal2->QueryInterface(__uuidof(pcwd), reinterpret_cast<void**>(&pcwd));    
    if (SUCCEEDED(hr))
    {
        hr = pcwd->SetDirectory(szCurDir);
        pcwd->Release();
    }

    pal2->Release();
  }

  hr = pac->Init(hWndEdit, punkSource, NULL, NULL);

  if (acoOptions != ACO_NONE)
  {
    IAutoComplete2 *pac2;
    HRESULT hr2 = pac->QueryInterface(__uuidof(pac2), reinterpret_cast<void**>(&pac2));
    if (SUCCEEDED(hr2))
    {
        hr2 = pac2->SetOptions(acoOptions);
        pac2->Release();
    }
  }

  punkSource->Release();
  pac->Release();
  return hr;
}

You can enable the auto completion for a control by calling this function:

EnableAutoCompleteWithCurrentDirectory(m_txtBox1.m_hWnd);