From 12e95836ecacead8bdd69cad4fdf5e9ad9321c0a Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Mon, 4 Jul 2005 17:22:18 +0000 Subject: [PATCH] add a quick search feature to the checklist control svn path=/trunk/; revision=16410 --- reactos/lib/aclui/aclui.c | 6 + reactos/lib/aclui/acluilib.h | 3 + reactos/lib/aclui/checklist.c | 646 ++++++++++++++++++++++++++++++++-- 3 files changed, 621 insertions(+), 34 deletions(-) diff --git a/reactos/lib/aclui/aclui.c b/reactos/lib/aclui/aclui.c index c7121c007b4..9f55849e538 100644 --- a/reactos/lib/aclui/aclui.c +++ b/reactos/lib/aclui/aclui.c @@ -705,6 +705,12 @@ SecurityPageProc(IN HWND hwndDlg, ShowWindow(GetDlgItem(hwndDlg, IDC_LABEL_ADVANCED), SW_HIDE); } + + /* enable quicksearch for the permissions checklist control */ + SendMessage(sp->hAceCheckList, + CLM_ENABLEQUICKSEARCH, + TRUE, + 0); } break; } diff --git a/reactos/lib/aclui/acluilib.h b/reactos/lib/aclui/acluilib.h index 35929fc4f97..af27316b233 100644 --- a/reactos/lib/aclui/acluilib.h +++ b/reactos/lib/aclui/acluilib.h @@ -102,6 +102,9 @@ ListViewSelectItem(IN HWND hwnd, #define CLM_GETCHECKBOXCOLUMN (WM_USER + 6) #define CLM_CLEARCHECKBOXES (WM_USER + 7) #define CLM_SETITEMSTATE (WM_USER + 8) +#define CLM_ENABLEQUICKSEARCH (WM_USER + 9) +#define CLM_SETQUICKSEARCH_TIMEOUT_RESET (WM_USER + 10) +#define CLM_SETQUICKSEARCH_TIMEOUT_SETFOCUS (WM_USER + 11) BOOL RegisterCheckListControl(HINSTANCE hInstance); diff --git a/reactos/lib/aclui/checklist.c b/reactos/lib/aclui/checklist.c index be2eb210155..86758b28457 100644 --- a/reactos/lib/aclui/checklist.c +++ b/reactos/lib/aclui/checklist.c @@ -28,6 +28,16 @@ */ #include "acluilib.h" +#define CI_TEXT_MARGIN_WIDTH (8) +#define CI_TEXT_MARGIN_HEIGHT (3) +#define CI_TEXT_SELECTIONMARGIN (1) + +#define TIMER_ID_SETHITFOCUS (1) +#define TIMER_ID_RESETQUICKSEARCH (2) + +#define DEFAULT_QUICKSEARCH_SETFOCUS_DELAY (2000) +#define DEFAULT_QUICKSEARCH_RESET_DELAY (3000) + typedef struct _CHECKITEM { struct _CHECKITEM *Next; @@ -54,6 +64,15 @@ typedef struct _CHECKLISTWND COLORREF TextColor[2]; UINT CheckBoxLeft[2]; + + BOOL QuickSearchEnabled; + PCHECKITEM QuickSearchHitItem; + WCHAR QuickSearchText[65]; + UINT QuickSearchSetFocusDelay; + UINT QuickSearchResetDelay; + + DWORD CaretWidth; + BOOL ShowingCaret; #if SUPPORT_UXTHEME PCHECKITEM HoveredCheckItem; @@ -64,8 +83,17 @@ typedef struct _CHECKLISTWND #endif } CHECKLISTWND, *PCHECKLISTWND; -#define CI_TEXT_MARGIN_WIDTH (8) -#define CI_TEXT_MARGIN_HEIGHT (3) +static VOID EscapeQuickSearch(IN PCHECKLISTWND infoPtr); +#if SUPPORT_UXTHEME +static VOID ChangeCheckItemHotTrack(IN PCHECKLISTWND infoPtr, + IN PCHECKITEM NewHotTrack, + IN UINT NewHotTrackBox); +#endif +static VOID ChangeCheckItemFocus(IN PCHECKLISTWND infoPtr, + IN PCHECKITEM NewFocus, + IN UINT NewFocusBox); + +/******************************************************************************/ static PCHECKITEM FindCheckItemByIndex(IN PCHECKLISTWND infoPtr, @@ -112,6 +140,27 @@ CheckItemToIndex(IN PCHECKLISTWND infoPtr, return -1; } +static PCHECKITEM +FindCheckItem(IN PCHECKLISTWND infoPtr, + IN LPWSTR SearchText) +{ + PCHECKITEM CurItem; + SIZE_T Count = wcslen(SearchText); + + for (CurItem = infoPtr->CheckItemListHead; + CurItem != NULL; + CurItem = CurItem->Next) + { + if ((CurItem->State & CIS_DISABLED) != CIS_DISABLED && + !wcsnicmp(CurItem->Name, SearchText, Count)) + { + break; + } + } + + return CurItem; +} + static PCHECKITEM FindFirstEnabledCheckBox(IN PCHECKLISTWND infoPtr, OUT UINT *CheckBox) @@ -366,6 +415,27 @@ DeleteCheckItem(IN PCHECKLISTWND infoPtr, { if (CurItem == Item) { + if (Item == infoPtr->QuickSearchHitItem && infoPtr->QuickSearchEnabled) + { + EscapeQuickSearch(infoPtr); + } + +#if SUPPORT_UXTHEME + if (Item == infoPtr->HoveredCheckItem) + { + ChangeCheckItemHotTrack(infoPtr, + NULL, + 0); + } +#endif + + if (Item == infoPtr->FocusedCheckItem) + { + ChangeCheckItemFocus(infoPtr, + NULL, + 0); + } + *PrevPtr = CurItem->Next; HeapFree(GetProcessHeap(), 0, @@ -608,7 +678,7 @@ MakeCheckItemVisible(IN PCHECKLISTWND infoPtr, NULL, NULL, NULL, - SW_INVALIDATE); + SW_INVALIDATE | SW_SCROLLCHILDREN); RedrawWindow(infoPtr->hSelf, NULL, @@ -664,7 +734,16 @@ RetChangeControlFont(IN PCHECKLISTWND infoPtr, { infoPtr->ItemHeight = (2 * CI_TEXT_MARGIN_HEIGHT) + GetIdealItemHeight(infoPtr); } - + + if (infoPtr->ShowingCaret) + { + DestroyCaret(); + CreateCaret(infoPtr->hSelf, + NULL, + 0, + infoPtr->ItemHeight - (2 * CI_TEXT_MARGIN_HEIGHT)); + } + UpdateControl(infoPtr, TRUE); @@ -788,14 +867,73 @@ PaintControl(IN PCHECKLISTWND infoPtr, #if SUPPORT_UXTHEME ItemHovered = (Enabled && infoPtr->HoveredCheckItem == Item); #endif - - /* draw the text */ - DrawText(hDC, - Item->Name, - -1, - &TextRect, - DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER); + if (infoPtr->QuickSearchHitItem == Item) + { + COLORREF OldBkColor, OldFgColor; + SIZE TextSize; + SIZE_T TextLen, HighlightLen = wcslen(infoPtr->QuickSearchText); + + /* highlight the quicksearch text */ + if (GetTextExtentPoint32(hDC, + Item->Name, + HighlightLen, + &TextSize)) + { + COLORREF HighlightTextColor, HighlightBackground; + RECT rcHighlight = TextRect; + + HighlightTextColor = GetSysColor(COLOR_HIGHLIGHTTEXT); + HighlightBackground = GetSysColor(COLOR_HIGHLIGHT); + + rcHighlight.right = rcHighlight.left + TextSize.cx; + + InflateRect(&rcHighlight, + 0, + CI_TEXT_SELECTIONMARGIN); + + OldBkColor = SetBkColor(hDC, + HighlightBackground); + OldFgColor = SetTextColor(hDC, + HighlightTextColor); + + /* draw the highlighted text */ + DrawText(hDC, + Item->Name, + HighlightLen, + &rcHighlight, + DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER); + + SetBkColor(hDC, + OldBkColor); + SetTextColor(hDC, + OldFgColor); + + /* draw the remaining part of the text */ + TextLen = wcslen(Item->Name); + if (HighlightLen < TextLen) + { + rcHighlight.left = rcHighlight.right; + rcHighlight.right = TextRect.right; + + DrawText(hDC, + Item->Name + HighlightLen, + -1, + &rcHighlight, + DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER); + } + } + } + else + { + /* draw the text */ + DrawText(hDC, + Item->Name, + -1, + &TextRect, + DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER); + } + CheckBox.top = TextRect.top; CheckBox.bottom = TextRect.bottom; @@ -1059,6 +1197,295 @@ ChangeCheckBox(IN PCHECKLISTWND infoPtr, CheckItem->State = NewState; } +static VOID +DisplayCaret(IN PCHECKLISTWND infoPtr) +{ + if (IsWindowEnabled(infoPtr->hSelf) && !infoPtr->ShowingCaret) + { + infoPtr->ShowingCaret = TRUE; + + CreateCaret(infoPtr->hSelf, + NULL, + infoPtr->CaretWidth, + infoPtr->ItemHeight - (2 * CI_TEXT_MARGIN_HEIGHT)); + + ShowCaret(infoPtr->hSelf); + } +} + +static VOID +RemoveCaret(IN PCHECKLISTWND infoPtr) +{ + if (IsWindowEnabled(infoPtr->hSelf) && infoPtr->ShowingCaret) + { + infoPtr->ShowingCaret = FALSE; + + HideCaret(infoPtr->hSelf); + DestroyCaret(); + } +} + +static VOID +KillQuickSearchTimers(IN PCHECKLISTWND infoPtr) +{ + KillTimer(infoPtr->hSelf, + TIMER_ID_SETHITFOCUS); + KillTimer(infoPtr->hSelf, + TIMER_ID_RESETQUICKSEARCH); +} + +static VOID +MapItemToRect(IN PCHECKLISTWND infoPtr, + IN PCHECKITEM CheckItem, + OUT RECT *prcItem) +{ + INT Index = CheckItemToIndex(infoPtr, + CheckItem); + if (Index != -1) + { + RECT rcClient; + LONG Style; + INT VisibleFirst; + + GetClientRect(infoPtr->hSelf, &rcClient); + + Style = GetWindowLong(infoPtr->hSelf, + GWL_STYLE); + + if (Style & WS_VSCROLL) + { + VisibleFirst = GetScrollPos(infoPtr->hSelf, + SB_VERT); + } + else + { + VisibleFirst = 0; + } + + prcItem->left = rcClient.left; + prcItem->right = rcClient.right; + prcItem->top = (Index - VisibleFirst) * infoPtr->ItemHeight; + prcItem->bottom = prcItem->top + infoPtr->ItemHeight; + } + else + { + prcItem->left = 0; + prcItem->top = 0; + prcItem->right = 0; + prcItem->bottom = 0; + } +} + +static VOID +UpdateCaretPos(IN PCHECKLISTWND infoPtr) +{ + if (infoPtr->ShowingCaret && infoPtr->QuickSearchHitItem != NULL) + { + HDC hDC = GetDC(infoPtr->hSelf); + if (hDC != NULL) + { + SIZE TextSize; + HGDIOBJ hOldFont = SelectObject(hDC, + infoPtr->hFont); + + TextSize.cx = 0; + TextSize.cy = 0; + + if (infoPtr->QuickSearchText[0] == L'\0' || + GetTextExtentPoint32(hDC, + infoPtr->QuickSearchHitItem->Name, + wcslen(infoPtr->QuickSearchText), + &TextSize)) + { + RECT rcItem; + + MapItemToRect(infoPtr, + infoPtr->QuickSearchHitItem, + &rcItem); + + /* actually change the caret position */ + SetCaretPos(rcItem.left + CI_TEXT_MARGIN_WIDTH + TextSize.cx, + rcItem.top + CI_TEXT_MARGIN_HEIGHT); + } + + SelectObject(hDC, + hOldFont); + + ReleaseDC(infoPtr->hSelf, + hDC); + } + } +} + +static VOID +EscapeQuickSearch(IN PCHECKLISTWND infoPtr) +{ + if (infoPtr->QuickSearchEnabled && infoPtr->QuickSearchHitItem != NULL) + { + PCHECKITEM OldHit = infoPtr->QuickSearchHitItem; + + infoPtr->QuickSearchHitItem = NULL; + infoPtr->QuickSearchText[0] = L'\0'; + + /* scroll back to the focused item */ + if (infoPtr->FocusedCheckItem != NULL) + { + MakeCheckItemVisible(infoPtr, + infoPtr->FocusedCheckItem); + } + + /* repaint the old search hit item if it's still visible */ + UpdateCheckItem(infoPtr, + OldHit); + + KillQuickSearchTimers(infoPtr); + + RemoveCaret(infoPtr); + } +} + +static VOID +ChangeSearchHit(IN PCHECKLISTWND infoPtr, + IN PCHECKITEM NewHit) +{ + PCHECKITEM OldHit = infoPtr->QuickSearchHitItem; + + infoPtr->QuickSearchHitItem = NewHit; + + if (OldHit != NewHit) + { + /* scroll to the new search hit */ + MakeCheckItemVisible(infoPtr, + NewHit); + + /* repaint the old hit if present and visible */ + if (OldHit != NULL) + { + UpdateCheckItem(infoPtr, + OldHit); + } + else + { + /* show the caret the first time we find an item */ + DisplayCaret(infoPtr); + } + } + + UpdateCaretPos(infoPtr); + + UpdateCheckItem(infoPtr, + NewHit); + + /* kill the reset timer and restart the set hit focus timer */ + KillTimer(infoPtr->hSelf, + TIMER_ID_RESETQUICKSEARCH); + if (infoPtr->QuickSearchSetFocusDelay != 0) + { + SetTimer(infoPtr->hSelf, + TIMER_ID_SETHITFOCUS, + infoPtr->QuickSearchSetFocusDelay, + NULL); + } +} + +static BOOL +QuickSearchFindHit(IN PCHECKLISTWND infoPtr, + IN WCHAR c) +{ + if (infoPtr->QuickSearchEnabled) + { + BOOL Ret = FALSE; + PCHECKITEM NewHit; + + switch (c) + { + case '\r': + case '\n': + { + Ret = infoPtr->QuickSearchHitItem != NULL; + if (Ret) + { + /* NOTE: QuickSearchHitItem definitely has at least one + enabled check box, the user can't search for disabled + check items */ + + ChangeCheckItemFocus(infoPtr, + infoPtr->QuickSearchHitItem, + ((!(infoPtr->QuickSearchHitItem->State & CIS_ALLOWDISABLED)) ? CLB_ALLOW : CLB_DENY)); + + EscapeQuickSearch(infoPtr); + } + break; + } + + case VK_BACK: + { + if (infoPtr->QuickSearchHitItem != NULL) + { + INT SearchLen = wcslen(infoPtr->QuickSearchText); + if (SearchLen > 0) + { + /* delete the last character */ + infoPtr->QuickSearchText[--SearchLen] = L'\0'; + + if (SearchLen > 0) + { + /* search again */ + NewHit = FindCheckItem(infoPtr, + infoPtr->QuickSearchText); + + if (NewHit != NULL) + { + /* change the search hit */ + ChangeSearchHit(infoPtr, + NewHit); + + Ret = TRUE; + } + } + } + + if (!Ret) + { + EscapeQuickSearch(infoPtr); + } + } + break; + } + + default: + { + INT SearchLen = wcslen(infoPtr->QuickSearchText); + if (SearchLen < (sizeof(infoPtr->QuickSearchText) / sizeof(infoPtr->QuickSearchText[0])) - 1) + { + infoPtr->QuickSearchText[SearchLen++] = c; + infoPtr->QuickSearchText[SearchLen] = L'\0'; + + NewHit = FindCheckItem(infoPtr, + infoPtr->QuickSearchText); + if (NewHit != NULL) + { + /* change the search hit */ + ChangeSearchHit(infoPtr, + NewHit); + + Ret = TRUE; + } + else + { + /* reset the input */ + infoPtr->QuickSearchText[--SearchLen] = L'\0'; + } + } + break; + } + } + return Ret; + } + + return FALSE; +} + static LRESULT CALLBACK CheckListWndProc(IN HWND hwnd, IN UINT uMsg, @@ -1292,7 +1719,7 @@ CheckListWndProc(IN HWND hwnd, NULL, NULL, NULL, - SW_INVALIDATE); + SW_INVALIDATE | SW_SCROLLCHILDREN); RedrawWindow(hwnd, NULL, @@ -1427,6 +1854,28 @@ CheckListWndProc(IN HWND hwnd, break; } + case CLM_ENABLEQUICKSEARCH: + { + if (wParam == 0) + { + EscapeQuickSearch(infoPtr); + } + infoPtr->QuickSearchEnabled = (wParam != 0); + break; + } + + case CLM_SETQUICKSEARCH_TIMEOUT_RESET: + { + infoPtr->QuickSearchResetDelay = (UINT)wParam; + break; + } + + case CLM_SETQUICKSEARCH_TIMEOUT_SETFOCUS: + { + infoPtr->QuickSearchSetFocusDelay = (UINT)wParam; + break; + } + case WM_SETFONT: { Ret = (LRESULT)RetChangeControlFont(infoPtr, @@ -1461,6 +1910,8 @@ CheckListWndProc(IN HWND hwnd, case WM_ENABLE: { + EscapeQuickSearch(infoPtr); + UpdateControl(infoPtr, TRUE); break; @@ -1515,7 +1966,7 @@ CheckListWndProc(IN HWND hwnd, NULL, NULL, NULL, - SW_INVALIDATE); + SW_INVALIDATE | SW_SCROLLCHILDREN); RedrawWindow(hwnd, NULL, @@ -1552,6 +2003,8 @@ CheckListWndProc(IN HWND hwnd, case WM_KILLFOCUS: { + EscapeQuickSearch(infoPtr); + infoPtr->HasFocus = FALSE; if (infoPtr->FocusedCheckItem != NULL) { @@ -1617,6 +2070,12 @@ CheckListWndProc(IN HWND hwnd, if (ChangeFocus) { + if (infoPtr->QuickSearchEnabled && infoPtr->QuickSearchHitItem != NULL && + infoPtr->QuickSearchHitItem != NewFocus) + { + EscapeQuickSearch(infoPtr); + } + ChangeCheckItemFocus(infoPtr, NewFocus, NewFocusBox); @@ -1680,19 +2139,26 @@ CheckListWndProc(IN HWND hwnd, { case VK_SPACE: { - if (infoPtr->FocusedCheckItem != NULL && GetCapture() == NULL) + if (GetCapture() == NULL && + !QuickSearchFindHit(infoPtr, + L' ')) { - BOOL OldPushed = infoPtr->FocusedPushed; - infoPtr->FocusedPushed = TRUE; - - if (infoPtr->FocusedPushed != OldPushed) + if (infoPtr->FocusedCheckItem != NULL && + (infoPtr->QuickSearchHitItem == NULL || + infoPtr->QuickSearchHitItem == infoPtr->FocusedCheckItem)) { - MakeCheckItemVisible(infoPtr, - infoPtr->FocusedCheckItem); + BOOL OldPushed = infoPtr->FocusedPushed; + infoPtr->FocusedPushed = TRUE; - UpdateCheckItemBox(infoPtr, - infoPtr->FocusedCheckItem, - infoPtr->FocusedCheckItemBox); + if (infoPtr->FocusedPushed != OldPushed) + { + MakeCheckItemVisible(infoPtr, + infoPtr->FocusedCheckItem); + + UpdateCheckItemBox(infoPtr, + infoPtr->FocusedCheckItem, + infoPtr->FocusedCheckItemBox); + } } } break; @@ -1700,18 +2166,24 @@ CheckListWndProc(IN HWND hwnd, case VK_RETURN: { - if (infoPtr->FocusedCheckItem != NULL && GetCapture() == NULL) + if (GetCapture() == NULL && + !QuickSearchFindHit(infoPtr, + L'\n')) { - MakeCheckItemVisible(infoPtr, - infoPtr->FocusedCheckItem); + if (infoPtr->FocusedCheckItem != NULL && + infoPtr->QuickSearchHitItem == NULL) + { + MakeCheckItemVisible(infoPtr, + infoPtr->FocusedCheckItem); - ChangeCheckBox(infoPtr, - infoPtr->FocusedCheckItem, - infoPtr->FocusedCheckItemBox); - - UpdateCheckItemBox(infoPtr, + ChangeCheckBox(infoPtr, infoPtr->FocusedCheckItem, infoPtr->FocusedCheckItemBox); + + UpdateCheckItemBox(infoPtr, + infoPtr->FocusedCheckItem, + infoPtr->FocusedCheckItemBox); + } } break; } @@ -1723,6 +2195,8 @@ CheckListWndProc(IN HWND hwnd, PCHECKITEM NewFocus; UINT NewFocusBox = 0; BOOL Shift = GetKeyState(VK_SHIFT) & 0x8000; + + EscapeQuickSearch(infoPtr); NewFocus = FindEnabledCheckBox(infoPtr, Shift, @@ -1779,16 +2253,23 @@ CheckListWndProc(IN HWND hwnd, { INT virtKey; - Ret = DLGC_HASSETSEL; + Ret = 0; virtKey = (lParam != 0 ? (INT)((LPMSG)lParam)->wParam : 0); switch (virtKey) { case VK_RETURN: { - Ret |= DLGC_WANTMESSAGE; + if (infoPtr->QuickSearchEnabled && infoPtr->QuickSearchHitItem != NULL) + { + Ret |= DLGC_WANTCHARS | DLGC_WANTMESSAGE; + } + else + { + Ret |= DLGC_WANTMESSAGE; + } break; } - + case VK_TAB: { INT CheckBox; @@ -1801,10 +2282,26 @@ CheckListWndProc(IN HWND hwnd, Ret |= (EnabledBox ? DLGC_WANTTAB : DLGC_WANTCHARS); break; } + + default: + { + if (infoPtr->QuickSearchEnabled) + { + Ret |= DLGC_WANTCHARS; + } + break; + } } break; } + case WM_CHAR: + { + QuickSearchFindHit(infoPtr, + (WCHAR)wParam); + break; + } + case WM_SYSCOLORCHANGE: { infoPtr->TextColor[0] = GetSysColor(COLOR_GRAYTEXT); @@ -1843,6 +2340,8 @@ CheckListWndProc(IN HWND hwnd, case WM_SETTINGCHANGE: { + DWORD OldCaretWidth = infoPtr->CaretWidth; + #if SUPPORT_UXTHEME /* update the hover time */ if (!SystemParametersInfo(SPI_GETMOUSEHOVERTIME, @@ -1853,6 +2352,23 @@ CheckListWndProc(IN HWND hwnd, infoPtr->HoverTime = HOVER_DEFAULT; } #endif + + /* update the caret */ + if (!SystemParametersInfo(SPI_GETCARETWIDTH, + 0, + &infoPtr->CaretWidth, + 0)) + { + infoPtr->CaretWidth = 2; + } + if (OldCaretWidth != infoPtr->CaretWidth && infoPtr->ShowingCaret) + { + DestroyCaret(); + CreateCaret(hwnd, + NULL, + infoPtr->CaretWidth, + infoPtr->ItemHeight - (2 * CI_TEXT_MARGIN_HEIGHT)); + } break; } @@ -1881,6 +2397,49 @@ CheckListWndProc(IN HWND hwnd, } break; } + + case WM_TIMER: + { + switch (wParam) + { + case TIMER_ID_SETHITFOCUS: + { + /* kill the timer */ + KillTimer(hwnd, + wParam); + + if (infoPtr->QuickSearchEnabled && infoPtr->QuickSearchHitItem != NULL) + { + /* change the focus to the hit item, this item has to have + at least one enabled checkbox! */ + ChangeCheckItemFocus(infoPtr, + infoPtr->QuickSearchHitItem, + ((!(infoPtr->QuickSearchHitItem->State & CIS_ALLOWDISABLED)) ? CLB_ALLOW : CLB_DENY)); + + /* start the timer to reset quicksearch */ + if (infoPtr->QuickSearchResetDelay != 0) + { + SetTimer(hwnd, + TIMER_ID_RESETQUICKSEARCH, + infoPtr->QuickSearchResetDelay, + NULL); + } + } + break; + } + case TIMER_ID_RESETQUICKSEARCH: + { + /* kill the timer */ + KillTimer(hwnd, + wParam); + + /* escape quick search */ + EscapeQuickSearch(infoPtr); + break; + } + } + break; + } case WM_CREATE: { @@ -1901,7 +2460,15 @@ CheckListWndProc(IN HWND hwnd, infoPtr->CheckItemListHead = NULL; infoPtr->CheckItemCount = 0; + if (!SystemParametersInfo(SPI_GETCARETWIDTH, + 0, + &infoPtr->CaretWidth, + 0)) + { + infoPtr->CaretWidth = 2; + } infoPtr->ItemHeight = 10; + infoPtr->ShowingCaret = FALSE; infoPtr->HasFocus = FALSE; infoPtr->FocusedCheckItem = NULL; @@ -1915,6 +2482,12 @@ CheckListWndProc(IN HWND hwnd, infoPtr->CheckBoxLeft[0] = rcClient.right - 30; infoPtr->CheckBoxLeft[1] = rcClient.right - 15; + + infoPtr->QuickSearchEnabled = FALSE; + infoPtr->QuickSearchText[0] = L'\0'; + + infoPtr->QuickSearchSetFocusDelay = DEFAULT_QUICKSEARCH_SETFOCUS_DELAY; + infoPtr->QuickSearchResetDelay = DEFAULT_QUICKSEARCH_RESET_DELAY; #if SUPPORT_UXTHEME infoPtr->HoveredCheckItem = NULL; @@ -1952,6 +2525,11 @@ CheckListWndProc(IN HWND hwnd, case WM_DESTROY: { + if (infoPtr->ShowingCaret) + { + DestroyCaret(); + } + ClearCheckItems(infoPtr); #if SUPPORT_UXTHEME