📄 checklist.c
字号:
{
*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 + -