mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[BROWSEUI] Implement auto-completion (#3507)
Implement IAutoComplete to realize input auto completion. CORE-9281, CORE-1419 - The main features of this PR are Auto-Suggest and Auto-Append. - Auto-Suggest shows a list near the textbox (an EDIT control) when the user has typed partial pathname into the textbox. - Auto-Append appends complement text into the textbox to complete the pathname with selected status. - The list of AutoSuggest is a top-level window whose window class is "Auto-Suggest Dropdown". We call it "the drop-down window". - The drop-down window contains three controls: a listview, a scrollbar and a sizebox. - The drop-down window watches the input into the textbox. If the textbox changed, then the window updates the list. - The sizebox control enables the user to resize the drop-down window.
This commit is contained in:
parent
0c34c067c4
commit
c19d9df259
2 changed files with 2249 additions and 621 deletions
File diff suppressed because it is too large
Load diff
|
@ -19,65 +19,286 @@
|
|||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef _AUTOCOMPLETE_H_
|
||||
#define _AUTOCOMPLETE_H_
|
||||
#include "atltypes.h"
|
||||
#include "rosctrls.h"
|
||||
|
||||
class CAutoComplete :
|
||||
public CComCoClass<CAutoComplete, &CLSID_AutoComplete>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IAutoComplete2,
|
||||
public IAutoCompleteDropDown,
|
||||
public IEnumString
|
||||
class CACEditCtrl;
|
||||
class CACListView;
|
||||
class CACScrollBar;
|
||||
class CACSizeBox;
|
||||
class CAutoComplete;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CACEditCtrl --- auto-completion textbox
|
||||
|
||||
class CACEditCtrl
|
||||
: public CWindowImpl<CACEditCtrl, CWindow, CControlWinTraits>
|
||||
{
|
||||
private:
|
||||
BOOL m_enabled;
|
||||
BOOL m_initialized;
|
||||
HWND m_hwndEdit;
|
||||
HWND m_hwndListBox;
|
||||
WNDPROC m_wpOrigEditProc;
|
||||
WNDPROC m_wpOrigLBoxProc;
|
||||
LPWSTR m_txtbackup; // HeapAlloc'ed
|
||||
LPWSTR m_quickComplete; // HeapAlloc'ed
|
||||
CComPtr<IEnumString> m_enumstr;
|
||||
AUTOCOMPLETEOPTIONS m_options;
|
||||
public:
|
||||
CAutoComplete* m_pDropDown;
|
||||
static LPCWSTR GetWndClassName() { return WC_EDITW; }
|
||||
|
||||
CAutoComplete();
|
||||
~CAutoComplete();
|
||||
CACEditCtrl();
|
||||
VOID HookWordBreakProc(BOOL bHook);
|
||||
|
||||
static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
static LRESULT APIENTRY ACLBoxSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
// message map
|
||||
BEGIN_MSG_MAP(CACEditCtrl)
|
||||
MESSAGE_HANDLER(WM_CHAR, OnChar)
|
||||
MESSAGE_HANDLER(WM_CLEAR, OnCutPasteClear)
|
||||
MESSAGE_HANDLER(WM_CUT, OnCutPasteClear)
|
||||
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
|
||||
MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
|
||||
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
|
||||
MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
|
||||
MESSAGE_HANDLER(WM_PASTE, OnCutPasteClear)
|
||||
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
|
||||
MESSAGE_HANDLER(WM_SETTEXT, OnSetText)
|
||||
END_MSG_MAP()
|
||||
|
||||
void CreateListbox();
|
||||
|
||||
// IAutoComplete2
|
||||
virtual HRESULT WINAPI Enable(BOOL fEnable);
|
||||
virtual HRESULT WINAPI Init(HWND hwndEdit, IUnknown *punkACL, LPCOLESTR pwzsRegKeyPath, LPCOLESTR pwszQuickComplete);
|
||||
virtual HRESULT WINAPI GetOptions(DWORD *pdwFlag);
|
||||
virtual HRESULT WINAPI SetOptions(DWORD dwFlag);
|
||||
|
||||
// IAutoCompleteDropDown
|
||||
virtual HRESULT STDMETHODCALLTYPE GetDropDownStatus(DWORD *pdwFlags, LPWSTR *ppwszString);
|
||||
virtual HRESULT STDMETHODCALLTYPE ResetEnumerator();
|
||||
|
||||
// IEnumString methods
|
||||
virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched);
|
||||
virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt);
|
||||
virtual HRESULT STDMETHODCALLTYPE Reset();
|
||||
virtual HRESULT STDMETHODCALLTYPE Clone(IEnumString **ppenum);
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_AUTOCOMPLETE)
|
||||
DECLARE_NOT_AGGREGATABLE(CAutoComplete)
|
||||
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
BEGIN_COM_MAP(CAutoComplete)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IAutoComplete, IAutoComplete)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IAutoComplete2, IAutoComplete2)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IAutoCompleteDropDown, IAutoCompleteDropDown)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IEnumString, IEnumString)
|
||||
END_COM_MAP()
|
||||
protected:
|
||||
// protected variables
|
||||
EDITWORDBREAKPROCW m_fnOldWordBreakProc;
|
||||
// message handlers
|
||||
LRESULT OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnCutPasteClear(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnSetText(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
};
|
||||
|
||||
#endif /* _AUTOCOMPLETE_H_ */
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CACListView --- auto-completion list control
|
||||
|
||||
class CACListView : public CWindowImpl<CACListView, CListView>
|
||||
{
|
||||
public:
|
||||
CAutoComplete* m_pDropDown;
|
||||
INT m_cyItem;
|
||||
static LPCWSTR GetWndClassName() { return WC_LISTVIEW; }
|
||||
|
||||
CACListView();
|
||||
HWND Create(HWND hwndParent);
|
||||
VOID SetFont(HFONT hFont);
|
||||
|
||||
INT GetVisibleCount();
|
||||
CStringW GetItemText(INT iItem);
|
||||
INT ItemFromPoint(INT x, INT y);
|
||||
|
||||
INT GetCurSel();
|
||||
VOID SetCurSel(INT iItem);
|
||||
VOID SelectHere(INT x, INT y);
|
||||
|
||||
protected:
|
||||
// message map
|
||||
BEGIN_MSG_MAP(CACListView)
|
||||
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
|
||||
MESSAGE_HANDLER(WM_LBUTTONUP, OnButtonUp)
|
||||
MESSAGE_HANDLER(WM_MBUTTONDOWN, OnMRButtonDown)
|
||||
MESSAGE_HANDLER(WM_MBUTTONUP, OnButtonUp)
|
||||
MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
|
||||
MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest)
|
||||
MESSAGE_HANDLER(WM_RBUTTONDOWN, OnMRButtonDown)
|
||||
MESSAGE_HANDLER(WM_RBUTTONUP, OnButtonUp)
|
||||
END_MSG_MAP()
|
||||
// message handlers
|
||||
LRESULT OnButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnMRButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CACScrollBar --- auto-completion scrollbar control
|
||||
|
||||
class CACScrollBar : public CWindowImpl<CACScrollBar>
|
||||
{
|
||||
public:
|
||||
CAutoComplete* m_pDropDown;
|
||||
static LPCWSTR GetWndClassName() { return WC_SCROLLBARW; }
|
||||
|
||||
CACScrollBar();
|
||||
HWND Create(HWND hwndParent);
|
||||
|
||||
protected:
|
||||
// message map
|
||||
BEGIN_MSG_MAP(CACScrollBar)
|
||||
END_MSG_MAP()
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CACSizeBox --- auto-completion size-box control
|
||||
|
||||
class CACSizeBox : public CWindowImpl<CACSizeBox>
|
||||
{
|
||||
public:
|
||||
CAutoComplete* m_pDropDown;
|
||||
static LPCWSTR GetWndClassName() { return WC_SCROLLBARW; }
|
||||
|
||||
CACSizeBox();
|
||||
HWND Create(HWND hwndParent);
|
||||
VOID SetStatus(BOOL bDowner, BOOL bLongList);
|
||||
|
||||
protected:
|
||||
// protected variables
|
||||
BOOL m_bDowner;
|
||||
BOOL m_bLongList;
|
||||
// message map
|
||||
BEGIN_MSG_MAP(CACSizeBox)
|
||||
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkGnd)
|
||||
MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest)
|
||||
MESSAGE_HANDLER(WM_PAINT, OnPaint)
|
||||
END_MSG_MAP()
|
||||
// message handlers
|
||||
LRESULT OnEraseBkGnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// CAutoComplete --- auto-completion drop-down window
|
||||
|
||||
#define WC_DROPDOWNW L"Auto-Suggest Dropdown" // the window class name
|
||||
|
||||
class CAutoComplete
|
||||
: public CComCoClass<CAutoComplete, &CLSID_AutoComplete>
|
||||
, public CComObjectRootEx<CComMultiThreadModelNoCS>
|
||||
, public CWindowImpl<CAutoComplete>
|
||||
, public IAutoComplete2
|
||||
, public IAutoCompleteDropDown
|
||||
, public IEnumString
|
||||
{
|
||||
public:
|
||||
DECLARE_WND_CLASS_EX(WC_DROPDOWNW, CS_DROPSHADOW | CS_SAVEBITS, COLOR_3DFACE)
|
||||
static LPCWSTR GetWndClassName() { return WC_DROPDOWNW; }
|
||||
BOOL m_bInSetText; // this flag avoids subsequent action in WM_SETTEXT
|
||||
BOOL m_bInSelectItem; // this flag avoids subsequent action in LVN_ITEMCHANGED
|
||||
|
||||
// public methods
|
||||
CAutoComplete();
|
||||
HWND CreateDropDown();
|
||||
virtual ~CAutoComplete();
|
||||
|
||||
BOOL CanAutoSuggest();
|
||||
BOOL CanAutoAppend();
|
||||
BOOL UseTab();
|
||||
BOOL IsComboBoxDropped();
|
||||
INT GetItemCount();
|
||||
CStringW GetItemText(INT iItem);
|
||||
|
||||
CStringW GetEditText();
|
||||
VOID SetEditText(LPCWSTR pszText);
|
||||
CStringW GetStemText();
|
||||
VOID SetEditSel(INT ich0, INT ich1);
|
||||
|
||||
VOID ShowDropDown();
|
||||
VOID HideDropDown();
|
||||
VOID SelectItem(INT iItem);
|
||||
VOID DoAutoAppend();
|
||||
VOID DoBackWord();
|
||||
VOID UpdateScrollBar();
|
||||
|
||||
LRESULT OnEditChar(WPARAM wParam, LPARAM lParam);
|
||||
BOOL OnEditKeyDown(WPARAM wParam, LPARAM lParam);
|
||||
VOID OnEditUpdate(BOOL bAppendOK);
|
||||
VOID OnListSelChange();
|
||||
BOOL OnListUpDown(UINT vk);
|
||||
|
||||
// IAutoComplete methods
|
||||
STDMETHODIMP Enable(BOOL fEnable) override;
|
||||
STDMETHODIMP Init(HWND hwndEdit, IUnknown *punkACL, LPCOLESTR pwszRegKeyPath,
|
||||
LPCOLESTR pwszQuickComplete) override;
|
||||
// IAutoComplete2 methods
|
||||
STDMETHODIMP GetOptions(DWORD *pdwFlag) override;
|
||||
STDMETHODIMP SetOptions(DWORD dwFlag) override;
|
||||
// IAutoCompleteDropDown methods
|
||||
STDMETHODIMP GetDropDownStatus(DWORD *pdwFlags, LPWSTR *ppwszString) override;
|
||||
STDMETHODIMP ResetEnumerator() override;
|
||||
// IEnumString methods
|
||||
STDMETHODIMP Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched) override;
|
||||
STDMETHODIMP Skip(ULONG celt) override;
|
||||
STDMETHODIMP Reset() override;
|
||||
STDMETHODIMP Clone(IEnumString **ppOut) override;
|
||||
|
||||
protected:
|
||||
// The following variables are POD (plain old data):
|
||||
BOOL m_bDowner; // downer or upper? (below textbox or above textbox)
|
||||
DWORD m_dwOptions; // for IAutoComplete2::SetOptions
|
||||
DWORD m_bEnabled; // the auto-composition is enabled?
|
||||
HWND m_hwndCombo; // the combobox if any
|
||||
HFONT m_hFont; // the font
|
||||
BOOL m_bResized; // re-sized by size-box?
|
||||
RECT m_rcEdit; // in screen coordinates, to watch the position
|
||||
// The following variables are non-POD:
|
||||
CStringW m_strText; // internal text (used in selecting item and reverting text)
|
||||
CStringW m_strStemText; // dirname + '\\'
|
||||
CStringW m_strQuickComplete; // used for [Ctrl]+[Enter]
|
||||
CACEditCtrl m_hwndEdit; // subclassed to watch
|
||||
CACListView m_hwndList; // this listview is virtual
|
||||
CACScrollBar m_hwndScrollBar; // scroll bar contol
|
||||
CACSizeBox m_hwndSizeBox; // the size grip
|
||||
CComPtr<IEnumString> m_pEnum; // used for enumeration
|
||||
CComPtr<IACList> m_pACList; // for IACList::Expand to update the list
|
||||
CSimpleArray<CStringW> m_innerList; // internal list
|
||||
CSimpleArray<CStringW> m_outerList; // owner data for virtual listview
|
||||
// protected methods
|
||||
VOID UpdateDropDownState();
|
||||
VOID CalcRects(BOOL bDowner, RECT& rcListView, RECT& rcScrollBar, RECT& rcSizeBox);
|
||||
VOID LoadQuickComplete(LPCWSTR pwszRegKeyPath, LPCWSTR pwszQuickComplete);
|
||||
CStringW GetQuickEdit(LPCWSTR pszText);
|
||||
VOID RepositionDropDown();
|
||||
INT ReLoadInnerList();
|
||||
INT UpdateInnerList();
|
||||
INT UpdateOuterList();
|
||||
VOID UpdateCompletion(BOOL bAppendOK);
|
||||
// message map
|
||||
BEGIN_MSG_MAP(CAutoComplete)
|
||||
MESSAGE_HANDLER(WM_CREATE, OnCreate)
|
||||
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
|
||||
MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
|
||||
MESSAGE_HANDLER(WM_EXITSIZEMOVE, OnExitSizeMove)
|
||||
MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
|
||||
MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)
|
||||
MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
|
||||
MESSAGE_HANDLER(WM_NCACTIVATE, OnNCActivate)
|
||||
MESSAGE_HANDLER(WM_NCLBUTTONDOWN, OnNCLButtonDown)
|
||||
MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
|
||||
MESSAGE_HANDLER(WM_NCHITTEST, OnNCHitTest)
|
||||
MESSAGE_HANDLER(WM_SIZE, OnSize)
|
||||
MESSAGE_HANDLER(WM_SHOWWINDOW, OnShowWindow)
|
||||
MESSAGE_HANDLER(WM_TIMER, OnTimer)
|
||||
MESSAGE_HANDLER(WM_VSCROLL, OnVScroll)
|
||||
END_MSG_MAP()
|
||||
// message handlers
|
||||
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnDrawItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnExitSizeMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnMeasureItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnNCActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnNCLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnNCHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnVScroll(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_AUTOCOMPLETE)
|
||||
DECLARE_NOT_AGGREGATABLE(CAutoComplete)
|
||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
BEGIN_COM_MAP(CAutoComplete)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IAutoComplete, IAutoComplete)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IAutoComplete2, IAutoComplete2)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IAutoCompleteDropDown, IAutoCompleteDropDown)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IEnumString, IEnumString)
|
||||
END_COM_MAP()
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue