reactos/dll/win32/browseui/CAutoComplete.h
Katayama Hirofumi MZ 9f68f482c1
[BROWSEUI] Check focus before opening AutoComplete (#7128)
Unexpectedly remaining
AutoComplete list is annoying.
JIRA issue: CORE-19685
- Add CAutoComplete::
  m_bEditHasFocus to watch
  focus.
- Update m_bEditHasFocus on
  WM_SETFOCUS and
  WM_KILLFOCUS messages on
  Edit window procedure.
- Don't open AutoComplete list
  when m_bEditHasFocus was
  FALSE.
2024-07-10 22:47:02 +09:00

300 lines
12 KiB
C++

/*
* AutoComplete interfaces implementation.
*
* Copyright 2004 Maxime Bellengé <maxime.bellenge@laposte.net>
* Copyright 2009 Andrew Hill
* Copyright 2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* 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
#include <atltypes.h>
#include <ui/rosctrls.h>
class CACListView;
class CACScrollBar;
class CACSizeBox;
class CAutoComplete;
//////////////////////////////////////////////////////////////////////////////
// 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() : m_pDropDown(NULL) { }
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() : m_pDropDown(NULL), m_bDowner(TRUE), m_bLongList(FALSE) { }
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);
};
//////////////////////////////////////////////////////////////////////////////
// AC_THREAD --- Thread data for CAutoComplete
typedef struct AC_THREAD
{
CAutoComplete *m_pThis;
BOOL m_bAppendOK;
CStringW m_strText;
CSimpleArray<CStringW> m_innerList; // internal list
CSimpleArray<CStringW> m_outerList; // outer list
BOOL m_bReset;
BOOL m_bExpand;
VOID ReLoadInnerList(const CStringW& strText);
} AC_THREAD, *PAC_THREAD;
//////////////////////////////////////////////////////////////////////////////
// CAutoComplete --- auto-completion drop-down window
#define WC_DROPDOWNW L"Auto-Suggest Dropdown" // the window class name
#define AUTOCOMP_START (WM_USER + 1)
#define AUTOCOMP_FINISH (WM_USER + 2)
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
BOOL m_bEditHasFocus;
// public methods
CAutoComplete();
virtual ~CAutoComplete();
HWND CreateDropDown();
BOOL CanAutoSuggest() const;
BOOL CanAutoAppend() const;
BOOL UseTab() const;
BOOL IsComboBoxDropped() const;
BOOL FilterPrefixes() const;
INT GetItemCount() const;
CStringW GetItemText(INT iItem) const;
CStringW GetEditText() const;
VOID SetEditText(LPCWSTR pszText);
CStringW GetStemText(const CStringW& strText) const;
VOID SetEditSel(INT ich0, INT ich1);
VOID ShowDropDown();
VOID HideDropDown();
VOID SelectItem(INT iItem);
VOID DoAutoAppend(PAC_THREAD pThread);
VOID DoThreadWork(PAC_THREAD pThread);
VOID DoBackWord();
VOID UpdateScrollBar();
VOID StartCompletion(BOOL bAppendOK);
VOID AutoCompThreadProc();
VOID FinishCompletion(PAC_THREAD pThread);
LRESULT EditWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnEditChar(WPARAM wParam, LPARAM lParam);
BOOL OnEditKeyDown(WPARAM wParam, LPARAM lParam);
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
HWND m_hwndEdit; // the textbox
WNDPROC m_fnOldEditProc; // old textbox procedure
EDITWORDBREAKPROCW m_fnOldWordBreakProc;
HANDLE m_hThread;
PAC_THREAD m_pThread;
// 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]
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; // inner list
CSimpleArray<CStringW> m_outerList; // outer list
// protected methods
VOID UpdateDropDownState();
VOID CalcRects(BOOL bDowner, RECT& rcListView, RECT& rcScrollBar, RECT& rcSizeBox) const;
VOID LoadQuickComplete(LPCWSTR pwszRegKeyPath, LPCWSTR pwszQuickComplete);
CStringW GetQuickEdit(LPCWSTR pszText) const;
VOID RepositionDropDown();
VOID ReLoadInnerList(PAC_THREAD pThread);
VOID ExtractInnerList(CSimpleArray<CStringW>& outerList,
const CSimpleArray<CStringW>& innerList,
const CString& strText);
// message map
BEGIN_MSG_MAP(CAutoComplete)
MESSAGE_HANDLER(AUTOCOMP_START, OnAutoCompStart)
MESSAGE_HANDLER(AUTOCOMP_FINISH, OnAutoCompFinish)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_NCDESTROY, OnNCDestroy)
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 OnNCDestroy(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);
LRESULT OnAutoCompStart(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnAutoCompFinish(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
virtual VOID OnFinalMessage(HWND) override;
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()
};