xref: /reactos/dll/win32/browseui/CAutoComplete.h (revision 957bb895)
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