⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 checklist.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
        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 < (INT)(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,
                 IN WPARAM wParam,
                 IN LPARAM lParam)
{
    PCHECKLISTWND infoPtr;
    LRESULT Ret;
    
    infoPtr = (PCHECKLISTWND)GetWindowLongPtr(hwnd,
                                              0);
    
    if (infoPtr == NULL && uMsg != WM_CREATE)
    {
        goto HandleDefaultMessage;
    }
    
    Ret = 0;
    
    switch (uMsg)
    {
        case WM_PAINT:
        {
            HDC hdc;
            RECT rcUpdate;
            PAINTSTRUCT ps;
            
            if (GetUpdateRect(hwnd,
                              &rcUpdate,
                              FALSE))
            {
                hdc = (wParam != 0 ? (HDC)wParam : BeginPaint(hwnd, &ps));

                if (hdc != NULL)
                {
                    PaintControl(infoPtr,
                                 hdc,
                                 &rcUpdate);

                    if (wParam == 0)
                    {
                        EndPaint(hwnd,
                                 &ps);
                    }
                }
            }
            break;
        }
        
        case WM_MOUSEMOVE:
        {
            POINT pt;
            BOOL InCheckBox;
            HWND hWndCapture = GetCapture();
            
            pt.x = (LONG)LOWORD(lParam);
            pt.y = (LONG)HIWORD(lParam);
            
#if SUPPORT_UXTHEME
            /* handle hovering checkboxes */
            if (hWndCapture == NULL && infoPtr->ThemeHandle != NULL)
            {
                TRACKMOUSEEVENT tme;
                PCHECKITEM HotTrackItem;
                UINT HotTrackItemBox;

                HotTrackItem = PtToCheckItemBox(infoPtr,
                                                &pt,
                                                &HotTrackItemBox,
                                                &InCheckBox);
                if (HotTrackItem != NULL && InCheckBox)
                {
                    if (infoPtr->HoveredCheckItem != HotTrackItem ||
                        infoPtr->HoveredCheckItemBox != HotTrackItemBox)
                    {
                        ChangeCheckItemHotTrack(infoPtr,
                                                HotTrackItem,
                                                HotTrackItemBox);
                    }
                }
                else
                {
                    ChangeCheckItemHotTrack(infoPtr,
                                            NULL,
                                            0);
                }
                
                tme.cbSize = sizeof(tme);
                tme.dwFlags = TME_LEAVE;
                tme.hwndTrack = hwnd;
                tme.dwHoverTime = infoPtr->HoverTime;
                
                TrackMouseEvent(&tme);
            }
#endif

            if (hWndCapture == hwnd && infoPtr->FocusedCheckItem != NULL)
            {
                PCHECKITEM PtItem;
                UINT PtItemBox;
                BOOL OldPushed;
                
                PtItem = PtToCheckItemBox(infoPtr,
                                          &pt,
                                          &PtItemBox,
                                          &InCheckBox);

                OldPushed = infoPtr->FocusedPushed;
                infoPtr->FocusedPushed = InCheckBox && infoPtr->FocusedCheckItem == PtItem &&
                                         infoPtr->FocusedCheckItemBox == PtItemBox;

                if (OldPushed != infoPtr->FocusedPushed)
                {
                    UpdateCheckItemBox(infoPtr,
                                       infoPtr->FocusedCheckItem,
                                       infoPtr->FocusedCheckItemBox);
                }
            }
            
            break;
        }
        
        case WM_VSCROLL:
        {
            SCROLLINFO ScrollInfo;
            
            ScrollInfo.cbSize = sizeof(ScrollInfo);
            ScrollInfo.fMask = SIF_RANGE | SIF_POS;

            if (GetScrollInfo(hwnd,
                              SB_VERT,
                              &ScrollInfo))
            {
                INT OldPos = ScrollInfo.nPos;
                
                switch (LOWORD(wParam))
                {
                    case SB_BOTTOM:
                        ScrollInfo.nPos = ScrollInfo.nMax;
                        break;

                    case SB_LINEDOWN:
                        if (ScrollInfo.nPos < ScrollInfo.nMax)
                        {
                            ScrollInfo.nPos++;
                        }
                        break;

                    case SB_LINEUP:
                        if (ScrollInfo.nPos > 0)
                        {
                            ScrollInfo.nPos--;
                        }
                        break;

                    case SB_PAGEDOWN:
                    {
                        RECT rcClient;
                        INT ScrollLines;
                        
                        /* don't use ScrollInfo.nPage because we should only scroll
                           down by the number of completely visible list entries.
                           nPage however also includes the partly cropped list
                           item at the bottom of the control */

                        GetClientRect(hwnd,
                                      &rcClient);

                        ScrollLines = max(1,
                                          (rcClient.bottom - rcClient.top) / infoPtr->ItemHeight);
                        
                        if (ScrollInfo.nPos + ScrollLines <= ScrollInfo.nMax)
                        {
                            ScrollInfo.nPos += ScrollLines;
                        }
                        else
                        {
                            ScrollInfo.nPos = ScrollInfo.nMax;
                        }
                        break;
                    }

                    case SB_PAGEUP:
                    {
                        RECT rcClient;
                        INT ScrollLines;

                        /* don't use ScrollInfo.nPage because we should only scroll
                           down by the number of completely visible list entries.
                           nPage however also includes the partly cropped list
                           item at the bottom of the control */

                        GetClientRect(hwnd,
                                      &rcClient);

                        ScrollLines = max(1,
                                          (rcClient.bottom - rcClient.top) / infoPtr->ItemHeight);
                        
                        if (ScrollInfo.nPos >= ScrollLines)
                        {
                            ScrollInfo.nPos -= ScrollLines;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -