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 "rosctrls.h" 26 27 class CACEditCtrl; 28 class CACListView; 29 class CACScrollBar; 30 class CACSizeBox; 31 class CAutoComplete; 32 33 ////////////////////////////////////////////////////////////////////////////// 34 // CACEditCtrl --- auto-completion textbox 35 36 class CACEditCtrl 37 : public CWindowImpl<CACEditCtrl, CWindow, CControlWinTraits> 38 { 39 public: 40 CAutoComplete* m_pDropDown; 41 static LPCWSTR GetWndClassName() { return WC_EDITW; } 42 43 CACEditCtrl(); 44 VOID HookWordBreakProc(BOOL bHook); 45 46 // message map 47 BEGIN_MSG_MAP(CACEditCtrl) 48 MESSAGE_HANDLER(WM_CHAR, OnChar) 49 MESSAGE_HANDLER(WM_CLEAR, OnCutPasteClear) 50 MESSAGE_HANDLER(WM_CUT, OnCutPasteClear) 51 MESSAGE_HANDLER(WM_DESTROY, OnDestroy) 52 MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode) 53 MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) 54 MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus) 55 MESSAGE_HANDLER(WM_PASTE, OnCutPasteClear) 56 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) 57 MESSAGE_HANDLER(WM_SETTEXT, OnSetText) 58 END_MSG_MAP() 59 60 protected: 61 // protected variables 62 EDITWORDBREAKPROCW m_fnOldWordBreakProc; 63 // message handlers 64 LRESULT OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 65 LRESULT OnCutPasteClear(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 66 LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 67 LRESULT OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 68 LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 69 LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 70 LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 71 LRESULT OnSetText(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 72 }; 73 74 ////////////////////////////////////////////////////////////////////////////// 75 // CACListView --- auto-completion list control 76 77 class CACListView : public CWindowImpl<CACListView, CListView> 78 { 79 public: 80 CAutoComplete* m_pDropDown; 81 INT m_cyItem; 82 static LPCWSTR GetWndClassName() { return WC_LISTVIEW; } 83 84 CACListView(); 85 HWND Create(HWND hwndParent); 86 VOID SetFont(HFONT hFont); 87 88 INT GetVisibleCount(); 89 CStringW GetItemText(INT iItem); 90 INT ItemFromPoint(INT x, INT y); 91 92 INT GetCurSel(); 93 VOID SetCurSel(INT iItem); 94 VOID SelectHere(INT x, INT y); 95 96 protected: 97 // message map 98 BEGIN_MSG_MAP(CACListView) 99 MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) 100 MESSAGE_HANDLER(WM_LBUTTONUP, OnButtonUp) 101 MESSAGE_HANDLER(WM_MBUTTONDOWN, OnMRButtonDown) 102 MESSAGE_HANDLER(WM_MBUTTONUP, OnButtonUp) 103 MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel) 104 MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest) 105 MESSAGE_HANDLER(WM_RBUTTONDOWN, OnMRButtonDown) 106 MESSAGE_HANDLER(WM_RBUTTONUP, OnButtonUp) 107 END_MSG_MAP() 108 // message handlers 109 LRESULT OnButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 110 LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 111 LRESULT OnMRButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 112 LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 113 LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 114 }; 115 116 ////////////////////////////////////////////////////////////////////////////// 117 // CACScrollBar --- auto-completion scrollbar control 118 119 class CACScrollBar : public CWindowImpl<CACScrollBar> 120 { 121 public: 122 CAutoComplete* m_pDropDown; 123 static LPCWSTR GetWndClassName() { return WC_SCROLLBARW; } 124 125 CACScrollBar(); 126 HWND Create(HWND hwndParent); 127 128 protected: 129 // message map 130 BEGIN_MSG_MAP(CACScrollBar) 131 END_MSG_MAP() 132 }; 133 134 ////////////////////////////////////////////////////////////////////////////// 135 // CACSizeBox --- auto-completion size-box control 136 137 class CACSizeBox : public CWindowImpl<CACSizeBox> 138 { 139 public: 140 CAutoComplete* m_pDropDown; 141 static LPCWSTR GetWndClassName() { return WC_SCROLLBARW; } 142 143 CACSizeBox(); 144 HWND Create(HWND hwndParent); 145 VOID SetStatus(BOOL bDowner, BOOL bLongList); 146 147 protected: 148 // protected variables 149 BOOL m_bDowner; 150 BOOL m_bLongList; 151 // message map 152 BEGIN_MSG_MAP(CACSizeBox) 153 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkGnd) 154 MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest) 155 MESSAGE_HANDLER(WM_PAINT, OnPaint) 156 END_MSG_MAP() 157 // message handlers 158 LRESULT OnEraseBkGnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 159 LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 160 LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 161 }; 162 163 ////////////////////////////////////////////////////////////////////////////// 164 // CAutoComplete --- auto-completion drop-down window 165 166 #define WC_DROPDOWNW L"Auto-Suggest Dropdown" // the window class name 167 168 class CAutoComplete 169 : public CComCoClass<CAutoComplete, &CLSID_AutoComplete> 170 , public CComObjectRootEx<CComMultiThreadModelNoCS> 171 , public CWindowImpl<CAutoComplete> 172 , public IAutoComplete2 173 , public IAutoCompleteDropDown 174 , public IEnumString 175 { 176 public: 177 DECLARE_WND_CLASS_EX(WC_DROPDOWNW, CS_DROPSHADOW | CS_SAVEBITS, COLOR_3DFACE) 178 static LPCWSTR GetWndClassName() { return WC_DROPDOWNW; } 179 BOOL m_bInSetText; // this flag avoids subsequent action in WM_SETTEXT 180 BOOL m_bInSelectItem; // this flag avoids subsequent action in LVN_ITEMCHANGED 181 182 // public methods 183 CAutoComplete(); 184 HWND CreateDropDown(); 185 virtual ~CAutoComplete(); 186 187 BOOL CanAutoSuggest(); 188 BOOL CanAutoAppend(); 189 BOOL UseTab(); 190 BOOL IsComboBoxDropped(); 191 INT GetItemCount(); 192 CStringW GetItemText(INT iItem); 193 194 CStringW GetEditText(); 195 VOID SetEditText(LPCWSTR pszText); 196 CStringW GetStemText(); 197 VOID SetEditSel(INT ich0, INT ich1); 198 199 VOID ShowDropDown(); 200 VOID HideDropDown(); 201 VOID SelectItem(INT iItem); 202 VOID DoAutoAppend(); 203 VOID DoBackWord(); 204 VOID UpdateScrollBar(); 205 206 LRESULT OnEditChar(WPARAM wParam, LPARAM lParam); 207 BOOL OnEditKeyDown(WPARAM wParam, LPARAM lParam); 208 VOID OnEditUpdate(BOOL bAppendOK); 209 VOID OnListSelChange(); 210 BOOL OnListUpDown(UINT vk); 211 212 // IAutoComplete methods 213 STDMETHODIMP Enable(BOOL fEnable) override; 214 STDMETHODIMP Init(HWND hwndEdit, IUnknown *punkACL, LPCOLESTR pwszRegKeyPath, 215 LPCOLESTR pwszQuickComplete) override; 216 // IAutoComplete2 methods 217 STDMETHODIMP GetOptions(DWORD *pdwFlag) override; 218 STDMETHODIMP SetOptions(DWORD dwFlag) override; 219 // IAutoCompleteDropDown methods 220 STDMETHODIMP GetDropDownStatus(DWORD *pdwFlags, LPWSTR *ppwszString) override; 221 STDMETHODIMP ResetEnumerator() override; 222 // IEnumString methods 223 STDMETHODIMP Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched) override; 224 STDMETHODIMP Skip(ULONG celt) override; 225 STDMETHODIMP Reset() override; 226 STDMETHODIMP Clone(IEnumString **ppOut) override; 227 228 protected: 229 // The following variables are POD (plain old data): 230 BOOL m_bDowner; // downer or upper? (below textbox or above textbox) 231 DWORD m_dwOptions; // for IAutoComplete2::SetOptions 232 DWORD m_bEnabled; // the auto-composition is enabled? 233 HWND m_hwndCombo; // the combobox if any 234 HFONT m_hFont; // the font 235 BOOL m_bResized; // re-sized by size-box? 236 RECT m_rcEdit; // in screen coordinates, to watch the position 237 // The following variables are non-POD: 238 CStringW m_strText; // internal text (used in selecting item and reverting text) 239 CStringW m_strStemText; // dirname + '\\' 240 CStringW m_strQuickComplete; // used for [Ctrl]+[Enter] 241 CACEditCtrl m_hwndEdit; // subclassed to watch 242 CACListView m_hwndList; // this listview is virtual 243 CACScrollBar m_hwndScrollBar; // scroll bar contol 244 CACSizeBox m_hwndSizeBox; // the size grip 245 CComPtr<IEnumString> m_pEnum; // used for enumeration 246 CComPtr<IACList> m_pACList; // for IACList::Expand to update the list 247 CSimpleArray<CStringW> m_innerList; // internal list 248 CSimpleArray<CStringW> m_outerList; // owner data for virtual listview 249 // protected methods 250 VOID UpdateDropDownState(); 251 VOID CalcRects(BOOL bDowner, RECT& rcListView, RECT& rcScrollBar, RECT& rcSizeBox); 252 VOID LoadQuickComplete(LPCWSTR pwszRegKeyPath, LPCWSTR pwszQuickComplete); 253 CStringW GetQuickEdit(LPCWSTR pszText); 254 VOID RepositionDropDown(); 255 INT ReLoadInnerList(); 256 INT UpdateInnerList(); 257 INT UpdateOuterList(); 258 VOID UpdateCompletion(BOOL bAppendOK); 259 // message map 260 BEGIN_MSG_MAP(CAutoComplete) 261 MESSAGE_HANDLER(WM_CREATE, OnCreate) 262 MESSAGE_HANDLER(WM_DESTROY, OnDestroy) 263 MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem) 264 MESSAGE_HANDLER(WM_EXITSIZEMOVE, OnExitSizeMove) 265 MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo) 266 MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem) 267 MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate) 268 MESSAGE_HANDLER(WM_NCACTIVATE, OnNCActivate) 269 MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNCLButtonDown) 270 MESSAGE_HANDLER(WM_NOTIFY, OnNotify) 271 MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest) 272 MESSAGE_HANDLER(WM_SIZE, OnSize) 273 MESSAGE_HANDLER(WM_SHOWWINDOW, OnShowWindow) 274 MESSAGE_HANDLER(WM_TIMER, OnTimer) 275 MESSAGE_HANDLER(WM_VSCROLL, OnVScroll) 276 END_MSG_MAP() 277 // message handlers 278 LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 279 LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 280 LRESULT OnDrawItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 281 LRESULT OnExitSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 282 LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 283 LRESULT OnMeasureItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 284 LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 285 LRESULT OnNCActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 286 LRESULT OnNCLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 287 LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 288 LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 289 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 290 LRESULT OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 291 LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 292 LRESULT OnVScroll(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 293 294 DECLARE_REGISTRY_RESOURCEID(IDR_AUTOCOMPLETE) 295 DECLARE_NOT_AGGREGATABLE(CAutoComplete) 296 DECLARE_PROTECT_FINAL_CONSTRUCT() 297 298 BEGIN_COM_MAP(CAutoComplete) 299 COM_INTERFACE_ENTRY_IID(IID_IAutoComplete, IAutoComplete) 300 COM_INTERFACE_ENTRY_IID(IID_IAutoComplete2, IAutoComplete2) 301 COM_INTERFACE_ENTRY_IID(IID_IAutoCompleteDropDown, IAutoCompleteDropDown) 302 COM_INTERFACE_ENTRY_IID(IID_IEnumString, IEnumString) 303 END_COM_MAP() 304 }; 305