https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e2d8837986e19dd2fdd943bb8692afb3829de1b8

commit e2d8837986e19dd2fdd943bb8692afb3829de1b8
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sun Jul 11 13:00:00 2021 +0900
Commit:     GitHub <[email protected]>
CommitDate: Sun Jul 11 13:00:00 2021 +0900

    [BROWSEUI] Multithreaded auto-completion (#3794)
    
    - Make auto-completion multi-threaded.
    CORE-9281
---
 dll/win32/browseui/CAutoComplete.cpp | 435 +++++++++++++++++++----------------
 dll/win32/browseui/CAutoComplete.h   |  48 +++-
 2 files changed, 279 insertions(+), 204 deletions(-)

diff --git a/dll/win32/browseui/CAutoComplete.cpp 
b/dll/win32/browseui/CAutoComplete.cpp
index e7a078c10a3..a6d6bc84817 100644
--- a/dll/win32/browseui/CAutoComplete.cpp
+++ b/dll/win32/browseui/CAutoComplete.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "precomp.h"
+#include <process.h> // _beginthreadex
 
 /*
   TODO:
@@ -32,7 +33,6 @@
 #define CX_LIST 30160 // width of m_hwndList (very wide but alright)
 #define CY_LIST 288 // maximum height of drop-down window
 #define CY_ITEM 18 // default height of listview item
-#define COMPLETION_TIMEOUT 300 // in milliseconds
 #define MAX_ITEM_COUNT 1000 // the maximum number of items
 #define WATCH_TIMER_ID 0xFEEDBEEF // timer ID to watch m_rcEdit
 #define WATCH_INTERVAL 300 // in milliseconds
@@ -53,7 +53,7 @@ static const PREFIX_INFO s_prefixes[] =
     { L"www.", 4 },
 };
 
-static inline BOOL DropPrefix(const CStringW& str, CStringW& strBody)
+static BOOL DropPrefix(const CStringW& str, CStringW& strBody)
 {
     for (size_t iPrefix = 0; iPrefix < _countof(s_prefixes); ++iPrefix)
     {
@@ -69,6 +69,21 @@ static inline BOOL DropPrefix(const CStringW& str, CStringW& 
strBody)
     return FALSE;
 }
 
+static BOOL DoesMatch(const CStringW& strTarget, const CStringW& strText)
+{
+    CStringW strBody;
+    if (DropPrefix(strTarget, strBody))
+    {
+        if (::StrCmpNIW(strBody, strText, strText.GetLength()) == 0)
+            return TRUE;
+    }
+    else if (::StrCmpNIW(strTarget, strText, strText.GetLength()) == 0)
+    {
+        return TRUE;
+    }
+    return FALSE;
+}
+
 // mouse hook procedure to watch the mouse click
 // 
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644988(v=vs.85)
 static LRESULT CALLBACK MouseProc(INT nCode, WPARAM wParam, LPARAM lParam)
@@ -291,7 +306,7 @@ LRESULT CAutoComplete::EditWndProc(HWND hwnd, UINT uMsg, 
WPARAM wParam, LPARAM l
             return OnEditChar(wParam, lParam);
         case WM_CUT: case WM_PASTE: case WM_CLEAR:
             ret = ::DefSubclassProc(hwnd, uMsg, wParam, lParam); // do default
-            UpdateCompletion(TRUE);
+            StartCompletion(TRUE);
             return ret;
         case WM_GETDLGCODE:
             ret = ::DefSubclassProc(hwnd, uMsg, wParam, lParam); // do default
@@ -640,7 +655,7 @@ CAutoComplete::CAutoComplete()
     , m_bDowner(TRUE), m_dwOptions(ACO_AUTOAPPEND | ACO_AUTOSUGGEST)
     , m_bEnabled(TRUE), m_hwndCombo(NULL), m_hFont(NULL), m_bResized(FALSE)
     , m_hwndEdit(NULL), m_fnOldEditProc(NULL), m_fnOldWordBreakProc(NULL)
-    , m_bPartialList(FALSE), m_dwTick(0)
+    , m_hThread(NULL), m_pThread(NULL)
 {
 }
 
@@ -658,6 +673,11 @@ HWND CAutoComplete::CreateDropDown()
 CAutoComplete::~CAutoComplete()
 {
     TRACE("CAutoComplete::~CAutoComplete(%p)\n", this);
+    if (m_hThread)
+    {
+        CloseHandle(m_hThread);
+        m_hThread = NULL;
+    }
     if (m_hFont)
     {
         ::DeleteObject(m_hFont);
@@ -763,7 +783,7 @@ VOID CAutoComplete::SelectItem(INT iItem)
         m_hwndList.EnsureVisible(iItem, FALSE);
 }
 
-VOID CAutoComplete::DoAutoAppend()
+VOID CAutoComplete::DoAutoAppend(AC_THREAD *pThread)
 {
     if (!CanAutoAppend()) // can we auto-append?
         return; // don't append
@@ -772,7 +792,7 @@ VOID CAutoComplete::DoAutoAppend()
     if (strText.IsEmpty())
         return; // don't append
 
-    INT cItems = m_innerList.GetSize(); // get the number of items
+    INT cItems = m_outerList.GetSize(); // get the number of items
     if (cItems == 0)
         return; // don't append
 
@@ -781,7 +801,7 @@ VOID CAutoComplete::DoAutoAppend()
     BOOL bFound = FALSE;
     for (INT iItem = 0; iItem < cItems; ++iItem)
     {
-        const CStringW& strItem = m_innerList[iItem]; // get the text of the 
item
+        const CStringW& strItem = m_outerList[iItem]; // get the text of the 
item
 
         CStringW strBody;
         if (DropPrefix(strItem, strBody) &&
@@ -950,7 +970,7 @@ BOOL CAutoComplete::OnEditKeyDown(WPARAM wParam, LPARAM 
lParam)
             if (!CanAutoSuggest())
                 return FALSE; // do default
             ::DefSubclassProc(m_hwndEdit, WM_KEYDOWN, VK_DELETE, 0); // do 
default
-            UpdateCompletion(FALSE);
+            StartCompletion(FALSE);
             return TRUE; // eat
         }
         case VK_BACK:
@@ -973,7 +993,7 @@ LRESULT CAutoComplete::OnEditChar(WPARAM wParam, LPARAM 
lParam)
         return 0; // eat
     LRESULT ret = ::DefSubclassProc(m_hwndEdit, WM_CHAR, wParam, lParam); // 
do default
     if (CanAutoSuggest() || CanAutoAppend())
-        UpdateCompletion(wParam != VK_BACK);
+        StartCompletion(wParam != VK_BACK);
     return ret;
 }
 
@@ -1212,7 +1232,8 @@ STDMETHODIMP CAutoComplete::ResetEnumerator()
     FIXME("(%p): stub\n", this);
 
     Reset();
-    m_innerList.RemoveAll();
+    m_hwndList.SendMessageW(LVM_SETITEMCOUNT, 0, 0);
+    m_outerList.RemoveAll();
     return S_OK;
 }
 
@@ -1444,217 +1465,59 @@ VOID CAutoComplete::RepositionDropDown()
     ShowWindow(SW_SHOWNOACTIVATE);
 }
 
-inline BOOL
-CAutoComplete::DoesMatch(const CStringW& strTarget, const CStringW& strText) 
const
+VOID
+CAutoComplete::ExtractInnerList(CSimpleArray<CStringW>& outerList,
+                                const CSimpleArray<CStringW>& innerList,
+                                const CString& strText)
 {
-    CStringW strBody;
-    if (DropPrefix(strTarget, strBody))
-    {
-        if (::StrCmpNIW(strBody, strText, strText.GetLength()) == 0)
-            return TRUE;
-    }
-    else if (::StrCmpNIW(strTarget, strText, strText.GetLength()) == 0)
+    for (INT iItem = 0; iItem < innerList.GetSize(); ++iItem)
     {
-        return TRUE;
-    }
-    return FALSE;
-}
+        if (m_pThread || !m_hThread)
+            break;
 
-VOID CAutoComplete::ScrapeOffList(const CStringW& strText, 
CSimpleArray<CStringW>& array)
-{
-    for (INT iItem = array.GetSize() - 1; iItem >= 0; --iItem)
-    {
-        if (!DoesMatch(array[iItem], strText))
-            array.RemoveAt(iItem);
+        const CStringW& strTarget = innerList[iItem];
+        if (DoesMatch(strTarget, strText))
+        {
+            outerList.Add(strTarget);
+
+            if (outerList.GetSize() >= MAX_ITEM_COUNT)
+                break;
+        }
     }
 }
 
-VOID CAutoComplete::ReLoadInnerList(const CStringW& strText)
+VOID CAutoComplete::ReLoadInnerList(PAC_THREAD pThread)
 {
-    m_innerList.RemoveAll(); // clear contents
-    m_bPartialList = FALSE;
+    pThread->m_innerList.RemoveAll(); // clear contents
 
-    if (!m_pEnum || strText.IsEmpty())
+    if (!m_pEnum || pThread->m_strText.IsEmpty())
         return;
 
     // reload the items
     LPWSTR pszItem;
     ULONG cGot;
-    CStringW strTarget;
     HRESULT hr;
-    for (;;)
+    CSimpleArray<CStringW>& innerList = pThread->m_innerList;
+    while (!m_pThread && m_hThread)
     {
         // get next item
         hr = m_pEnum->Next(1, &pszItem, &cGot);
-        //TRACE("m_pEnum->Next(%p): 0x%08lx\n", reinterpret_cast<IUnknown 
*>(m_pEnum), hr);
         if (hr != S_OK)
             break;
 
-        strTarget = pszItem;
+        innerList.Add(pszItem); // append item to innerList
         ::CoTaskMemFree(pszItem); // free
-
-        if (m_bPartialList) // if items are too many
-        {
-            // do filter the items
-            if (DoesMatch(strTarget, strText))
-            {
-                m_innerList.Add(strTarget);
-
-                if (m_innerList.GetSize() >= MAX_ITEM_COUNT)
-                    break;
-            }
-        }
-        else
-        {
-            m_innerList.Add(strTarget); // append item to m_innerList
-
-            // if items are too many
-            if (m_innerList.GetSize() >= MAX_ITEM_COUNT)
-            {
-                // filter the items now
-                m_bPartialList = TRUE;
-                ScrapeOffList(strText, m_innerList);
-
-                if (m_innerList.GetSize() >= MAX_ITEM_COUNT)
-                    break;
-            }
-        }
-
-        // check the timeout
-        if (::GetTickCount() - m_dwTick >= COMPLETION_TIMEOUT)
-            break; // too late
     }
 }
 
-// update inner list and m_strText and m_strStemText
-VOID CAutoComplete::UpdateInnerList(const CStringW& strText)
+VOID CAutoComplete::StartCompletion(BOOL bAppendOK)
 {
-    BOOL bReset = FALSE, bExpand = FALSE; // flags
-
-    // if previous text was empty
-    if (m_strText.IsEmpty())
-    {
-        bReset = TRUE;
-    }
-    // save text
-    m_strText = strText;
-
-    // do expand the items if the stem is changed
-    CStringW strStemText = GetStemText(strText);
-    if (m_strStemText.CompareNoCase(strStemText) != 0)
-    {
-        m_strStemText = strStemText;
-        bReset = TRUE;
-        bExpand = !m_strStemText.IsEmpty();
-    }
-
-    // if the previous enumeration is too large
-    if (m_bPartialList)
-        bReset = bExpand = TRUE; // retry enumeratation
-
-    // reset if necessary
-    if (bReset && m_pEnum)
-    {
-        HRESULT hr = m_pEnum->Reset(); // IEnumString::Reset
-        TRACE("m_pEnum->Reset(%p): 0x%08lx\n",
-              static_cast<IUnknown *>(m_pEnum), hr);
-    }
-
-    // update ac list if necessary
-    if (bExpand && m_pACList)
-    {
-        HRESULT hr = m_pACList->Expand(strStemText); // IACList::Expand
-        TRACE("m_pACList->Expand(%p, %S): 0x%08lx\n",
-              static_cast<IUnknown *>(m_pACList),
-              static_cast<LPCWSTR>(strStemText), hr);
-    }
-
-    if (bExpand || m_innerList.GetSize() == 0)
-    {
-        // reload the inner list
-        ReLoadInnerList(strText);
-    }
-}
+    TRACE("CAutoComplete::StartCompletion(%p, %d)\n", this, bAppendOK);
 
-VOID CAutoComplete::UpdateOuterList(const CStringW& strText)
-{
-    if (strText.IsEmpty())
-    {
-        m_outerList.RemoveAll();
+    if (!m_pEnum || (!CanAutoSuggest() && !CanAutoAppend()))
         return;
-    }
-
-    if (m_bPartialList)
-    {
-        // it is already filtered
-        m_outerList = m_innerList;
-    }
-    else
-    {
-        // do filtering
-        m_outerList.RemoveAll();
-        for (INT iItem = 0; iItem < m_innerList.GetSize(); ++iItem)
-        {
-            const CStringW& strTarget = m_innerList[iItem];
-
-            if (DoesMatch(strTarget, strText))
-                m_outerList.Add(strTarget);
 
-            // check the timeout
-            if (::GetTickCount() - m_dwTick >= COMPLETION_TIMEOUT)
-                break; // too late
-        }
-    }
-
-    if (::GetTickCount() - m_dwTick < COMPLETION_TIMEOUT)
-    {
-        // sort and unique
-        DoSort(m_outerList);
-        DoUniqueAndTrim(m_outerList);
-    }
-
-    // set the item count of the virtual listview
-    m_hwndList.SendMessageW(LVM_SETITEMCOUNT, m_outerList.GetSize(), 0);
-}
-
-VOID CAutoComplete::UpdateCompletion(BOOL bAppendOK)
-{
-    TRACE("CAutoComplete::UpdateCompletion(%p, %d)\n", this, bAppendOK);
-
-    m_dwTick = GetTickCount(); // to check the timeout
-
-    CStringW strText = GetEditText();
-    if (m_strText.CompareNoCase(strText) == 0)
-    {
-        // no change
-        return;
-    }
-
-    // update inner list
-    UpdateInnerList(strText);
-    if (m_innerList.GetSize() <= 0) // no items
-    {
-        HideDropDown();
-        return;
-    }
-
-    if (CanAutoSuggest()) // can we auto-suggest?
-    {
-        m_bInSelectItem = TRUE; // don't respond
-        SelectItem(-1); // select none
-        m_bInSelectItem = FALSE;
-
-        UpdateOuterList(strText);
-        if (m_outerList.GetSize() > 0)
-            RepositionDropDown();
-        else
-            HideDropDown();
-    }
-
-    if (CanAutoAppend() && bAppendOK) // can we auto-append?
-    {
-        DoAutoAppend();
-    }
+    ::SendMessageW(m_hWnd, AUTOCOMP_START, bAppendOK, 0);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -2116,3 +1979,189 @@ LRESULT CAutoComplete::OnVScroll(UINT uMsg, WPARAM 
wParam, LPARAM lParam, BOOL &
     }
     return 0;
 }
+
+static inline PAC_THREAD
+InterlockedExchangeThreadData(volatile PAC_THREAD *Target, PAC_THREAD Value)
+{
+    return reinterpret_cast<PAC_THREAD>(
+        ::InterlockedExchangePointer(reinterpret_cast<volatile PVOID 
*>(Target), Value));
+}
+
+static unsigned __stdcall AutoCompThreadProc(void *arg)
+{
+    CAutoComplete* pThis = reinterpret_cast<CAutoComplete*>(arg);
+    pThis->AutoCompThreadProc();
+    return 0;
+}
+
+VOID CAutoComplete::AutoCompThreadProc()
+{
+    for (;;)
+    {
+        PAC_THREAD pThread = InterlockedExchangeThreadData(&m_pThread, NULL);
+        if (!pThread)
+            break;
+        DoThreadWork(pThread);
+    }
+}
+
+VOID CAutoComplete::DoThreadWork(PAC_THREAD pThread)
+{
+    if (pThread->m_bExpand || m_innerList.GetSize() == 0)
+    {
+        ReLoadInnerList(pThread);
+    }
+    else
+    {
+        pThread->m_innerList = m_innerList;
+    }
+
+    if (m_pThread || !m_hThread)
+    {
+        delete pThread;
+        return;
+    }
+
+    ExtractInnerList(pThread->m_outerList, pThread->m_innerList, 
pThread->m_strText);
+
+    if (m_pThread || !m_hThread)
+    {
+        delete pThread;
+        return;
+    }
+
+    DoSort(pThread->m_outerList);
+    DoUniqueAndTrim(pThread->m_outerList);
+
+    if (m_pThread || !m_hThread ||
+        !::PostMessageW(m_hWnd, AUTOCOMP_FINISH, 0, (LPARAM)pThread))
+    {
+        delete pThread;
+    }
+}
+
+// AUTOCOMP_START
+LRESULT CAutoComplete::OnAutoCompStart(UINT uMsg, WPARAM wParam, LPARAM 
lParam, BOOL &bHandled)
+{
+    BOOL bAppendOK = (BOOL)wParam;
+
+    CStringW strText = GetEditText();
+    if (m_strText.CompareNoCase(strText) == 0)
+    {
+        // no change
+        return 0;
+    }
+
+    PAC_THREAD pThread = new AC_THREAD { this, bAppendOK, strText };
+
+    // if previous text was empty
+    if (m_strText.IsEmpty())
+    {
+        pThread->m_bReset = TRUE;
+    }
+    m_strText = strText;
+
+    // do expand the items if the stem is changed
+    CStringW strStemText = GetStemText(pThread->m_strText);
+    if (m_strStemText.CompareNoCase(strStemText) != 0)
+    {
+        pThread->m_bReset = TRUE;
+        pThread->m_bExpand = !strStemText.IsEmpty();
+        m_strStemText = strStemText;
+    }
+
+    // reset if necessary
+    if (pThread->m_bReset && m_pEnum)
+    {
+        HRESULT hr = m_pEnum->Reset(); // IEnumString::Reset
+        TRACE("m_pEnum->Reset(%p): 0x%08lx\n",
+              static_cast<IUnknown *>(m_pEnum), hr);
+    }
+
+    // update ac list if necessary
+    if (pThread->m_bExpand && m_pACList)
+    {
+        HRESULT hr = m_pACList->Expand(strStemText); // IACList::Expand
+        TRACE("m_pACList->Expand(%p, %S): 0x%08lx\n",
+              static_cast<IUnknown *>(m_pACList),
+              static_cast<LPCWSTR>(strStemText), hr);
+    }
+
+    PAC_THREAD pOld = InterlockedExchangeThreadData(&m_pThread, pThread);
+    if (pOld)
+        delete pOld;
+
+    BOOL bDoStart = FALSE;
+    DWORD dwWait = WaitForSingleObject(m_hThread, 0);
+    if (dwWait != WAIT_TIMEOUT)
+    {
+        CloseHandle(m_hThread);
+        bDoStart = TRUE;
+    }
+    else if (!m_hThread)
+    {
+        bDoStart = TRUE;
+    }
+
+    if (bDoStart)
+        m_hThread = (HANDLE)_beginthreadex(NULL, 0, ::AutoCompThreadProc, 
this, 0, NULL);
+
+    return 0;
+}
+
+// AUTOCOMP_FINISH
+LRESULT CAutoComplete::OnAutoCompFinish(UINT uMsg, WPARAM wParam, LPARAM 
lParam, BOOL &bHandled)
+{
+    PAC_THREAD pThread = reinterpret_cast<PAC_THREAD>(lParam);
+    if (m_pThread == NULL)
+    {
+        FinishCompletion(pThread);
+    }
+    CloseHandle(m_hThread);
+    m_hThread = NULL;
+    delete pThread;
+    return 0;
+}
+
+VOID CAutoComplete::FinishCompletion(PAC_THREAD pThread)
+{
+    if (m_pThread || !m_hThread)
+        return;
+
+    if (!CanAutoSuggest() && !CanAutoAppend())
+        return;
+
+    if (m_pThread || !m_hThread)
+        return;
+
+    // set inner list
+    m_innerList = pThread->m_innerList;
+
+    if (m_pThread || !m_hThread)
+        return;
+
+    // set the items of the virtual listview
+    m_outerList = pThread->m_outerList; // FIXME: We need more speed!
+    m_hwndList.SendMessageW(LVM_SETITEMCOUNT, m_outerList.GetSize(), 0);
+
+    // save text
+    m_strText = pThread->m_strText;
+    m_strStemText = GetStemText(m_strText);
+
+    if (CanAutoSuggest()) // can we auto-suggest?
+    {
+        m_bInSelectItem = TRUE; // don't respond
+        SelectItem(-1); // select none
+        m_bInSelectItem = FALSE;
+
+        if (m_outerList.GetSize() > 0)
+            RepositionDropDown();
+        else
+            HideDropDown();
+    }
+
+    if (CanAutoAppend() && pThread->m_bAppendOK) // can we auto-append?
+    {
+        DoAutoAppend(pThread);
+    }
+}
diff --git a/dll/win32/browseui/CAutoComplete.h 
b/dll/win32/browseui/CAutoComplete.h
index 51ef81b135a..586a878d154 100644
--- a/dll/win32/browseui/CAutoComplete.h
+++ b/dll/win32/browseui/CAutoComplete.h
@@ -116,11 +116,30 @@ protected:
     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>
@@ -156,10 +175,15 @@ public:
     VOID ShowDropDown();
     VOID HideDropDown();
     VOID SelectItem(INT iItem);
-    VOID DoAutoAppend();
+    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);
@@ -194,8 +218,8 @@ protected:
     HWND m_hwndEdit; // the textbox
     WNDPROC m_fnOldEditProc; // old textbox procedure
     EDITWORDBREAKPROCW m_fnOldWordBreakProc;
-    BOOL m_bPartialList; // is the list partial?
-    DWORD m_dwTick; // to check timeout
+    HANDLE m_hThread;
+    AC_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 + '\\'
@@ -205,22 +229,22 @@ protected:
     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
+    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(const CStringW& strText);
-    VOID UpdateInnerList(const CStringW& strText);
-    VOID UpdateOuterList(const CStringW& strText);
-    VOID UpdateCompletion(BOOL bAppendOK);
-    VOID ScrapeOffList(const CStringW& strText, CSimpleArray<CStringW>& array);
-    BOOL DoesMatch(const CStringW& strTarget, const CStringW& strText) const;
+    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)
@@ -253,6 +277,8 @@ protected:
     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);
 
     DECLARE_REGISTRY_RESOURCEID(IDR_AUTOCOMPLETE)
     DECLARE_NOT_AGGREGATABLE(CAutoComplete)

Reply via email to