📄 checklst.pas
字号:
if not Header[itemID] then
if not UseRightToLeftAlignment then
rcItem.Left := rcItem.Left + GetCheckWidth
else
rcItem.Right := rcItem.Right - GetCheckWidth;
inherited;
end;
procedure TCheckListBox.DrawCheck(R: TRect; AState: TCheckBoxState; AEnabled: Boolean);
var
DrawState: Integer;
DrawRect: TRect;
OldBrushColor: TColor;
OldBrushStyle: TBrushStyle;
OldPenColor: TColor;
Rgn, SaveRgn: HRgn;
ElementDetails: TThemedElementDetails;
begin
SaveRgn := 0;
DrawRect.Left := R.Left + (R.Right - R.Left - FCheckWidth) div 2;
DrawRect.Top := R.Top + (R.Bottom - R.Top - FCheckHeight) div 2;
DrawRect.Right := DrawRect.Left + FCheckWidth;
DrawRect.Bottom := DrawRect.Top + FCheckHeight;
with Canvas do
begin
if Flat then
begin
{ Remember current clipping region }
SaveRgn := CreateRectRgn(0,0,0,0);
GetClipRgn(Handle, SaveRgn);
{ Clip 3d-style checkbox to prevent flicker }
with DrawRect do
Rgn := CreateRectRgn(Left + 2, Top + 2, Right - 2, Bottom - 2);
SelectClipRgn(Handle, Rgn);
DeleteObject(Rgn);
end;
if ThemeServices.ThemesEnabled then
begin
case AState of
cbChecked:
if AEnabled then
ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxCheckedNormal)
else
ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxCheckedDisabled);
cbUnchecked:
if AEnabled then
ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxUncheckedNormal)
else
ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxUncheckedDisabled)
else // cbGrayed
if AEnabled then
ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxMixedNormal)
else
ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxMixedDisabled);
end;
ThemeServices.DrawElement(Handle, ElementDetails, R);
end
else
begin
case AState of
cbChecked:
DrawState := DFCS_BUTTONCHECK or DFCS_CHECKED;
cbUnchecked:
DrawState := DFCS_BUTTONCHECK;
else // cbGrayed
DrawState := DFCS_BUTTON3STATE or DFCS_CHECKED;
end;
if not AEnabled then
DrawState := DrawState or DFCS_INACTIVE;
DrawFrameControl(Handle, DrawRect, DFC_BUTTON, DrawState);
end;
if Flat then
begin
SelectClipRgn(Handle, SaveRgn);
DeleteObject(SaveRgn);
{ Draw flat rectangle in-place of clipped 3d checkbox above }
OldBrushStyle := Brush.Style;
OldBrushColor := Brush.Color;
OldPenColor := Pen.Color;
Brush.Style := bsClear;
Pen.Color := clBtnShadow;
with DrawRect do
Rectangle(Left + 1, Top + 1, Right - 1, Bottom - 1);
Brush.Style := OldBrushStyle;
Brush.Color := OldBrushColor;
Pen.Color := OldPenColor;
end;
end;
end;
procedure TCheckListBox.SetChecked(Index: Integer; AChecked: Boolean);
begin
if AChecked <> GetChecked(Index) then
begin
TCheckListBoxDataWrapper(GetWrapper(Index)).SetChecked(AChecked);
InvalidateCheck(Index);
end;
end;
procedure TCheckListBox.SetItemEnabled(Index: Integer; const Value: Boolean);
begin
if Value <> GetItemEnabled(Index) then
begin
TCheckListBoxDataWrapper(GetWrapper(Index)).Disabled := not Value;
InvalidateCheck(Index);
end;
end;
procedure TCheckListBox.SetState(Index: Integer; AState: TCheckBoxState);
begin
if AState <> GetState(Index) then
begin
TCheckListBoxDataWrapper(GetWrapper(Index)).State := AState;
InvalidateCheck(Index);
end;
end;
procedure TCheckListBox.InvalidateCheck(Index: Integer);
var
R: TRect;
begin
if not Header[Index] then
begin
R := ItemRect(Index);
if not UseRightToLeftAlignment then
R.Right := R.Left + GetCheckWidth
else
R.Left := R.Right - GetCheckWidth;
InvalidateRect(Handle, @R, not (csOpaque in ControlStyle));
UpdateWindow(Handle);
end;
end;
function TCheckListBox.GetChecked(Index: Integer): Boolean;
begin
if HaveWrapper(Index) then
Result := TCheckListBoxDataWrapper(GetWrapper(Index)).GetChecked
else
Result := False;
end;
function TCheckListBox.GetItemEnabled(Index: Integer): Boolean;
begin
if HaveWrapper(Index) then
Result := not TCheckListBoxDataWrapper(GetWrapper(Index)).Disabled
else
Result := True;
end;
function TCheckListBox.GetState(Index: Integer): TCheckBoxState;
begin
if HaveWrapper(Index) then
Result := TCheckListBoxDataWrapper(GetWrapper(Index)).State
else
Result := TCheckListBoxDataWrapper.GetDefaultState;
end;
procedure TCheckListBox.KeyPress(var Key: Char);
begin
if (Key = ' ') then
ToggleClickCheck(ItemIndex);
inherited KeyPress(Key);
end;
procedure TCheckListBox.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
Index: Integer;
begin
inherited;
if Button = mbLeft then
begin
Index := ItemAtPos(Point(X,Y),True);
if (Index <> -1) and GetItemEnabled(Index) then
if not UseRightToLeftAlignment then
begin
if X - ItemRect(Index).Left < GetCheckWidth then
ToggleClickCheck(Index)
end
else
begin
Dec(X, ItemRect(Index).Right - GetCheckWidth);
if (X > 0) and (X < GetCheckWidth) then
ToggleClickCheck(Index)
end;
end;
end;
procedure TCheckListBox.ToggleClickCheck;
var
State: TCheckBoxState;
begin
if (Index >= 0) and (Index < Items.Count) and GetItemEnabled(Index) then
begin
State := Self.State[Index];
case State of
cbUnchecked:
if AllowGrayed then State := cbGrayed else State := cbChecked;
cbChecked: State := cbUnchecked;
cbGrayed: State := cbChecked;
end;
Self.State[Index] := State;
ClickCheck;
end;
end;
procedure TCheckListBox.ClickCheck;
begin
if Assigned(FOnClickCheck) then FOnClickCheck(Self);
end;
function TCheckListBox.GetItemData(Index: Integer): LongInt;
begin
Result := 0;
if HaveWrapper(Index) then
Result := TCheckListBoxDataWrapper(GetWrapper(Index)).FData;
end;
function TCheckListBox.GetWrapper(Index: Integer): TObject;
begin
Result := ExtractWrapper(Index);
if Result = nil then
Result := CreateWrapper(Index);
end;
function TCheckListBox.ExtractWrapper(Index: Integer): TObject;
begin
Result := TCheckListBoxDataWrapper(inherited GetItemData(Index));
if LB_ERR = Integer(Result) then
raise EListError.CreateResFmt(@SListIndexError, [Index]);
if (Result <> nil) and (not (Result is TCheckListBoxDataWrapper)) then
Result := nil;
end;
function TCheckListBox.InternalGetItemData(Index: Integer): LongInt;
begin
Result := inherited GetItemData(Index);
end;
procedure TCheckListBox.InternalSetItemData(Index: Integer; AData: LongInt);
begin
inherited SetItemData(Index, AData);
end;
function TCheckListBox.CreateWrapper(Index: Integer): TObject;
begin
Result := TCheckListBoxDataWrapper.Create;
inherited SetItemData(Index, LongInt(Result));
end;
function TCheckListBox.HaveWrapper(Index: Integer): Boolean;
begin
Result := ExtractWrapper(Index) <> nil;
end;
procedure TCheckListBox.SetItemData(Index: Integer; AData: LongInt);
var
Wrapper: TCheckListBoxDataWrapper;
begin
if HaveWrapper(Index) or (AData <> 0) then
begin
Wrapper := TCheckListBoxDataWrapper(GetWrapper(Index));
Wrapper.FData := AData;
end;
end;
procedure TCheckListBox.ResetContent;
var
I: Integer;
begin
for I := 0 to Items.Count - 1 do
if HaveWrapper(I) then
GetWrapper(I).Free;
inherited;
end;
procedure TCheckListBox.DeleteString(Index: Integer);
begin
if HaveWrapper(Index) then
GetWrapper(Index).Free;
inherited;
end;
procedure TCheckListBox.SetFlat(Value: Boolean);
begin
if Value <> FFlat then
begin
FFlat := Value;
Invalidate;
end;
end;
procedure TCheckListBox.WMDestroy(var Msg: TWMDestroy);
var
i: Integer;
begin
for i := 0 to Items.Count -1 do
ExtractWrapper(i).Free;
inherited;
end;
function TCheckListBox.GetHeader(Index: Integer): Boolean;
begin
if HaveWrapper(Index) then
Result := TCheckListBoxDataWrapper(GetWrapper(Index)).Header
else
Result := False;
end;
procedure TCheckListBox.SetHeader(Index: Integer; const Value: Boolean);
begin
if Value <> GetHeader(Index) then
begin
TCheckListBoxDataWrapper(GetWrapper(Index)).Header := Value;
InvalidateCheck(Index);
end;
end;
procedure TCheckListBox.SetHeaderBackgroundColor(const Value: TColor);
begin
if Value <> HeaderBackgroundColor then
begin
FHeaderBackgroundColor := Value;
Invalidate;
end;
end;
procedure TCheckListBox.SetHeaderColor(const Value: TColor);
begin
if Value <> HeaderColor then
begin
FHeaderColor := Value;
Invalidate;
end;
end;
initialization
GetCheckSize;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -