xref: /reactos/dll/win32/browseui/CAutoComplete.h (revision 3c5a56ed)
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 
157     // public methods
158     CAutoComplete();
159     HWND CreateDropDown();
160     virtual ~CAutoComplete();
161 
162     BOOL CanAutoSuggest() const;
163     BOOL CanAutoAppend() const;
164     BOOL UseTab() const;
165     BOOL IsComboBoxDropped() const;
166     BOOL FilterPrefixes() const;
167     INT GetItemCount() const;
168     CStringW GetItemText(INT iItem) const;
169 
170     CStringW GetEditText() const;
171     VOID SetEditText(LPCWSTR pszText);
172     CStringW GetStemText(const CStringW& strText) const;
173     VOID SetEditSel(INT ich0, INT ich1);
174 
175     VOID ShowDropDown();
176     VOID HideDropDown();
177     VOID SelectItem(INT iItem);
178     VOID DoAutoAppend(PAC_THREAD pThread);
179     VOID DoThreadWork(PAC_THREAD pThread);
180     VOID DoBackWord();
181     VOID UpdateScrollBar();
182 
183     VOID StartCompletion(BOOL bAppendOK);
184     VOID AutoCompThreadProc();
185     VOID FinishCompletion(PAC_THREAD pThread);
186 
187     LRESULT EditWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
188     LRESULT OnEditChar(WPARAM wParam, LPARAM lParam);
189     BOOL OnEditKeyDown(WPARAM wParam, LPARAM lParam);
190     VOID OnListSelChange();
191     BOOL OnListUpDown(UINT vk);
192 
193     // IAutoComplete methods
194     STDMETHODIMP Enable(BOOL fEnable) override;
195     STDMETHODIMP Init(HWND hwndEdit, IUnknown *punkACL, LPCOLESTR pwszRegKeyPath,
196                       LPCOLESTR pwszQuickComplete) override;
197     // IAutoComplete2 methods
198     STDMETHODIMP GetOptions(DWORD *pdwFlag) override;
199     STDMETHODIMP SetOptions(DWORD dwFlag) override;
200     // IAutoCompleteDropDown methods
201     STDMETHODIMP GetDropDownStatus(DWORD *pdwFlags, LPWSTR *ppwszString) override;
202     STDMETHODIMP ResetEnumerator() override;
203     // IEnumString methods
204     STDMETHODIMP Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched) override;
205     STDMETHODIMP Skip(ULONG celt) override;
206     STDMETHODIMP Reset() override;
207     STDMETHODIMP Clone(IEnumString **ppOut) override;
208 
209 protected:
210     // The following variables are POD (plain old data):
211     BOOL m_bDowner; // downer or upper? (below textbox or above textbox)
212     DWORD m_dwOptions; // for IAutoComplete2::SetOptions
213     DWORD m_bEnabled; // the auto-composition is enabled?
214     HWND m_hwndCombo; // the combobox if any
215     HFONT m_hFont; // the font
216     BOOL m_bResized; // re-sized by size-box?
217     RECT m_rcEdit; // in screen coordinates, to watch the position
218     HWND m_hwndEdit; // the textbox
219     WNDPROC m_fnOldEditProc; // old textbox procedure
220     EDITWORDBREAKPROCW m_fnOldWordBreakProc;
221     HANDLE m_hThread;
222     PAC_THREAD m_pThread;
223 
224     // The following variables are non-POD:
225     CStringW m_strText; // internal text (used in selecting item and reverting text)
226     CStringW m_strStemText; // dirname + '\\'
227     CStringW m_strQuickComplete; // used for [Ctrl]+[Enter]
228     CACListView m_hwndList; // this listview is virtual
229     CACScrollBar m_hwndScrollBar; // scroll bar contol
230     CACSizeBox m_hwndSizeBox; // the size grip
231     CComPtr<IEnumString> m_pEnum; // used for enumeration
232     CComPtr<IACList> m_pACList; // for IACList::Expand to update the list
233     CSimpleArray<CStringW> m_innerList; // inner list
234     CSimpleArray<CStringW> m_outerList; // outer list
235 
236     // protected methods
237     VOID UpdateDropDownState();
238     VOID CalcRects(BOOL bDowner, RECT& rcListView, RECT& rcScrollBar, RECT& rcSizeBox) const;
239     VOID LoadQuickComplete(LPCWSTR pwszRegKeyPath, LPCWSTR pwszQuickComplete);
240     CStringW GetQuickEdit(LPCWSTR pszText) const;
241     VOID RepositionDropDown();
242     VOID ReLoadInnerList(PAC_THREAD pThread);
243     VOID ExtractInnerList(CSimpleArray<CStringW>& outerList,
244                           const CSimpleArray<CStringW>& innerList,
245                           const CString& strText);
246 
247     // message map
248     BEGIN_MSG_MAP(CAutoComplete)
249         MESSAGE_HANDLER(AUTOCOMP_START, OnAutoCompStart)
250         MESSAGE_HANDLER(AUTOCOMP_FINISH, OnAutoCompFinish)
251         MESSAGE_HANDLER(WM_CREATE, OnCreate)
252         MESSAGE_HANDLER(WM_NCDESTROY, OnNCDestroy)
253         MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
254         MESSAGE_HANDLER(WM_EXITSIZEMOVE, OnExitSizeMove)
255         MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
256         MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)
257         MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
258         MESSAGE_HANDLER(WM_NCACTIVATE, OnNCActivate)
259         MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNCLButtonDown)
260         MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
261         MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest)
262         MESSAGE_HANDLER(WM_SIZE, OnSize)
263         MESSAGE_HANDLER(WM_SHOWWINDOW, OnShowWindow)
264         MESSAGE_HANDLER(WM_TIMER, OnTimer)
265         MESSAGE_HANDLER(WM_VSCROLL, OnVScroll)
266     END_MSG_MAP()
267 
268     // message handlers
269     LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
270     LRESULT OnNCDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
271     LRESULT OnDrawItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
272     LRESULT OnExitSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
273     LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
274     LRESULT OnMeasureItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
275     LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
276     LRESULT OnNCActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
277     LRESULT OnNCLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
278     LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
279     LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
280     LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
281     LRESULT OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
282     LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
283     LRESULT OnVScroll(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
284     LRESULT OnAutoCompStart(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
285     LRESULT OnAutoCompFinish(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
286 
287     DECLARE_REGISTRY_RESOURCEID(IDR_AUTOCOMPLETE)
288     DECLARE_NOT_AGGREGATABLE(CAutoComplete)
289     DECLARE_PROTECT_FINAL_CONSTRUCT()
290 
291     BEGIN_COM_MAP(CAutoComplete)
292         COM_INTERFACE_ENTRY_IID(IID_IAutoComplete, IAutoComplete)
293         COM_INTERFACE_ENTRY_IID(IID_IAutoComplete2, IAutoComplete2)
294         COM_INTERFACE_ENTRY_IID(IID_IAutoCompleteDropDown, IAutoCompleteDropDown)
295         COM_INTERFACE_ENTRY_IID(IID_IEnumString, IEnumString)
296     END_COM_MAP()
297 };
298