1 /* 2 * AutoComplete interfaces implementation. 3 * 4 * Copyright 2004 Maxime Bellengé <maxime.bellenge@laposte.net> 5 * Copyright 2009 Andrew Hill 6 * Copyright 2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 21 */ 22 #pragma once 23 24 #include <atltypes.h> 25 #include <ui/rosctrls.h> 26 27 class CACListView; 28 class CACScrollBar; 29 class CACSizeBox; 30 class CAutoComplete; 31 32 ////////////////////////////////////////////////////////////////////////////// 33 // CACListView --- auto-completion list control 34 35 class CACListView : public CWindowImpl<CACListView, CListView> 36 { 37 public: 38 CAutoComplete* m_pDropDown; 39 INT m_cyItem; 40 static LPCWSTR GetWndClassName() { return WC_LISTVIEW; } 41 42 CACListView(); 43 HWND Create(HWND hwndParent); 44 VOID SetFont(HFONT hFont); 45 46 INT GetVisibleCount(); 47 CStringW GetItemText(INT iItem); 48 INT ItemFromPoint(INT x, INT y); 49 50 INT GetCurSel(); 51 VOID SetCurSel(INT iItem); 52 VOID SelectHere(INT x, INT y); 53 54 protected: 55 // message map 56 BEGIN_MSG_MAP(CACListView) 57 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) 58 MESSAGE_HANDLER(WM_LBUTTONUP, OnButtonUp) 59 MESSAGE_HANDLER(WM_MBUTTONDOWN, OnMRButtonDown) 60 MESSAGE_HANDLER(WM_MBUTTONUP, OnButtonUp) 61 MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel) 62 MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest) 63 MESSAGE_HANDLER(WM_RBUTTONDOWN, OnMRButtonDown) 64 MESSAGE_HANDLER(WM_RBUTTONUP, OnButtonUp) 65 END_MSG_MAP() 66 // message handlers 67 LRESULT OnButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 68 LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 69 LRESULT OnMRButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 70 LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 71 LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 72 }; 73 74 ////////////////////////////////////////////////////////////////////////////// 75 // CACScrollBar --- auto-completion scrollbar control 76 77 class CACScrollBar : public CWindowImpl<CACScrollBar> 78 { 79 public: 80 CAutoComplete* m_pDropDown; 81 static LPCWSTR GetWndClassName() { return WC_SCROLLBARW; } 82 CACScrollBar() : m_pDropDown(NULL) { } 83 HWND Create(HWND hwndParent); 84 85 protected: 86 // message map 87 BEGIN_MSG_MAP(CACScrollBar) 88 END_MSG_MAP() 89 }; 90 91 ////////////////////////////////////////////////////////////////////////////// 92 // CACSizeBox --- auto-completion size-box control 93 94 class CACSizeBox : public CWindowImpl<CACSizeBox> 95 { 96 public: 97 CAutoComplete* m_pDropDown; 98 static LPCWSTR GetWndClassName() { return WC_SCROLLBARW; } 99 CACSizeBox() : m_pDropDown(NULL), m_bDowner(TRUE), m_bLongList(FALSE) { } 100 HWND Create(HWND hwndParent); 101 VOID SetStatus(BOOL bDowner, BOOL bLongList); 102 103 protected: 104 // protected variables 105 BOOL m_bDowner; 106 BOOL m_bLongList; 107 // message map 108 BEGIN_MSG_MAP(CACSizeBox) 109 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkGnd) 110 MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest) 111 MESSAGE_HANDLER(WM_PAINT, OnPaint) 112 END_MSG_MAP() 113 // message handlers 114 LRESULT OnEraseBkGnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 115 LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 116 LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 117 }; 118 119 ////////////////////////////////////////////////////////////////////////////// 120 // AC_THREAD --- Thread data for CAutoComplete 121 122 typedef struct AC_THREAD 123 { 124 CAutoComplete *m_pThis; 125 BOOL m_bAppendOK; 126 CStringW m_strText; 127 CSimpleArray<CStringW> m_innerList; // internal list 128 CSimpleArray<CStringW> m_outerList; // outer list 129 BOOL m_bReset; 130 BOOL m_bExpand; 131 132 VOID ReLoadInnerList(const CStringW& strText); 133 } AC_THREAD, *PAC_THREAD; 134 135 ////////////////////////////////////////////////////////////////////////////// 136 // CAutoComplete --- auto-completion drop-down window 137 138 #define WC_DROPDOWNW L"Auto-Suggest Dropdown" // the window class name 139 140 #define AUTOCOMP_START (WM_USER + 1) 141 #define AUTOCOMP_FINISH (WM_USER + 2) 142 143 class CAutoComplete 144 : public CComCoClass<CAutoComplete, &CLSID_AutoComplete> 145 , public CComObjectRootEx<CComMultiThreadModelNoCS> 146 , public CWindowImpl<CAutoComplete> 147 , public IAutoComplete2 148 , public IAutoCompleteDropDown 149 , public IEnumString 150 { 151 public: 152 DECLARE_WND_CLASS_EX(WC_DROPDOWNW, CS_DROPSHADOW | CS_SAVEBITS, COLOR_3DFACE) 153 static LPCWSTR GetWndClassName() { return WC_DROPDOWNW; } 154 BOOL m_bInSetText; // this flag avoids subsequent action in WM_SETTEXT 155 BOOL m_bInSelectItem; // this flag avoids subsequent action in LVN_ITEMCHANGED 156 BOOL m_bEditHasFocus; 157 158 // public methods 159 CAutoComplete(); 160 virtual ~CAutoComplete(); 161 162 HWND CreateDropDown(); 163 BOOL CanAutoSuggest() const; 164 BOOL CanAutoAppend() const; 165 BOOL UseTab() const; 166 BOOL IsComboBoxDropped() const; 167 BOOL FilterPrefixes() const; 168 INT GetItemCount() const; 169 CStringW GetItemText(INT iItem) const; 170 171 CStringW GetEditText() const; 172 VOID SetEditText(LPCWSTR pszText); 173 CStringW GetStemText(const CStringW& strText) const; 174 VOID SetEditSel(INT ich0, INT ich1); 175 176 VOID ShowDropDown(); 177 VOID HideDropDown(); 178 VOID SelectItem(INT iItem); 179 VOID DoAutoAppend(PAC_THREAD pThread); 180 VOID DoThreadWork(PAC_THREAD pThread); 181 VOID DoBackWord(); 182 VOID UpdateScrollBar(); 183 184 VOID StartCompletion(BOOL bAppendOK); 185 VOID AutoCompThreadProc(); 186 VOID FinishCompletion(PAC_THREAD pThread); 187 188 LRESULT EditWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 189 LRESULT OnEditChar(WPARAM wParam, LPARAM lParam); 190 BOOL OnEditKeyDown(WPARAM wParam, LPARAM lParam); 191 VOID OnListSelChange(); 192 BOOL OnListUpDown(UINT vk); 193 194 // IAutoComplete methods 195 STDMETHODIMP Enable(BOOL fEnable) override; 196 STDMETHODIMP Init(HWND hwndEdit, IUnknown *punkACL, LPCOLESTR pwszRegKeyPath, 197 LPCOLESTR pwszQuickComplete) override; 198 // IAutoComplete2 methods 199 STDMETHODIMP GetOptions(DWORD *pdwFlag) override; 200 STDMETHODIMP SetOptions(DWORD dwFlag) override; 201 // IAutoCompleteDropDown methods 202 STDMETHODIMP GetDropDownStatus(DWORD *pdwFlags, LPWSTR *ppwszString) override; 203 STDMETHODIMP ResetEnumerator() override; 204 // IEnumString methods 205 STDMETHODIMP Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched) override; 206 STDMETHODIMP Skip(ULONG celt) override; 207 STDMETHODIMP Reset() override; 208 STDMETHODIMP Clone(IEnumString **ppOut) override; 209 210 protected: 211 // The following variables are POD (plain old data): 212 BOOL m_bDowner; // downer or upper? (below textbox or above textbox) 213 DWORD m_dwOptions; // for IAutoComplete2::SetOptions 214 DWORD m_bEnabled; // the auto-composition is enabled? 215 HWND m_hwndCombo; // the combobox if any 216 HFONT m_hFont; // the font 217 BOOL m_bResized; // re-sized by size-box? 218 RECT m_rcEdit; // in screen coordinates, to watch the position 219 HWND m_hwndEdit; // the textbox 220 WNDPROC m_fnOldEditProc; // old textbox procedure 221 EDITWORDBREAKPROCW m_fnOldWordBreakProc; 222 HANDLE m_hThread; 223 PAC_THREAD m_pThread; 224 225 // The following variables are non-POD: 226 CStringW m_strText; // internal text (used in selecting item and reverting text) 227 CStringW m_strStemText; // dirname + '\\' 228 CStringW m_strQuickComplete; // used for [Ctrl]+[Enter] 229 CACListView m_hwndList; // this listview is virtual 230 CACScrollBar m_hwndScrollBar; // scroll bar contol 231 CACSizeBox m_hwndSizeBox; // the size grip 232 CComPtr<IEnumString> m_pEnum; // used for enumeration 233 CComPtr<IACList> m_pACList; // for IACList::Expand to update the list 234 CSimpleArray<CStringW> m_innerList; // inner list 235 CSimpleArray<CStringW> m_outerList; // outer list 236 237 // protected methods 238 VOID UpdateDropDownState(); 239 VOID CalcRects(BOOL bDowner, RECT& rcListView, RECT& rcScrollBar, RECT& rcSizeBox) const; 240 VOID LoadQuickComplete(LPCWSTR pwszRegKeyPath, LPCWSTR pwszQuickComplete); 241 CStringW GetQuickEdit(LPCWSTR pszText) const; 242 VOID RepositionDropDown(); 243 VOID ReLoadInnerList(PAC_THREAD pThread); 244 VOID ExtractInnerList(CSimpleArray<CStringW>& outerList, 245 const CSimpleArray<CStringW>& innerList, 246 const CString& strText); 247 248 // message map 249 BEGIN_MSG_MAP(CAutoComplete) 250 MESSAGE_HANDLER(AUTOCOMP_START, OnAutoCompStart) 251 MESSAGE_HANDLER(AUTOCOMP_FINISH, OnAutoCompFinish) 252 MESSAGE_HANDLER(WM_CREATE, OnCreate) 253 MESSAGE_HANDLER(WM_NCDESTROY, OnNCDestroy) 254 MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem) 255 MESSAGE_HANDLER(WM_EXITSIZEMOVE, OnExitSizeMove) 256 MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo) 257 MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem) 258 MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate) 259 MESSAGE_HANDLER(WM_NCACTIVATE, OnNCActivate) 260 MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNCLButtonDown) 261 MESSAGE_HANDLER(WM_NOTIFY, OnNotify) 262 MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest) 263 MESSAGE_HANDLER(WM_SIZE, OnSize) 264 MESSAGE_HANDLER(WM_SHOWWINDOW, OnShowWindow) 265 MESSAGE_HANDLER(WM_TIMER, OnTimer) 266 MESSAGE_HANDLER(WM_VSCROLL, OnVScroll) 267 END_MSG_MAP() 268 269 // message handlers 270 LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 271 LRESULT OnNCDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 272 LRESULT OnDrawItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 273 LRESULT OnExitSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 274 LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 275 LRESULT OnMeasureItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 276 LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 277 LRESULT OnNCActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 278 LRESULT OnNCLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 279 LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 280 LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 281 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 282 LRESULT OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 283 LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 284 LRESULT OnVScroll(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 285 LRESULT OnAutoCompStart(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 286 LRESULT OnAutoCompFinish(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 287 288 virtual VOID OnFinalMessage(HWND) override; 289 290 DECLARE_REGISTRY_RESOURCEID(IDR_AUTOCOMPLETE) 291 DECLARE_NOT_AGGREGATABLE(CAutoComplete) 292 DECLARE_PROTECT_FINAL_CONSTRUCT() 293 294 BEGIN_COM_MAP(CAutoComplete) 295 COM_INTERFACE_ENTRY_IID(IID_IAutoComplete, IAutoComplete) 296 COM_INTERFACE_ENTRY_IID(IID_IAutoComplete2, IAutoComplete2) 297 COM_INTERFACE_ENTRY_IID(IID_IAutoCompleteDropDown, IAutoCompleteDropDown) 298 COM_INTERFACE_ENTRY_IID(IID_IEnumString, IEnumString) 299 END_COM_MAP() 300 }; 301