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

📄 checklist.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
            {
                *DirectlyInCheckBox = TRUE;
            }
            else
            {
                *DirectlyInCheckBox = FALSE;
            }
        }
    }
    
    return Item;
}

static VOID
ClearCheckItems(IN PCHECKLISTWND infoPtr)
{
    PCHECKITEM CurItem, NextItem;

    CurItem = infoPtr->CheckItemListHead;
    while (CurItem != NULL)
    {
        NextItem = CurItem->Next;
        HeapFree(GetProcessHeap(),
                 0,
                 CurItem);
        CurItem = NextItem;
    }

    infoPtr->CheckItemListHead = NULL;
    infoPtr->CheckItemCount = 0;
}

static BOOL
DeleteCheckItem(IN PCHECKLISTWND infoPtr,
                IN PCHECKITEM Item)
{
    PCHECKITEM CurItem;
    PCHECKITEM *PrevPtr = &infoPtr->CheckItemListHead;
    
    for (CurItem = infoPtr->CheckItemListHead;
         CurItem != NULL;
         CurItem = CurItem->Next)
    {
        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,
                     CurItem);
            infoPtr->CheckItemCount--;
            return TRUE;
        }
        
        PrevPtr = &CurItem->Next;
    }
    
    return FALSE;
}

static PCHECKITEM
AddCheckItem(IN PCHECKLISTWND infoPtr,
             IN LPWSTR Name,
             IN DWORD State,
             IN ACCESS_MASK AccessMask,
             OUT INT *Index)
{
    PCHECKITEM CurItem;
    INT i;
    PCHECKITEM *PrevPtr = &infoPtr->CheckItemListHead;
    PCHECKITEM Item = HeapAlloc(GetProcessHeap(),
                                0,
                                sizeof(CHECKITEM) + (wcslen(Name) * sizeof(WCHAR)));
    if (Item != NULL)
    {
        for (CurItem = infoPtr->CheckItemListHead, i = 0;
             CurItem != NULL;
             CurItem = CurItem->Next)
        {
            PrevPtr = &CurItem->Next;
            i++;
        }
        
        Item->Next = NULL;
        Item->AccessMask = AccessMask;
        Item->State = State & CIS_MASK;
        wcscpy(Item->Name,
               Name);
        
        *PrevPtr = Item;
        infoPtr->CheckItemCount++;
        
        if (Index != NULL)
        {
            *Index = i;
        }
    }
    
    return Item;
}

static UINT
ClearCheckBoxes(IN PCHECKLISTWND infoPtr)
{
    PCHECKITEM CurItem;
    UINT nUpdated = 0;
    
    for (CurItem = infoPtr->CheckItemListHead;
         CurItem != NULL;
         CurItem = CurItem->Next)
    {
        if (CurItem->State & (CIS_ALLOW | CIS_DENY))
        {
            CurItem->State &= ~(CIS_ALLOW | CIS_DENY);
            nUpdated++;
        }
    }
    
    return nUpdated;
}

static VOID
UpdateControl(IN PCHECKLISTWND infoPtr)
{
    RECT rcClient;
    SCROLLINFO ScrollInfo;
    INT VisibleItems;
    
    GetClientRect(infoPtr->hSelf,
                  &rcClient);

    ScrollInfo.cbSize = sizeof(ScrollInfo);
    ScrollInfo.fMask = SIF_PAGE | SIF_RANGE;
    ScrollInfo.nMin = 0;
    ScrollInfo.nMax = infoPtr->CheckItemCount;
    ScrollInfo.nPage = ((rcClient.bottom - rcClient.top) + infoPtr->ItemHeight - 1) / infoPtr->ItemHeight;
    ScrollInfo.nPos = 0;
    ScrollInfo.nTrackPos = 0;
    
    VisibleItems = (rcClient.bottom - rcClient.top) / infoPtr->ItemHeight;
    
    if (ScrollInfo.nPage == (UINT)VisibleItems && ScrollInfo.nMax > 0)
    {
        ScrollInfo.nMax--;
    }

    SetScrollInfo(infoPtr->hSelf,
                  SB_VERT,
                  &ScrollInfo,
                  TRUE);

    RedrawWindow(infoPtr->hSelf,
                 NULL,
                 NULL,
                 RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN);
}

static VOID
UpdateCheckItem(IN PCHECKLISTWND infoPtr,
                IN PCHECKITEM Item)
{
    RECT rcClient;
    INT VisibleFirst, VisibleItems;
    INT Index = CheckItemToIndex(infoPtr,
                                 Item);
    if (Index != -1)
    {
        VisibleFirst = GetScrollPos(infoPtr->hSelf,
                                    SB_VERT);
        
        if (Index >= VisibleFirst)
        {
            GetClientRect(infoPtr->hSelf,
                          &rcClient);

            VisibleItems = ((rcClient.bottom - rcClient.top) + infoPtr->ItemHeight - 1) / infoPtr->ItemHeight;
            
            if (Index <= VisibleFirst + VisibleItems)
            {
                RECT rcUpdate;
                
                rcUpdate.left = rcClient.left;
                rcUpdate.right = rcClient.right;
                rcUpdate.top = (Index - VisibleFirst) * infoPtr->ItemHeight;
                rcUpdate.bottom = rcUpdate.top + infoPtr->ItemHeight;

                RedrawWindow(infoPtr->hSelf,
                             &rcUpdate,
                             NULL,
                             RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN);
            }
        }
    }
}

