foobar2000 SDK  2015-01-14
AutoComplete.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 
3 namespace {
4 
5 class CEnumString : public IEnumString {
6 public:
8  CEnumString(const t_data & in) : m_data(in) {m_walk = m_data.first();}
9  CEnumString() {}
10 
11  void AddString(const TCHAR * in) {
12  m_data.insert_last()->set_data_fromptr(in, _tcslen(in) + 1);
13  m_walk = m_data.first();
14  }
15  void AddStringU(const char * in, t_size len) {
16  pfc::array_t<TCHAR> & arr = * m_data.insert_last();
19  m_walk = m_data.first();
20  }
21  void AddStringU(const char * in) {
22  pfc::array_t<TCHAR> & arr = * m_data.insert_last();
25  m_walk = m_data.first();
26  }
27  void ResetStrings() {m_walk.invalidate(); m_data.remove_all();}
28 
30  COM_QI_BEGIN()
31  COM_QI_ENTRY(IUnknown)
32  COM_QI_ENTRY(IEnumString)
33  COM_QI_END()
34 
35  HRESULT STDMETHODCALLTYPE Next( ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched) {
36  if (rgelt == NULL) return E_INVALIDARG;
37  ULONG done = 0;
38  while( done < celt && m_walk.is_valid()) {
39  rgelt[done] = CoStrDup(m_walk->get_ptr());
40  ++m_walk; ++done;
41  }
42  if (pceltFetched != NULL) *pceltFetched = done;
43  return done == celt ? S_OK : S_FALSE;
44  }
45 
46  static TCHAR * CoStrDup(const TCHAR * in) {
47  const size_t lenBytes = (_tcslen(in) + 1) * sizeof(TCHAR);
48  TCHAR * out = reinterpret_cast<TCHAR*>(CoTaskMemAlloc(lenBytes));
49  if (out) memcpy(out, in, lenBytes);
50  return out;
51  }
52 
53  HRESULT STDMETHODCALLTYPE Skip(ULONG celt) {
54  while(celt > 0) {
55  if (m_walk.is_empty()) return S_FALSE;
56  --celt; ++m_walk;
57  }
58  return S_OK;
59  }
60 
61  HRESULT STDMETHODCALLTYPE Reset() {
62  m_walk = m_data.first();
63  return S_OK;
64  }
65 
66  HRESULT STDMETHODCALLTYPE Clone(IEnumString **ppenum) {
67  *ppenum = new TImpl(*this); return S_OK;
68  }
69 private:
70  t_data m_data;
72 };
73 class CACList_History : public CEnumString {
74 public:
75  CACList_History(cfg_dropdown_history_mt * var) : m_var(var) {Reset();}
77 
78  HRESULT STDMETHODCALLTYPE Reset() {
79  /*if (core_api::assert_main_thread())*/ {
80  ResetStrings();
81  pfc::string8 state; m_var->get_state(state);
82  for(const char * walk = state;;) {
83  const char * next = strchr(walk, cfg_dropdown_history_mt::separator);
84  t_size len = (next != NULL) ? next - walk : ~0;
85  AddStringU(walk, len);
86  if (next == NULL) break;
87  walk = next + 1;
88  }
89  }
90  return __super::Reset();
91  }
92 
93  HRESULT STDMETHODCALLTYPE Clone(IEnumString **ppenum) {
94  *ppenum = new TImpl(*this); return S_OK;
95  }
96 
97 private:
98  cfg_dropdown_history_mt * const m_var;
99 };
100 }
101 
102 HRESULT InitializeSimpleAC(HWND edit, IUnknown * vals, DWORD opts) {
104  HRESULT hr;
105  hr = CoCreateInstance(CLSID_AutoComplete, NULL, CLSCTX_ALL, IID_IAutoComplete, (void**)ac.receive_ptr());
106  if (FAILED(hr)) {
107  PFC_ASSERT(!"Should not get here - CoCreateInstance/IAutoComplete fail!"); return hr;
108  }
109  hr = ac->Init(edit, vals, NULL, NULL);
110  if (FAILED(hr)) {
111  PFC_ASSERT(!"Should not get here - ac->Init fail!"); return hr;
112  }
113 
115  hr = ac->QueryInterface( ac2.receive_ptr() );
116  if (FAILED(hr)) {
117  PFC_ASSERT(!"Should not get here - ac->QueryInterface fail!"); return hr;
118  }
119  hr = ac2->SetOptions(opts);
120  if (FAILED(hr)) {
121  PFC_ASSERT(!"Should not get here - ac2->SetOptions fail!"); return hr;
122  }
123  return S_OK;
124 }
125 
128  while(valueEnum.is_valid()) {
129  acl->AddStringU(*valueEnum); ++valueEnum;
130  }
131  return acl;
132 }
135  while(valueEnum.is_valid()) {
136  acl->AddStringU(*valueEnum); ++valueEnum;
137  }
138  return acl;
139 }
142  while(valueEnum.is_valid()) {
143  acl->AddStringU(valueEnum->ptr()); ++valueEnum;
144  }
145  return acl;
146 }
147 
149  return new CEnumString::TImpl();
150 }
151 
152 void CreateACList_AddItem(IUnknown * theList, const char * item) {
153  static_cast<CEnumString*>(theList)->AddStringU( item );
154 }
155 
156 HRESULT InitializeEditAC(HWND edit, pfc::const_iterator<pfc::string8> valueEnum, DWORD opts) {
157  pfc::com_ptr_t<IUnknown> acl = CreateACList(valueEnum);
158  return InitializeSimpleAC(edit, acl.get_ptr(), opts);
159 }
160 HRESULT InitializeEditAC(HWND edit, const char * values, DWORD opts) {
162  for(const char * walk = values;;) {
163  const char * next = strchr(walk, cfg_dropdown_history_mt::separator);
164  if (next == NULL) {acl->AddStringU(walk, ~0); break;}
165  acl->AddStringU(walk, next - walk);
166  walk = next + 1;
167  }
168  return InitializeSimpleAC(edit, acl.get_ptr(), opts);
169 }
170 
171 HRESULT InitializeDropdownAC(HWND comboBox, cfg_dropdown_history_mt & var, const char * initVal) {
172  var.on_init(comboBox, initVal);
173  COMBOBOXINFO ci = {}; ci.cbSize = sizeof(ci);
174  if (!GetComboBoxInfo(comboBox, &ci)) {
175  PFC_ASSERT(!"Should not get here - GetComboBoxInfo fail!");
176  return E_FAIL;
177  }
179  return InitializeSimpleAC(ci.hwndItem, acl.get_ptr(), ACO_AUTOAPPEND|ACO_AUTOSUGGEST);
180 }
const t_item * get_ptr() const
Definition: array.h:213
::pfc::const_iterator< t_item > const_iterator
Definition: chain_list_v2.h:31
t_size estimate_utf8_to_wide(const char *p_in)
T * get_ptr() const
Definition: com_ptr_t.h:49
void CreateACList_AddItem(IUnknown *theList, const char *item)
T ** receive_ptr()
Definition: com_ptr_t.h:73
Differences between chain_list_v2_t<> and old chain_list_t<>: Iterators pointing to removed items as...
Definition: chain_list_v2.h:26
bool is_valid() const
Definition: iterators.h:24
const char * ptr() const
Definition: stringNew.h:124
pfc::com_ptr_t< IUnknown > CreateACList(pfc::const_iterator< pfc::string8 > valueEnum)
size_t t_size
Definition: int_types.h:48
t_size convert_utf8_to_wide(wchar_t *p_out, t_size p_out_size, const char *p_in, t_size p_in_size)
Converts UTF-8 characters to wide character.
void set_size(t_size p_size)
Definition: array.h:104
t_size convert_utf8_to_wide_unchecked(wchar_t *p_out, const char *p_in)
Simple implementation of a COM reference counter. The initial reference count is zero, so it can be used with pfc::com_ptr_t<> with plain operator=/constructor rather than attach().
Definition: win-objects.h:243
HRESULT InitializeEditAC(HWND edit, pfc::const_iterator< pfc::string8 > valueEnum, DWORD opts)
HRESULT InitializeSimpleAC(HWND edit, IUnknown *vals, DWORD opts)
void on_init(HWND ctrl, const char *initVal)
HRESULT InitializeDropdownAC(HWND comboBox, cfg_dropdown_history_mt &var, const char *initVal)
t_size get_size() const
Definition: array.h:130