static VOID
MakeCheckItemVisible(IN PCHECKLISTWND infoPtr,
                     IN PCHECKITEM Item)
{
    RECT rcClient;
    INT VisibleFirst, VisibleItems, NewPos;
    INT Index = CheckItemToIndex(infoPtr,
                                 Item);
    if (Index != -1)
    {
        VisibleFirst = GetScrollPos(infoPtr->hSelf,
                                    SB_VERT);
    
        if (Index <= VisibleFirst)
        {
            NewPos = Index;
        }
        else
        {
            GetClientRect(infoPtr->hSelf,
                          &rcClient);

            VisibleItems = (rcClient.bottom - rcClient.top) / infoPtr->ItemHeight;
            if (Index - VisibleItems + 1 > VisibleFirst)
            {
                NewPos = Index - VisibleItems + 1;
            }
            else
            {
                NewPos = VisibleFirst;
            }
        }
        
        if (VisibleFirst != NewPos)
        {
            SCROLLINFO ScrollInfo;
            
            ScrollInfo.cbSize = sizeof(ScrollInfo);
            ScrollInfo.fMask = SIF_POS;
            ScrollInfo.nPos = NewPos;
            NewPos = SetScrollInfo(infoPtr->hSelf,
                                   SB_VERT,
                                   &ScrollInfo,
                                   TRUE);

            if (VisibleFirst != NewPos)
            {
                ScrollWindowEx(infoPtr->hSelf,
                               0,
                               (NewPos - VisibleFirst) * infoPtr->ItemHeight,
                               NULL,
                               NULL,
                               NULL,
                               NULL,
                               SW_INVALIDATE | SW_SCROLLCHILDREN);

                RedrawWindow(infoPtr->hSelf,
                             NULL,
                             NULL,
                             RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN);
            }
        }
    }
}

static UINT
GetIdealItemHeight(IN PCHECKLISTWND infoPtr)
{
    HDC hdc = GetDC(infoPtr->hSelf);
    if(hdc != NULL)
    {
        UINT height;
        TEXTMETRIC tm;
        HGDIOBJ hOldFont = SelectObject(hdc,
                                        infoPtr->hFont);

        if(GetTextMetrics(hdc,
                          &tm))
        {
            height = tm.tmHeight;
        }
        else
        {
            height = 2;
        }

        SelectObject(hdc,
                     hOldFont);

        ReleaseDC(infoPtr->hSelf,
                  hdc);

        return height;
    }
    return 0;
}

static HFONT
RetChangeControlFont(IN PCHECKLISTWND infoPtr,
                     IN HFONT hFont,
                     IN BOOL Redraw)
{
    HFONT hOldFont = infoPtr->hFont;
    infoPtr->hFont = hFont;
    
    if (hOldFont != hFont)
    {
        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);

    return hOldFont;
}

#if SUPPORT_UXTHEME
static INT
CalculateCheckBoxStyle(IN BOOL Checked,
                       IN BOOL Enabled,
                       IN BOOL HotTrack,
                       IN BOOL Pushed)
{
    INT BtnState;

    if (Checked)
    {
        BtnState = (Enabled ?
                    (Pushed ? CBS_CHECKEDPRESSED : (HotTrack ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL)) :
                    CBS_CHECKEDDISABLED);
    }
    else
    {
        BtnState = (Enabled ?
                    (Pushed ? CBS_UNCHECKEDPRESSED : (HotTrack ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL)) :
                    CBS_UNCHECKEDDISABLED);
    }

    return BtnState;
}
#endif

static VOID
PaintControl(IN PCHECKLISTWND infoPtr,
             IN HDC hDC,
             IN PRECT rcUpdate)
{
    INT ScrollPos;
    PCHECKITEM FirstItem, Item;
    RECT rcClient;
    UINT VisibleFirstIndex = rcUpdate->top / infoPtr->ItemHeight;
    UINT LastTouchedIndex = rcUpdate->bottom / infoPtr->ItemHeight;
    
    FillRect(hDC,
             rcUpdate,
             (HBRUSH)(COLOR_WINDOW + 1));
    
    GetClientRect(infoPtr->hSelf,
                  &rcClient);
    
    ScrollPos = GetScrollPos(infoPtr->hSelf,
                             SB_VERT);
    
    FirstItem = FindCheckItemByIndex(infoPtr,
                                     ScrollPos + VisibleFirstIndex);
    if (FirstItem != NULL)
    {
        RECT TextRect, ItemRect, CheckBox;
        HFONT hOldFont;
        DWORD CurrentIndex;
        COLORREF OldTextColor;
        BOOL Enabled, PrevEnabled, IsPushed;
        POINT hOldBrushOrg;
#if SUPPORT_UXTHEME
        HRESULT hDrawResult;
        BOOL ItemHovered;
#endif
        
        Enabled = IsWindowEnabled(infoPtr->hSelf);
        PrevEnabled = Enabled;
        
        ItemRect.left = 0;
        ItemRect.right = rcClient.right;
        ItemRect.top = VisibleFirstIndex * infoPtr->ItemHeight;
        
        TextRect.left = ItemRect.left + CI_TEXT_MARGIN_WIDTH;
        TextRect.right = ItemRect.right - CI_TEXT_MARGIN_WIDTH;
        TextRect.top = ItemRect.top + CI_TEXT_MARGIN_HEIGHT;
        
        SetBrushOrgEx(hDC,
                      ItemRect.left,
                      ItemRect.top,
                      &hOldBrushOrg);
        
        OldTextColor = SetTextColor(hDC,

⌨️ 快捷键说明

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