Componentes.Terceros.DevExp.../internal/x.46/2/ExpressEditors Library 5/Sources/cxCheckBox.pas

2616 lines
83 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressEditors }
{ }
{ Copyright (c) 1998-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSEDITORS AND ALL }
{ ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{********************************************************************}
unit cxCheckBox;
{$I cxVer.inc}
interface
uses
Messages, Windows,
{$IFDEF DELPHI6}
Types, Variants,
{$ENDIF}
Classes, Controls, Forms, Graphics, SysUtils, cxClasses, cxContainer, cxControls,
cxCustomData, cxDataStorage, cxEdit, cxGraphics, cxLookAndFeels, cxTextEdit,
cxDropDownEdit, cxVariants, cxFilterControlUtils, cxLookAndFeelPainters;
const
cxEditCheckBoxSingleBorderDefaultColor = clBtnShadow;
type
TcxCheckBoxNullValueShowingStyle = (nssUnchecked, nssInactive, nssGrayedChecked);
TcxCheckStatesValueFormatEx = (cvfCaptions, cvfIndices, cvfInteger, cvfStatesString, cvfCustom);
TcxCheckStatesValueFormat = cvfCaptions..cvfStatesString;
TcxCheckStates = array of TcxCheckBoxState;
TcxEditCheckBoxBorderStyle = TcxEditBorderStyle;
TcxEditCheckState = (ecsNormal, ecsHot, ecsPressed, ecsDisabled);
TcxCheckStatesToValueEvent = procedure(Sender: TObject;
const ACheckStates: TcxCheckStates; out AValue: TcxEditValue) of object;
TcxValueToCheckStatesEvent = procedure(Sender: TObject;
const AValue: TcxEditValue; var ACheckStates: TcxCheckStates) of object;
{ IcxCheckItems }
IcxCheckItems = interface
['{5BF13228-CF05-4741-9833-F2B8FBFD57ED}']
function GetCaption(Index: Integer): string;
function GetCount: Integer;
property Captions[Index: Integer]: string read GetCaption;
property Count: Integer read GetCount;
end;
{ TcxCaptionItem }
TcxCaptionItem = class(TCollectionItem)
private
FCaption: TCaption;
FTag: TcxTag;
function IsTagStored: Boolean;
procedure SetCaption(AValue: TCaption);
protected
property Caption: TCaption read FCaption write SetCaption;
property Tag: TcxTag read FTag write FTag stored IsTagStored;
public
procedure Assign(Source: TPersistent); override;
end;
{ TcxCaptionItems }
TcxCaptionItems = class(TcxOwnedInterfacedCollection, IcxCheckItems)
private
function GetItem(AIndex: Integer): TcxCaptionItem;
procedure SetItem(AIndex: Integer; AValue: TcxCaptionItem);
protected
function DoCompareItems(AItem1, AItem2: TcxInterfacedCollectionItem): Integer; override;
// IcxCheckItems
function GetCaption(AIndex: Integer): string;
function GetCount: Integer;
public
property Items[AIndex: Integer]: TcxCaptionItem read GetItem write SetItem; default;
end;
{ TcxCustomCheckBoxViewInfo }
TcxCustomCheckBox = class;
TcxCustomCheckBoxViewInfo = class(TcxCustomTextEditViewInfo)
private
function GetEdit: TcxCustomCheckBox;
protected
procedure InternalPaint(ACanvas: TcxCanvas); override;
function IsTextEnabled: Boolean;
public
Alignment: TAlignment;
CheckBorderOffset: Integer;
CheckBoxBorderStyle: TcxEditCheckBoxBorderStyle;
CheckBoxGlyph: TBitmap;
CheckBoxGlyphCount: Integer;
CheckBoxRect: TRect;
CheckBoxState: TcxEditCheckState;
DrawCaptionFlags: Integer;
FocusRect: TRect;
HasGlyph: Boolean;
IsTextColorAssigned: Boolean;
NullValueShowingStyle: TcxCheckBoxNullValueShowingStyle;
State: TcxCheckBoxState;
procedure Assign(Source: TObject); override;
procedure DrawText(ACanvas: TcxCanvas); override;
function GetUpdateRegion(AViewInfo: TcxContainerViewInfo): TcxRegion; override;
function IsHotTrack: Boolean; override;
function IsHotTrack(P: TPoint): Boolean; override;
function NeedShowHint(ACanvas: TcxCanvas; const P: TPoint; out AText: TCaption;
out AIsMultiLine: Boolean; out ATextRect: TRect): Boolean; override;
procedure Offset(DX, DY: Integer); override;
function Repaint(AControl: TWinControl; const AInnerEditRect: TRect;
AViewInfo: TcxContainerViewInfo = nil): Boolean; override;
property Edit: TcxCustomCheckBox read GetEdit;
end;
{ TcxCustomCheckBoxViewData }
TcxCustomCheckBoxProperties = class;
TcxCustomCheckBoxViewData = class(TcxCustomEditViewData)
private
function GetProperties: TcxCustomCheckBoxProperties;
protected
function InternalGetEditConstantPartSize(ACanvas: TcxCanvas; AIsInplace: Boolean;
AEditSizeProperties: TcxEditSizeProperties;
var MinContentSize: TSize; AViewInfo: TcxCustomEditViewInfo): TSize; override;
function GetDrawTextFlags: Integer; virtual;
function GetIsEditClass: Boolean;
function IsCheckPressed: Boolean;
public
procedure Calculate(ACanvas: TcxCanvas; const ABounds: TRect; const P: TPoint;
Button: TcxMouseButton; Shift: TShiftState; AViewInfo: TcxCustomEditViewInfo;
AIsMouseEvent: Boolean); override;
procedure EditValueToDrawValue(ACanvas: TcxCanvas; const AEditValue: TcxEditValue;
AViewInfo: TcxCustomEditViewInfo); override;
function GetBorderStyle: TcxEditBorderStyle; override;
property Properties: TcxCustomCheckBoxProperties read GetProperties;
end;
{ TcxCheckBoxStyle }
TcxCheckBoxStyle = class(TcxEditStyle)
public
function HasBorder: Boolean; override;
end;
{ TcxCustomCheckBoxProperties }
TcxCustomCheckBoxProperties = class(TcxCustomEditProperties)
private
FAllowGrayed: Boolean;
FCaption: TCaption; // obsolete
FDisplayChecked: WideString;
FDisplayGrayed: WideString;
FDisplayUnchecked: WideString;
FFullFocusRect: Boolean;
FGlyph: TBitmap;
FGlyphCount: Integer;
FIsCaptionAssigned: Boolean; // obsolete
FMultiLine: Boolean;
FNullStyle: TcxCheckBoxNullValueShowingStyle;
FUseAlignmentWhenInplace: Boolean;
FValueChecked: TcxEditValue;
FValueGrayed: TcxEditValue;
FValueUnchecked: TcxEditValue;
function GetAlignment: TAlignment;
function GetGlyph: TBitmap;
function GetInternalAlignment: TcxEditAlignment;
procedure GlyphChanged(Sender: TObject);
function IsAlignmentStored: Boolean;
function IsDisplayCheckedStored: Boolean;
function IsDisplayGrayedStored: Boolean;
function IsDisplayUncheckedStored: Boolean;
function IsLoading: Boolean;
function IsValueCheckedStored: Boolean;
function IsValueGrayedStored: Boolean;
function IsValueUncheckedStored: Boolean;
procedure ReadCaption(Reader: TReader); // obsolete
procedure SetAlignment(Value: TAlignment);
procedure SetCaption(const Value: TCaption); // obsolete
procedure SetFullFocusRect(Value: Boolean);
procedure SetGlyph(Value: TBitmap);
procedure SetGlyphCount(Value: Integer);
procedure SetMultiLine(Value: Boolean);
procedure SetNullStyle(Value: TcxCheckBoxNullValueShowingStyle);
procedure SetStateValues(const AValueChecked, AValueGrayed, AValueUnchecked: TcxEditValue);
procedure SetUseAlignmentWhenInplace(Value: Boolean);
procedure SetValueChecked(const Value: TcxEditValue);
procedure SetValueGrayed(const Value: TcxEditValue);
procedure SetValueUnchecked(const Value: TcxEditValue);
protected
function CanValidate: Boolean; override;
procedure DefineProperties(Filer: TFiler); override;
class function GetViewDataClass: TcxCustomEditViewDataClass; override;
function HasDisplayValue: Boolean; override;
function CheckValue(const AValue: TcxEditValue): Boolean;
function GetState(const AEditValue: TcxEditValue): TcxCheckBoxState;
function InternalGetGlyph: TBitmap; virtual;
function IsEmbeddedEdit: Boolean; virtual;
property InternalAlignment: TcxEditAlignment read GetInternalAlignment;
public
constructor Create(AOwner: TPersistent); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
function CanCompareEditValue: Boolean; override;
function CompareDisplayValues(
const AEditValue1, AEditValue2: TcxEditValue): Boolean; override;
class function GetContainerClass: TcxContainerClass; override;
function GetDisplayText(const AEditValue: TcxEditValue;
AFullText: Boolean = False; AIsInplace: Boolean = True): WideString; override;
class function GetStyleClass: TcxCustomEditStyleClass; override;
function GetSpecialFeatures: TcxEditSpecialFeatures; override;
function GetSupportedOperations: TcxEditSupportedOperations; override;
class function GetViewInfoClass: TcxContainerViewInfoClass; override;
function IsActivationKey(AKey: Char): Boolean; override;
function IsEditValueValid(var EditValue: TcxEditValue; AEditFocused: Boolean): Boolean; override;
function IsResetEditClass: Boolean; override;
procedure PrepareDisplayValue(const AEditValue: TcxEditValue;
var DisplayValue: TcxEditValue; AEditFocused: Boolean); override;
// !!!
property Alignment: TAlignment read GetAlignment write SetAlignment
stored IsAlignmentStored;
// property AlignmentVert: TcxAlignmentVert read GetAlignmentVert
// write SetAlignmentVert stored IsAlignmentVertStored;
property AllowGrayed: Boolean read FAllowGrayed write FAllowGrayed default False;
property Caption: TCaption read FCaption write SetCaption stored False; // obsolete
property DisplayChecked: WideString read FDisplayChecked write FDisplayChecked
stored IsDisplayCheckedStored;
property DisplayGrayed: WideString read FDisplayGrayed write FDisplayGrayed
stored IsDisplayGrayedStored;
property DisplayUnchecked: WideString read FDisplayUnchecked write FDisplayUnchecked
stored IsDisplayUncheckedStored;
property FullFocusRect: Boolean read FFullFocusRect write SetFullFocusRect default False;
property Glyph: TBitmap read GetGlyph write SetGlyph;
property GlyphCount: Integer read FGlyphCount write SetGlyphCount default 6;
property MultiLine: Boolean read FMultiLine write SetMultiLine default False;
property NullStyle: TcxCheckBoxNullValueShowingStyle read FNullStyle write
SetNullStyle default nssGrayedChecked;
property UseAlignmentWhenInplace: Boolean read FUseAlignmentWhenInplace
write SetUseAlignmentWhenInplace default False;
property ValueChecked: TcxEditValue read FValueChecked write SetValueChecked
stored IsValueCheckedStored;
property ValueGrayed: TcxEditValue read FValueGrayed write SetValueGrayed
stored IsValueGrayedStored;
property ValueUnchecked: TcxEditValue read FValueUnchecked write SetValueUnchecked
stored IsValueUncheckedStored;
end;
{ TcxCheckBoxProperties }
TcxCheckBoxProperties = class(TcxCustomCheckBoxProperties)
published
property Alignment;
property AllowGrayed;
property AssignedValues;
property Caption; // obsolete
property ClearKey;
property DisplayChecked;
property DisplayUnchecked;
property DisplayGrayed;
property FullFocusRect;
property Glyph;
property GlyphCount;
property ImmediatePost;
property MultiLine;
property NullStyle;
property ReadOnly;
property UseAlignmentWhenInplace;
property ValueChecked;
property ValueGrayed;
property ValueUnchecked;
property OnChange;
property OnEditValueChanged;
property OnValidate;
end;
{ TcxCustomCheckBox }
TcxCustomCheckBox = class(TcxCustomEdit)
private
FIsCheckPressed: Boolean;
FIsLoaded: Boolean;
FIsLoadingStateAssigned: Boolean;
FLoadingState: TcxCheckBoxState;
function GetChecked: Boolean;
function GetProperties: TcxCustomCheckBoxProperties;
function GetActiveProperties: TcxCustomCheckBoxProperties;
function GetState: TcxCheckBoxState;
function GetStyle: TcxCheckBoxStyle;
function GetViewInfo: TcxCustomCheckBoxViewInfo;
function IsStateStored: Boolean;
procedure SetChecked(Value: Boolean);
procedure SetProperties(Value: TcxCustomCheckBoxProperties);
procedure SetState(Value: TcxCheckBoxState);
procedure SetStyle(Value: TcxCheckBoxStyle);
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
protected
procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
function CanHaveTransparentBorder: Boolean; override;
function DefaultParentColor: Boolean; override;
procedure DoEditKeyDown(var Key: Word; Shift: TShiftState); override;
procedure DoEditKeyPress(var Key: Char); override;
procedure DoEditKeyUp(var Key: Word; Shift: TShiftState); override;
procedure DoExit; override;
procedure FillSizeProperties(var AEditSizeProperties: TcxEditSizeProperties); override;
function GetActionLinkClass: TControlActionLinkClass; override;
function GetEditStateColorKind: TcxEditStateColorKind; override;
function GetShadowBounds: TRect; override;
procedure Initialize; override;
function InternalGetNotPublishedStyleValues: TcxEditStyleValues; override;
procedure InternalSetEditValue(const Value: TcxEditValue;
AValidateEditValue: Boolean); override;
function IsClickEnabledDuringLoading: Boolean; override;
function IsNativeBackground: Boolean; override;
procedure Loaded; override;
procedure ProcessViewInfoChanges(APrevViewInfo: TcxCustomEditViewInfo;
AIsMouseDownUpEvent: Boolean); override;
procedure PropertiesChanged(Sender: TObject); override;
procedure TextChanged; override;
procedure InvalidateCheckRect;
procedure Toggle; virtual;
property Caption;
property Checked: Boolean read GetChecked write SetChecked stored False;
property ViewInfo: TcxCustomCheckBoxViewInfo read GetViewInfo;
public
procedure Clear; override;
class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
procedure PrepareEditValue(const ADisplayValue: TcxEditValue;
out EditValue: TcxEditValue; AEditFocused: Boolean); override;
property ActiveProperties: TcxCustomCheckBoxProperties read GetActiveProperties;
property Properties: TcxCustomCheckBoxProperties read GetProperties
write SetProperties;
property State: TcxCheckBoxState read GetState write SetState
stored IsStateStored default cbsUnchecked;
property Style: TcxCheckBoxStyle read GetStyle write SetStyle;
property Transparent;
end;
{ TcxCheckBox }
TcxCheckBox = class(TcxCustomCheckBox)
private
function GetActiveProperties: TcxCheckBoxProperties;
function GetProperties: TcxCheckBoxProperties;
procedure SetProperties(Value: TcxCheckBoxProperties);
public
class function GetPropertiesClass: TcxCustomEditPropertiesClass; override;
property ActiveProperties: TcxCheckBoxProperties read GetActiveProperties;
published
property Action;
property Align;
property Anchors;
property AutoSize;
property Caption;
property Checked;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property ParentBackground;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property Properties: TcxCheckBoxProperties read GetProperties
write SetProperties;
property ShowHint;
property State;
property Style;
property StyleDisabled;
property StyleFocused;
property StyleHot;
property TabOrder;
property TabStop;
property Transparent;
property Visible;
property OnClick;
property OnContextPopup;
property OnDragDrop;
property OnDragOver;
property OnEditing;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
end;
{ TcxFilterCheckBoxHelper }
TcxFilterCheckBoxHelper = class(TcxFilterComboBoxHelper)
public
class procedure GetFilterValue(AEdit: TcxCustomEdit;
AEditProperties: TcxCustomEditProperties; var V: Variant; var S: TCaption); override;
class function GetSupportedFilterOperators(
AProperties: TcxCustomEditProperties;
AValueTypeClass: TcxValueTypeClass;
AExtendedSet: Boolean = False): TcxFilterControlOperators; override;
class procedure InitializeProperties(AProperties,
AEditProperties: TcxCustomEditProperties; AHasButtons: Boolean); override;
class procedure SetFilterValue(AEdit: TcxCustomEdit; AEditProperties: TcxCustomEditProperties;
AValue: Variant); override;
class function UseDisplayValue: Boolean; override;
end;
{ TcxCheckBoxActionLink }
TcxCheckBoxActionLink = class(TWinControlActionLink)
protected
FClient: TcxCustomCheckBox;
procedure AssignClient(AClient: TObject); override;
function IsCheckedLinked: Boolean; override;
procedure SetChecked(Value: Boolean); override;
procedure InternalSetChecked(Value: Boolean);
end;
var
CheckStates: TcxCheckStates = nil;
function CalculateCheckStatesValue(const ACheckStates: TcxCheckStates;
AItems: IcxCheckItems; AValueFormat: TcxCheckStatesValueFormat): TcxEditValue;
function CalculateCheckStates(const AValue: TcxEditValue;
AItems: IcxCheckItems; AValueFormat: TcxCheckStatesValueFormat;
var ACheckStates: TcxCheckStates): Boolean;
procedure DrawEditCheck(ACanvas: TcxCanvas; const ACheckRect: TRect;
AState: TcxCheckBoxState; ACheckState: TcxEditCheckState; AGlyph: TBitmap;
AGlyphCount: Integer; ABorderStyle: TcxEditCheckBoxBorderStyle;
ANativeStyle: Boolean; ABorderColor: TColor; ABackgroundColor: TColor;
ADrawBackground, AIsDesigning, AFocused, ASupportGrayed: Boolean;
APainter: TcxCustomLookAndFeelPainterClass;
AGrayedShowingStyle: TcxCheckBoxNullValueShowingStyle = nssGrayedChecked);
function GetEditCheckBorderOffset(ACheckBorderStyle: TcxContainerBorderStyle;
ANativeStyle, AHasGlyph: Boolean; APainter: TcxCustomLookAndFeelPainterClass): Integer; overload;
function GetEditCheckBorderOffset(ACheckBorderStyle: TcxEditBorderStyle;
ANativeStyle, AHasGlyph: Boolean; APainter: TcxCustomLookAndFeelPainterClass): Integer; overload;
function GetEditCheckBorderOffset(ALookAndFeelKind: TcxLookAndFeelKind;
ANativeStyle, AHasGlyph: Boolean; APainter: TcxCustomLookAndFeelPainterClass): Integer; overload;
function GetEditCheckGlyphIndex(AState: TcxCheckBoxState;
ACheckState: TcxEditCheckState; ASupportGrayed: Boolean;
AGlyphCount: Integer): Integer;
function GetEditCheckSize(ACanvas: TcxCanvas; ANativeStyle: Boolean;
AGlyph: TBitmap; AGlyphCount: Integer; APainter: TcxCustomLookAndFeelPainterClass): TSize;
procedure DrawCheckBoxText(ACanvas: TcxCanvas; AText: string; AFont: TFont;
ATextColor: TColor; ATextRect: TRect; ADrawTextFlags: Integer; AEnabled: Boolean);
implementation
uses
Math, ActnList, cxGeometry, dxThemeConsts, dxThemeManager, dxUxTheme, cxEditConsts,
cxEditPaintUtils, cxDrawTextUtils, cxEditUtils;
var
FCheckMask: TBitmap;
procedure PrepareCheckMask;
procedure InternalPrepareCheckMask(AButtonsBitmap: HBITMAP);
var
AMemDC: HDC;
APrevBitmap: HBITMAP;
I, J: Integer;
begin
FCheckMask := TBitmap.Create;
with TcxCustomLookAndFeelPainter do
begin
FCheckMask.Width := CheckButtonSize.cx;
FCheckMask.Height := CheckButtonSize.cy;
end;
AMemDC := CreateCompatibleDC(0);
APrevBitmap := 0;
try
APrevBitmap := SelectObject(AMemDC, AButtonsBitmap);
with FCheckMask.Canvas do
for I := 0 to FCheckMask.Height - 1 do
for J := 0 to FCheckMask.Width - 1 do
if Windows.GetPixel(AMemDC, J, I) = Windows.GetPixel(AMemDC, J + FCheckMask.Width, I) then
Pixels[J, I] := clWhite
else
Pixels[J, I] := 0;
finally
if APrevBitmap <> 0 then
SelectObject(AMemDC, APrevBitmap);
DeleteDC(AMemDC);
end;
end;
var
AButtonsBitmap: HBITMAP;
begin
AButtonsBitmap := LoadBitmap(0, PChar(OBM_CHECKBOXES));
try
InternalPrepareCheckMask(AButtonsBitmap);
finally
DeleteObject(AButtonsBitmap);
end;
end;
procedure CalculateCheckBoxViewInfo(AViewData: TcxCustomCheckBoxViewData; AViewInfo:
TcxCustomCheckBoxViewInfo; AIsMouseEvent: Boolean);
begin
with AViewInfo do
begin
AViewData.CalculateViewInfo(AViewInfo, AIsMouseEvent);
TextRect := ClientRect;
ExtendRect(TextRect, GetTextEditDrawTextOffset(AViewData));
end;
end;
function CalculateCheckStatesValue(const ACheckStates: TcxCheckStates;
AItems: IcxCheckItems; AValueFormat: TcxCheckStatesValueFormat): TcxEditValue;
function CalculateCaptionsValue: TcxEditValue;
var
ACheckedCaptions, AGrayedCaptions: string;
I: Integer;
begin
ACheckedCaptions := '';
AGrayedCaptions := '';
for I := 0 to Length(ACheckStates) - 1 do
begin
if ACheckStates[I] <> cbsUnchecked then
if ACheckStates[I] = cbsGrayed then
AGrayedCaptions := AGrayedCaptions +
IntToStr(Length(AItems.Captions[I])) + ':' + AItems.Captions[I]
else
ACheckedCaptions := ACheckedCaptions +
IntToStr(Length(AItems.Captions[I])) + ':' + AItems.Captions[I];
end;
Result := AGrayedCaptions;
if Length(ACheckedCaptions) > 0 then
Result := Result + ';' + ACheckedCaptions;
end;
function CalculateIndicesValue: TcxEditValue;
var
ACheckedCaptions, AGrayedCaptions: string;
I: Integer;
begin
ACheckedCaptions := '';
AGrayedCaptions := '';
for I := 0 to Length(ACheckStates) - 1 do
if ACheckStates[I] <> cbsUnchecked then
if ACheckStates[I] = cbsGrayed then
begin
if AGrayedCaptions <> '' then
AGrayedCaptions := AGrayedCaptions + ',';
AGrayedCaptions := AGrayedCaptions + IntToStr(I);
end
else
begin
if ACheckedCaptions <> '' then
ACheckedCaptions := ACheckedCaptions + ',';
ACheckedCaptions := ACheckedCaptions + IntToStr(I);
end;
Result := AGrayedCaptions;
if Length(ACheckedCaptions) > 0 then
Result := Result + ';' + ACheckedCaptions;
end;
function CalculateStatesIntegerValue: TcxEditValue;
var
V: {$IFDEF DELPHI6}Int64{$ELSE}Integer{$ENDIF};
I, L: Integer;
begin
V := 0;
L := Length(ACheckStates);
if L > SizeOf({$IFDEF DELPHI6}Int64{$ELSE}Integer{$ENDIF}) * 8 then
L := SizeOf({$IFDEF DELPHI6}Int64{$ELSE}Integer{$ENDIF}) * 8;
for I := L - 1 downto 0 do
begin
V := V shl 1;
V := V + {$IFDEF DELPHI6}Int64{$ELSE}Integer{$ENDIF}(ACheckStates[I] = cbsChecked);
end;
Result := V;
VarCast(Result, Result, {$IFDEF DELPHI6}varInt64{$ELSE}varInteger{$ENDIF});
end;
function CalculateStatesStringValue: TcxEditValue;
var
I: Integer;
S: string;
begin
SetLength(S, Length(ACheckStates));
for I := 0 to High(ACheckStates) do
S[I + 1] := Char(Integer(ACheckStates[I]) + Ord('0'));
Result := S;
end;
begin
Result := Null;
case AValueFormat of
cvfCaptions:
Result := CalculateCaptionsValue;
cvfIndices:
Result := CalculateIndicesValue;
cvfInteger:
Result := CalculateStatesIntegerValue;
cvfStatesString:
Result := CalculateStatesStringValue;
end;
end;
function CalculateCheckStates(const AValue: TcxEditValue;
AItems: IcxCheckItems; AValueFormat: TcxCheckStatesValueFormat;
var ACheckStates: TcxCheckStates): Boolean;
function GetNumber(var ANumber, AIndex: Integer;
const S: string): Boolean;
function IsDigit(C: Char): Boolean;
begin
Result := (C >= '0') and (C <= '9');
end;
const
AMaxLength = MaxInt div 10;
AMaxIntLastDigit = MaxInt mod 10;
var
L: Integer;
D: Integer;
begin
Result := False;
L := Length(S);
if (AIndex > L) or not IsDigit(S[AIndex]) then
Exit;
ANumber := 0;
repeat
D := StrToInt(S[AIndex]);
if (ANumber > AMaxLength) or
((ANumber = AMaxLength) and (D > AMaxIntLastDigit)) then
Exit;
ANumber := ANumber * 10 + D;
Inc(AIndex);
until (AIndex > L) or not IsDigit(S[AIndex]);
Result := True;
end;
function CalculateItemsByCaptionsValue: Boolean;
function GetCaptions(ACaptions: TStringList): Boolean;
var
S: string;
ACaptionLength, AIndex, AValueLength: Integer;
AChecked: Boolean;
begin
S := VarToStr(AValue);
Result := S = '';
if Result then
Exit;
Result := False;
AChecked := False;
AValueLength := Length(S);
AIndex := 1;
repeat
if (S[AIndex] = ';') and not AChecked then
begin
AChecked := True;
Inc(AIndex);
end;
if not GetNumber(ACaptionLength, AIndex, S) then
Exit;
if (AIndex > AValueLength) or (S[AIndex] <> ':') then
Exit;
Inc(AIndex);
if AIndex + ACaptionLength - 1 > AValueLength then
Exit;
ACaptions.AddObject(Copy(S, AIndex, ACaptionLength),
Pointer(AChecked));
Inc(AIndex, ACaptionLength);
if AIndex > AValueLength then
Break;
until (AIndex > AValueLength);
Result := True;
end;
function CalculateStates(ACaptions: TStringList): Boolean;
var
AIndex, I: Integer;
begin
for I := 0 to AItems.Count - 1 do
begin
AIndex := ACaptions.IndexOf(AItems.Captions[I]);
if AIndex = -1 then
ACheckStates[I] := cbsUnchecked
else
begin
if Boolean(ACaptions.Objects[AIndex]) then
ACheckStates[I] := cbsChecked
else
ACheckStates[I] := cbsGrayed;
ACaptions.Delete(AIndex);
end;
end;
Result := ACaptions.Count = 0;
end;
var
ACaptions: TStringList;
begin
if not(VarIsNull(AValue) or VarIsStr(AValue)) then
begin
Result := False;
Exit;
end;
ACaptions := TStringList.Create;
try
Result := GetCaptions(ACaptions);
if not Result then
Exit;
ACaptions.Sort;
Result := CalculateStates(ACaptions);
finally
FreeAndNil(ACaptions);
end;
end;
procedure SetStatesToUnchecked;
var
I: Integer;
begin
for I := 0 to AItems.Count - 1 do
ACheckStates[I] := cbsUnchecked;
end;
function CalculateItemsByIndicesValue: Boolean;
var
AChecked: Boolean;
AIndex, AItemIndex, L: Integer;
S: string;
begin
Result := VarIsNull(AValue) or VarIsStr(AValue);
if not Result then
Exit;
S := VarToStr(AValue);
SetStatesToUnchecked;
if S = '' then
Exit;
Result := False;
AIndex := 1;
L := Length(S);
AChecked := False;
repeat
if (S[AIndex] = ';') and not AChecked then
begin
AChecked := True;
Inc(AIndex);
end;
if not GetNumber(AItemIndex, AIndex, S) or (AItemIndex >= AItems.Count) then
Exit;
if AChecked then
ACheckStates[AItemIndex] := cbsChecked
else
ACheckStates[AItemIndex] := cbsGrayed;
if AIndex > L then
Break;
if S[AIndex] = ',' then
Inc(AIndex);
until AIndex > L;
Result := True;
end;
function CalculateItemsByStatesIntegerValue: Boolean;
var
V: {$IFDEF DELPHI6}Int64{$ELSE}Integer{$ENDIF};
I, ACode: Integer;
begin
Result := VarIsNumericEx(AValue) or VarIsStr(AValue) or VarIsDate(AValue) or
VarIsNull(AValue);
if Result then
begin
if VarIsNull(AValue) then
V := 0
else
if VarIsStr(AValue) then
begin
Val(AValue, V, ACode);
Result := ACode = 0;
if not Result then
Exit;
end
else
V := VarAsType(AValue, {$IFDEF DELPHI6}varInt64{$ELSE}varInteger{$ENDIF});
for I := 0 to AItems.Count - 1 do
begin
if V and 1 = 0 then
ACheckStates[I] := cbsUnchecked
else
ACheckStates[I] := cbsChecked;
V := V shr 1;
end;
end
end;
function CalculateItemsByStatesStringValue: Boolean;
var
AItemCount, I: Integer;
S: string;
begin
Result := VarIsNull(AValue) or VarIsStr(AValue);
if not Result then
Exit;
Result := False;
S := VarToStr(AValue);
AItemCount := Length(S);
if AItemCount > AItems.Count then
AItemCount := AItems.Count;
for I := 1 to AItemCount do
if (S[I] < '0') or (S[I] > '2') then
Exit
else
ACheckStates[I - 1] := TcxCheckBoxState(Ord(S[I]) - Ord('0'));
if AItemCount < AItems.Count then
for I := AItemCount to AItems.Count - 1 do
ACheckStates[I] := cbsUnchecked;
Result := True;
end;
var
I: Integer;
begin
SetLength(ACheckStates, AItems.Count);
case AValueFormat of
cvfCaptions:
Result := CalculateItemsByCaptionsValue;
cvfIndices:
Result := CalculateItemsByIndicesValue;
cvfInteger:
Result := CalculateItemsByStatesIntegerValue;
cvfStatesString:
Result := CalculateItemsByStatesStringValue;
else
Result := False;
end;
if not Result then
for I := 0 to AItems.Count - 1 do
ACheckStates[I] := cbsUnchecked;
end;
procedure CalculateCustomCheckBoxViewInfo(ACanvas: TcxCanvas; AViewData: TcxCustomCheckBoxViewData;
AViewInfo: TcxCustomCheckBoxViewInfo);
procedure CheckFocusRectBounds;
var
AMaxRect: TRect;
begin
with AViewInfo do
begin
if Alignment = taCenter then
AMaxRect := Rect(FocusRect.Left, ClientRect.Top, FocusRect.Right, ClientRect.Bottom)
else
begin
AMaxRect := Rect(TextRect.Left - 1, TextRect.Top - 1 + 2 * Integer(IsInplace),
TextRect.Right + 1, TextRect.Bottom + 1 - 2 * Integer(IsInplace));
if AMaxRect.Right > BorderRect.Right - 1 then
AMaxRect.Right := BorderRect.Right - 1;
end;
if FocusRect.Left < AMaxRect.Left then
FocusRect.Left := AMaxRect.Left;
if FocusRect.Top < AMaxRect.Top then
FocusRect.Top := AMaxRect.Top;
if FocusRect.Right > AMaxRect.Right then
FocusRect.Right := AMaxRect.Right;
if FocusRect.Bottom > AMaxRect.Bottom then
FocusRect.Bottom := AMaxRect.Bottom;
end;
end;
begin
with AViewInfo do
begin
BackgroundColor := AViewData.Style.Color;
if Focused and ((not IsInplace or AViewData.Properties.IsEmbeddedEdit) and (Alignment <> taCenter) or
IsInplace and (Alignment = taCenter) and (epoShowFocusRectWhenInplace in PaintOptions)) then
begin
if Alignment = taCenter then
begin
FocusRect := ClientRect;
InflateRect(FocusRect, -1, -1);
end
else
if Length(Text) <> 0 then
begin
FocusRect := TextRect;
if not AViewData.Properties.FullFocusRect then
begin
ACanvas.Font := Font;
ACanvas.TextExtent(Text, FocusRect, DrawTextFlags);
end;
InflateRect(FocusRect, 1, 1);
Inc(FocusRect.Bottom);
end
else
FocusRect := cxEmptyRect;
end
else
FocusRect := cxEmptyRect;
if not IsRectEmpty(FocusRect) then
CheckFocusRectBounds;
end;
end;
procedure DrawCheckBoxText(ACanvas: TcxCanvas; AText: string; AFont: TFont;
ATextColor: TColor; ATextRect: TRect; ADrawTextFlags: Integer; AEnabled: Boolean);
begin
ACanvas.Font := AFont;
ACanvas.Font.Color := ATextColor;
ACanvas.Brush.Style := bsClear;
ACanvas.DrawText(AText, ATextRect, ADrawTextFlags, AEnabled);
ACanvas.Brush.Style := bsSolid;
end;
function IsGlyphValid(AGlyph: TBitmap; AGlyphCount: Integer): Boolean;
begin
Result := (AGlyphCount > 0) and VerifyBitmap(AGlyph);
end;
function GetCheckNativeState(AState: TcxCheckBoxState; ACheckState: TcxEditCheckState): Integer;
const
ANativeCheckStateMap: array[TcxCheckBoxState, TcxEditCheckState] of Integer = (
(CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED, CBS_UNCHECKEDDISABLED),
(CBS_CHECKEDNORMAL, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED, CBS_CHECKEDDISABLED),
(CBS_MIXEDNORMAL, CBS_MIXEDHOT, CBS_MIXEDPRESSED, CBS_MIXEDDISABLED)
);
begin
Result := ANativeCheckStateMap[AState, ACheckState];
end;
procedure DrawCustomCheckBox(ACanvas: TcxCanvas; AViewInfo: TcxCustomCheckBoxViewInfo); overload;
var
AIsBackgroundTransparent: Boolean;
ACheckRect: TRect;
ACheckTransparent: Boolean;
begin
AIsBackgroundTransparent := AViewInfo.IsBackgroundTransparent;
// ACanvas.Brush.Color := AViewInfo.BackgroundColor; // to fix problem with DC color after RestoreDC
ACheckRect := AViewInfo.CheckBoxRect;
InflateRect(ACheckRect, -AViewInfo.CheckBorderOffset, -AViewInfo.CheckBorderOffset);
ACheckTransparent := AIsBackgroundTransparent and
(Assigned(AViewInfo.Painter) or AViewInfo.HasGlyph or
AViewInfo.NativeStyle and IsThemeBackgroundPartiallyTransparent(
OpenTheme(totButton), BP_CHECKBOX, GetCheckNativeState(AViewInfo.State, AViewInfo.CheckBoxState)));
AViewInfo.DrawEditBackground(ACanvas, AViewInfo.Bounds, ACheckRect, ACheckTransparent);
DrawEditCheck(ACanvas, AViewInfo.CheckBoxRect, AViewInfo.State, AViewInfo.CheckBoxState,
AViewInfo.CheckBoxGlyph, AViewInfo.CheckBoxGlyphCount,
AViewInfo.CheckBoxBorderStyle, AViewInfo.NativeStyle,
AViewInfo.BorderColor, AViewInfo.BackgroundColor, not AIsBackgroundTransparent,
AViewInfo.IsDesigning, AViewInfo.Focused, True, AViewInfo.Painter,
AViewInfo.NullValueShowingStyle);
if AViewInfo.Alignment <> taCenter then
DrawCheckBoxText(ACanvas, AViewInfo.Text, AViewInfo.Font, AViewInfo.TextColor,
AViewInfo.TextRect, AViewInfo.DrawTextFlags, AViewInfo.IsTextEnabled);
if not IsRectEmpty(AViewInfo.FocusRect) then
ACanvas.DrawFocusRect(AViewInfo.FocusRect);
end;
procedure DrawEditCheck(ACanvas: TcxCanvas; const ACheckRect: TRect;
AState: TcxCheckBoxState; ACheckState: TcxEditCheckState; AGlyph: TBitmap;
AGlyphCount: Integer; ABorderStyle: TcxEditCheckBoxBorderStyle;
ANativeStyle: Boolean; ABorderColor: TColor; ABackgroundColor: TColor;
ADrawBackground, AIsDesigning, AFocused, ASupportGrayed: Boolean;
APainter: TcxCustomLookAndFeelPainterClass;
AGrayedShowingStyle: TcxCheckBoxNullValueShowingStyle = nssGrayedChecked);
const
CheckState2ButtonState: array[TcxEditCheckState] of TcxButtonState =
(cxbsNormal, cxbsHot, cxbsPressed, cxbsDisabled);
procedure DrawCheckBoxGlyph;
var
ABitmap: TBitmap;
AGlyphIndex: Integer;
R: TRect;
begin
AGlyphIndex := GetEditCheckGlyphIndex(AState, ACheckState, ASupportGrayed,
AGlyphCount);
ABitmap := TBitmap.Create;
try
ABitmap.Assign(AGlyph);
ABitmap.Height := ACheckRect.Bottom - ACheckRect.Top;
ABitmap.Width := ACheckRect.Right - ACheckRect.Left;
R.Left := (AGlyph.Width div AGlyphCount) * AGlyphIndex;
R.Right := R.Left + ABitmap.Width;
R.Top := (AGlyph.Height - ABitmap.Height) div 2;
R.Bottom := R.Top + ABitmap.Height;
ABitmap.Canvas.CopyRect(Rect(0, 0, ABitmap.Width, ABitmap.Height),
AGlyph.Canvas, R);
DrawGlyph(ACanvas, ACheckRect.Left, ACheckRect.Top, ABitmap,
ACheckState <> ecsDisabled, ColorToRGB(ABackgroundColor));
finally
ABitmap.Free;
end;
end;
procedure DrawCheckBoxBorder;
const
ACheckBoxStateToButtonStateMap: array [TcxEditCheckState] of TcxButtonState =
(cxbsNormal, cxbsHot, cxbsPressed, cxbsDisabled);
var
ACheckBorderOffset: Integer;
R: TRect;
begin
if ANativeStyle then
begin
DrawThemeBackground(OpenTheme(totButton), ACanvas.Handle, BP_CHECKBOX,
GetCheckNativeState(AState, ACheckState), ACheckRect);
Exit;
end;
R := ACheckRect;
ACheckBorderOffset := GetEditCheckBorderOffset(ABorderStyle, False, False, APainter);
if ADrawBackground and (ACheckBorderOffset > 0) then
ACanvas.FrameRect(R, ABackgroundColor, ACheckBorderOffset);
InflateRect(R, -ACheckBorderOffset, -ACheckBorderOffset);
with ACanvas do
begin
case ABorderStyle of
ebsSingle:
FrameRect(R, ABorderColor);
ebsThick:
FrameRect(R, ABorderColor, 2);
ebsFlat:
begin
DrawEdge(R, True, True, cxBordersAll);
InflateRect(R, -1, -1);
FrameRect(R, clBtnFace);
end;
ebs3D:
begin
DrawEdge(R, True, True, cxBordersAll);
InflateRect(R, -1, -1);
DrawComplexFrame(R, cl3DDkShadow, cl3DLight, cxBordersAll);
end;
ebsUltraFlat, ebsOffice11:
begin
if (ABorderStyle = ebsOffice11) and (ACheckState = ecsNormal) and
not AIsDesigning and not AFocused then
ABorderColor := clBtnText
else
if (ACheckState in [ecsHot, ecsPressed]) or
AIsDesigning and (ACheckState <> ecsDisabled) or
(ACheckState = ecsNormal) and AFocused then
ABorderColor := GetEditBorderHighlightColor(
ABorderStyle = ebsOffice11)
else
ABorderColor := clBtnShadow;
FrameRect(R, ABorderColor);
end;
end;
end;
end;
procedure DrawCheck(R: TRect; AColor: TColor);
const
ROP_PSDPxax = $B8074A;
var
APrevClipRgn: TcxRegion;
begin
APrevClipRgn := ACanvas.GetClipRegion;
try
ACanvas.SetClipRegion(TcxRegion.Create(R), roIntersect);
InflateRect(R, cxEditMaxCheckBoxBorderWidth, cxEditMaxCheckBoxBorderWidth);
ACanvas.Brush.Color := AColor;
BitBlt(ACanvas.Handle, R.Left, R.Top, FCheckMask.Width, FCheckMask.Height,
FCheckMask.Canvas.Handle, 0, 0, ROP_PSDPxax);
finally
ACanvas.SetClipRegion(APrevClipRgn, roSet);
end;
end;
function GetCheckBoxContentColor: TColor;
const
AColors: array[TcxEditCheckState] of TColor =
(clWindow, clWindow, clBtnFace, clBtnFace);
begin
if ABorderStyle in [ebsUltraFlat, ebsOffice11] then
case ACheckState of
ecsNormal:
if (AState = cbsGrayed) and (AGrayedShowingStyle = nssInactive) then
Result := clBtnFace
else
Result := clWindow;
ecsHot, ecsPressed:
Result := GetEditButtonHighlightColor(
ACheckState = ecsPressed,
ABorderStyle = ebsOffice11);
else
Result := clBtnFace;
end
else
if (AState = cbsGrayed) and (AGrayedShowingStyle = nssInactive) then
Result := clBtnFace
else
Result := AColors[ACheckState];
end;
procedure InternalDrawCheckBoxContent(AContentRect: TRect);
const
AButtonStateMap: array [TcxEditCheckState] of TcxButtonState =
(cxbsNormal, cxbsHot, cxbsPressed, cxbsDisabled);
var
ACheckColor: TColor;
begin
cxEditFillRect(ACanvas.Handle, AContentRect,
GetSolidBrush(GetCheckBoxContentColor));
if (AState = cbsUnchecked) or
(AState = cbsGrayed) and (AGrayedShowingStyle <> nssGrayedChecked) then
Exit;
if (ACheckState = ecsDisabled) or (AState = cbsGrayed) then
ACheckColor := clBtnShadow
else
ACheckColor := clBtnText;
DrawCheck(AContentRect, ACheckColor);
end;
procedure DrawWindowsCheckBoxContent(AContentRect: TRect);
const
ABorder3DStyleMap: array [Boolean] of Integer = (DFCS_FLAT, 0);
AGrayedShowingStyleMap: array [TcxCheckBoxNullValueShowingStyle] of Integer =
(0, DFCS_INACTIVE, DFCS_CHECKED);
var
AClipRgnExists: Boolean;
AFlags: Integer;
APrevClipRgn: HRGN;
begin
if ACheckState = ecsDisabled then
begin
AFlags := DFCS_BUTTON3STATE or DFCS_PUSHED;
if (AState = cbsUnchecked) or ((AState = cbsGrayed) and (AGrayedShowingStyle <> nssGrayedChecked)) then
AFlags := AFlags or DFCS_INACTIVE
else
AFlags := AFlags or DFCS_CHECKED;
end
else
begin
AFlags := 0;
case AState of
cbsGrayed:
AFlags := DFCS_BUTTON3STATE or
AGrayedShowingStyleMap[AGrayedShowingStyle];
cbsChecked:
AFlags := DFCS_CHECKED;
end;
if ACheckState = ecsPressed then
AFlags := AFlags or DFCS_PUSHED;
end;
APrevClipRgn := CreateRectRgn(0, 0, 0, 0);
AClipRgnExists := GetClipRgn(ACanvas.Handle, APrevClipRgn) = 1;
with AContentRect do
IntersectClipRect(ACanvas.Handle, Left, Top, Right, Bottom);
InflateRect(AContentRect, cxEditMaxCheckBoxBorderWidth, cxEditMaxCheckBoxBorderWidth);
DrawFrameControl(ACanvas.Handle, AContentRect, DFC_BUTTON, DFCS_BUTTONCHECK or AFlags or ABorder3DStyleMap[ABorderStyle = ebs3D]);
if AClipRgnExists then
SelectClipRgn(ACanvas.Handle, APrevClipRgn)
else
SelectClipRgn(ACanvas.Handle, 0);
DeleteObject(APrevClipRgn);
end;
procedure DrawCheckBoxContent;
var
ACheckBoxBorderWidth: Integer;
R: TRect;
begin
if ANativeStyle then
Exit;
ACheckBoxBorderWidth := cxEditMaxCheckBoxBorderWidth;
R := ACheckRect;
InflateRect(R, -ACheckBoxBorderWidth, -ACheckBoxBorderWidth);
if ABorderStyle in [ebsUltraFlat, ebsOffice11] then
InternalDrawCheckBoxContent(R)
else
DrawWindowsCheckBoxContent(R);
end;
begin
if not ADrawBackground then
ABackgroundColor := clNone;
if (AState = cbsGrayed) and (AGrayedShowingStyle = nssUnchecked) then
AState := cbsUnchecked;
if IsGlyphValid(AGlyph, AGlyphCount) then
DrawCheckBoxGlyph
else
begin
if APainter <> nil then
begin
if ADrawBackground then
ACanvas.FillRect(ACheckRect, ABackgroundColor);
APainter.DrawCheckButton(ACanvas, ACheckRect,
CheckState2ButtonState[ACheckState], AState);
end
else
begin
DrawCheckBoxBorder;
DrawCheckBoxContent;
end;
end;
end;
function GetEditCheckBorderOffset(ACheckBorderStyle: TcxContainerBorderStyle;
ANativeStyle, AHasGlyph: Boolean; APainter: TcxCustomLookAndFeelPainterClass): Integer;
begin
if ANativeStyle or AHasGlyph or (APainter <> nil) then
Result := 0
else
Result := cxContainerMaxBorderWidth - GetContainerBorderWidth(ACheckBorderStyle);
end;
function GetEditCheckBorderOffset(ACheckBorderStyle: TcxEditBorderStyle;
ANativeStyle, AHasGlyph: Boolean; APainter: TcxCustomLookAndFeelPainterClass): Integer; overload;
begin
Result := GetEditCheckBorderOffset(
TcxContainerBorderStyle(ACheckBorderStyle), ANativeStyle, AHasGlyph, APainter);
end;
function GetEditCheckBorderOffset(ALookAndFeelKind: TcxLookAndFeelKind;
ANativeStyle, AHasGlyph: Boolean; APainter: TcxCustomLookAndFeelPainterClass): Integer;
begin
if ANativeStyle or AHasGlyph or (APainter <> nil) then
Result := 0
else
Result := cxContainerMaxBorderWidth - GetContainerBorderWidth(ALookAndFeelKind);
end;
function GetEditCheckGlyphIndex(AState: TcxCheckBoxState;
ACheckState: TcxEditCheckState; ASupportGrayed: Boolean;
AGlyphCount: Integer): Integer;
var
AStateCount: Integer;
begin
AStateCount := Integer(High(TcxCheckBoxState)) -
Integer(Low(TcxCheckBoxState)) + 1;
if not ASupportGrayed and (AGlyphCount mod 3 <> 0) and (AGlyphCount mod 2 = 0) then
Dec(AStateCount);
case AState of
cbsUnchecked:
Result := 0;
cbsChecked:
Result := 1;
else
Result := 2;
end;
if ACheckState = ecsPressed then
Inc(Result, AStateCount);
if (Result >= AGlyphCount) and (Result > AStateCount - 1) then
Result := Result mod AStateCount;
end;
function GetEditCheckSize(ACanvas: TcxCanvas; ANativeStyle: Boolean;
AGlyph: TBitmap; AGlyphCount: Integer; APainter: TcxCustomLookAndFeelPainterClass): TSize;
var
AHasGlyph: Boolean;
begin
AHasGlyph := IsGlyphValid(AGlyph, AGlyphCount);
if AHasGlyph then
begin
Result.cx := AGlyph.Width div AGlyphCount;
Result.cy := AGlyph.Height;
end
else
if APainter <> nil then
Result := APainter.CheckButtonSize
else
if AreVisualStylesMustBeUsed(ANativeStyle, totButton) then
with TcxWinXPLookAndFeelPainter do
Result := CheckButtonSize
else
with TcxCustomLookAndFeelPainter do
Result := CheckButtonSize;
end;
{ TcxCaptionItem }
procedure TcxCaptionItem.Assign(Source: TPersistent);
begin
if Source is TcxCaptionItem then
begin
Caption := TcxCaptionItem(Source).Caption;
Tag := TcxCaptionItem(Source).Tag;
end
else
inherited;
end;
function TcxCaptionItem.IsTagStored: Boolean;
begin
Result := FTag <> 0;
end;
procedure TcxCaptionItem.SetCaption(AValue: TCaption);
begin
if Caption <> AValue then
begin
FCaption := AValue;
if (Collection <> nil) and TcxCaptionItems(Collection).Sorted then
TcxCaptionItems(Collection).Sort
else
Changed(False);
end;
end;
{ TcxCaptionItems }
function TcxCaptionItems.DoCompareItems(AItem1, AItem2: TcxInterfacedCollectionItem): Integer;
begin
Result := AnsiCompareText(TcxCaptionItem(AItem1).Caption, TcxCaptionItem(AItem2).Caption);
end;
function TcxCaptionItems.GetCaption(AIndex: Integer): string;
begin
Result := Items[Aindex].Caption;
end;
function TcxCaptionItems.GetCount: Integer;
begin
Result := Count;
end;
function TcxCaptionItems.GetItem(AIndex: Integer): TcxCaptionItem;
begin
Result := TcxCaptionItem(inherited Items[AIndex]);
end;
procedure TcxCaptionItems.SetItem(AIndex: Integer; AValue: TcxCaptionItem);
begin
inherited Items[AIndex] := AValue;
end;
{ TcxCustomCheckBoxViewInfo }
procedure TcxCustomCheckBoxViewInfo.Assign(Source: TObject);
begin
if Source is TcxCustomCheckBoxViewInfo then
with Source as TcxCustomCheckBoxViewInfo do
begin
Self.CheckBoxState := CheckBoxState;
Self.State := State;
end;
inherited Assign(Source);
end;
procedure TcxCustomCheckBoxViewInfo.DrawText(ACanvas: TcxCanvas);
begin
DrawCheckBoxText(ACanvas, Text, Font, TextColor, TextRect, DrawTextFlags, IsTextEnabled);
end;
function TcxCustomCheckBoxViewInfo.GetUpdateRegion(AViewInfo: TcxContainerViewInfo): TcxRegion;
var
AEquals: Boolean;
ATempRgn: TcxRegion;
begin
Result := inherited GetUpdateRegion(AViewInfo);
if not(AViewInfo is TcxCustomCheckBoxViewInfo) then
Exit;
with TcxCustomCheckBoxViewInfo(AViewInfo) do
AEquals := (Self.CheckBoxState = CheckBoxState) and (Self.State = State);
if not AEquals then
begin
ATempRgn := TcxRegion.Create(CheckBoxRect);
UniteRegions(Result, ATempRgn);
ATempRgn.Free;
end;
end;
function TcxCustomCheckBoxViewInfo.IsHotTrack: Boolean;
begin
Result := True;
end;
function TcxCustomCheckBoxViewInfo.IsHotTrack(P: TPoint): Boolean;
begin
Result := IsHotTrack;
end;
function TcxCustomCheckBoxViewInfo.NeedShowHint(ACanvas: TcxCanvas;
const P: TPoint; out AText: TCaption; out AIsMultiLine: Boolean;
out ATextRect: TRect): Boolean;
begin
Result := False;
end;
procedure TcxCustomCheckBoxViewInfo.Offset(DX, DY: Integer);
begin
inherited Offset(DX, DY);
OffsetRect(CheckBoxRect, DX, DY);
OffsetRect(FocusRect, DX, DY);
end;
function TcxCustomCheckBoxViewInfo.Repaint(AControl: TWinControl;
const AInnerEditRect: TRect; AViewInfo: TcxContainerViewInfo = nil): Boolean;
var
R: TRect;
begin
Result := AControl.HandleAllocated;
if not Result then
Exit;
Result := inherited Repaint(AControl, AInnerEditRect, AViewInfo);
with TcxCustomCheckBoxViewInfo(AViewInfo) do
begin
Result := Result or (AViewInfo <> nil) and
((Self.CheckBoxState <> CheckBoxState) or (Self.State <> State));
if (AViewInfo = nil) or (Self.CheckBoxState <> CheckBoxState) or (Self.State <> State) then
begin
R := Self.CheckBoxRect;
OffsetRect(R, Self.Left, Self.Top);
InternalInvalidate(AControl.Handle, R, cxEmptyRect, False);
end;
end;
end;
function TcxCustomCheckBoxViewInfo.IsTextEnabled: Boolean;
begin
Result := IsContainerInnerControl or Enabled or IsTextColorAssigned or NativeStyle;
end;
procedure TcxCustomCheckBoxViewInfo.InternalPaint(ACanvas: TcxCanvas);
begin
DrawCustomCheckBox(ACanvas, Self);
end;
function TcxCustomCheckBoxViewInfo.GetEdit: TcxCustomCheckBox;
begin
Result := TcxCustomCheckBox(FEdit);
end;
{ TcxCustomCheckBoxViewData }
procedure TcxCustomCheckBoxViewData.Calculate(ACanvas: TcxCanvas; const ABounds: TRect;
const P: TPoint; Button: TcxMouseButton; Shift: TShiftState; AViewInfo: TcxCustomEditViewInfo;
AIsMouseEvent: Boolean);
procedure CalculateCheckBoxRect(ACheckBoxViewInfo: TcxCustomCheckBoxViewInfo; const ACheckSize: TSize);
var
ACheckBoxRect, AAvailableArea: TRect;
AAlignment: TAlignment;
begin
AAlignment := ACheckBoxViewInfo.Alignment;
AAvailableArea := AViewInfo.ClientRect;
if IsInplace and not Properties.IsEmbeddedEdit then
case AAlignment of
taLeftJustify: Inc(AAvailableArea.Left, 2);
taRightJustify: Dec(AAvailableArea.Right, 2);
end;
if not (IsInplace or AreVisualStylesMustBeUsed(AViewInfo.NativeStyle, totButton) and Properties.IsEmbeddedEdit) then
InflateRect(AAvailableArea, -2, -2);
ACheckBoxRect := cxRectCenter(AAvailableArea, Min(ACheckSize.cx, cxRectWidth(AAvailableArea)), ACheckSize.cy);
if cxRectWidth(AAvailableArea) > ACheckSize.cx then
case AAlignment of
taLeftJustify:
begin
ACheckBoxRect.Left := AAvailableArea.Left;
ACheckBoxRect.Right := ACheckBoxRect.Left + ACheckSize.cx;
end;
taRightJustify:
begin
ACheckBoxRect.Right := AAvailableArea.Right;
ACheckBoxRect.Left := ACheckBoxRect.Right - ACheckSize.cx;
end;
end;
ACheckBoxViewInfo.CheckBoxRect := ACheckBoxRect;
end;
procedure CalculateTextRect(ACheckBoxViewInfo: TcxCustomCheckBoxViewInfo);
var
ACaptionRect: TRect;
AAlignment: TAlignment;
begin
AAlignment := ACheckBoxViewInfo.Alignment;
ACaptionRect := AViewInfo.ClientRect;
if IsInplace then
begin
case AAlignment of
taLeftJustify: Dec(ACaptionRect.Right, 2);
taRightJustify: Inc(ACaptionRect.Left, 2);
end;
Inc(ACaptionRect.Top, EditContentParams.Offsets.Top);
Dec(ACaptionRect.Bottom, EditContentParams.Offsets.Bottom);
end
else
begin
InflateRect(ACaptionRect, -2, -2);
if not Properties.IsEmbeddedEdit and (not EmulateStandardControlDrawing or
not AreVisualStylesMustBeUsed(AViewInfo.NativeStyle, totButton) and (Style.LookAndFeel.SkinPainter = nil)) then
Dec(ACaptionRect.Top);
end;
if cxRectWidth(ACheckBoxViewInfo.CheckBoxRect) < cxRectWidth(AViewInfo.ClientRect) then
case AAlignment of
taLeftJustify:
ACaptionRect.Left := ACheckBoxViewInfo.CheckBoxRect.Right + 3;
taRightJustify:
ACaptionRect.Right := ACheckBoxViewInfo.CheckBoxRect.Left - 3 + Integer(IsInplace and Properties.IsEmbeddedEdit);
end
else
ACaptionRect.Right := ACaptionRect.Left;
if not ACheckBoxViewInfo.IsTextEnabled and (Style.LookAndFeel.SkinPainter = nil) then
begin
Inc(ACaptionRect.Right);
Inc(ACaptionRect.Bottom);
end;
ACheckBoxViewInfo.TextRect := ACaptionRect;
end;
function GetCheckBoxBorderStyle(AEditHotState: TcxContainerHotState): TcxEditBorderStyle;
const
ABorderStyles: array[TcxContainerHotState, TcxEditBorderStyle] of TcxEditBorderStyle = (
(ebsNone, ebsSingle, ebsThick, ebsFlat, ebs3D, ebsUltraFlat, ebsOffice11),
(ebsNone, ebsSingle, ebsThick, ebsFlat, ebs3D, ebsUltraFlat, ebsOffice11),
(ebsFlat, ebsThick, ebsThick, ebs3D, ebs3D, ebsUltraFlat, ebsOffice11)
);
begin
Result := ABorderStyles[AEditHotState, Style.BorderStyle];
end;
var
ACheckBoxViewInfo: TcxCustomCheckBoxViewInfo;
begin
inherited Calculate(ACanvas, ABounds, P, Button, Shift, AViewInfo, AIsMouseEvent);
ACheckBoxViewInfo := TcxCustomCheckBoxViewInfo(AViewInfo);
ACheckBoxViewInfo.IsEditClass := GetIsEditClass;
ACheckBoxViewInfo.DrawSelectionBar := False;
ACheckBoxViewInfo.HasPopupWindow := False;
ACheckBoxViewInfo.DrawTextFlags := GetDrawTextFlags;
CalculateCheckBoxViewInfo(Self, ACheckBoxViewInfo, AIsMouseEvent);
if Edit <> nil then
ACheckBoxViewInfo.Text := TcxCustomCheckBox(Edit).Caption;
if IsInplace and not (Properties.IsEmbeddedEdit or
Properties.UseAlignmentWhenInplace or (ACheckBoxViewInfo.Text <> '')) then
ACheckBoxViewInfo.Alignment := taCenter
else
ACheckBoxViewInfo.Alignment := Properties.Alignment;
ACheckBoxViewInfo.CheckBoxBorderStyle := GetCheckBoxBorderStyle(AViewInfo.HotState);
ACheckBoxViewInfo.CheckBoxGlyph := Properties.Glyph;
ACheckBoxViewInfo.CheckBoxGlyphCount := Properties.GlyphCount;
ACheckBoxViewInfo.NullValueShowingStyle := Properties.NullStyle;
ACheckBoxViewInfo.HasGlyph := IsGlyphValid(Properties.Glyph, Properties.GlyphCount);
ACheckBoxViewInfo.CheckBorderOffset :=
GetEditCheckBorderOffset(ACheckBoxViewInfo.CheckBoxBorderStyle, NativeStyle,
ACheckBoxViewInfo.HasGlyph, ACheckBoxViewInfo.Painter);
ACheckBoxViewInfo.IsTextColorAssigned := Style.IsValueAssigned(svTextColor) or
((ACheckBoxViewInfo.Painter <> nil) and
(ACheckBoxViewInfo.Painter.DefaultEditorTextColor(True) <> clDefault));
CalculateCheckBoxRect(ACheckBoxViewInfo, GetEditCheckSize(ACanvas, NativeStyle, Properties.Glyph,
Properties.GlyphCount, AViewInfo.Painter));
CalculateTextRect(ACheckBoxViewInfo);
if not Enabled then
ACheckBoxViewInfo.CheckBoxState := ecsDisabled
else
if IsCheckPressed then
ACheckBoxViewInfo.CheckBoxState := ecsPressed
else
if not IsDesigning and PtInRect(ACheckBoxViewInfo.BorderRect, P) then
if ([ssLeft, ssRight, ssMiddle] * Shift) = [] then
ACheckBoxViewInfo.CheckBoxState := ecsHot
else
if (ssLeft in Shift) and ((Button = cxmbLeft) or (ACheckBoxViewInfo.CheckBoxState = ecsPressed)) then
ACheckBoxViewInfo.CheckBoxState := ecsPressed
else
ACheckBoxViewInfo.CheckBoxState := ecsNormal
else
ACheckBoxViewInfo.CheckBoxState := ecsNormal;
CalculateCustomCheckBoxViewInfo(ACanvas, Self, ACheckBoxViewInfo);
if IsInplace and (ACheckBoxViewInfo.CheckBoxBorderStyle = ebsSingle) then
if (ACheckBoxViewInfo.CheckBoxState = ecsHot) or (IsDesigning and (ACheckBoxViewInfo.CheckBoxState <> ecsDisabled)) then
ACheckBoxViewInfo.BorderColor := clHighlight
else
ACheckBoxViewInfo.BorderColor := clBtnShadow;
end;
procedure TcxCustomCheckBoxViewData.EditValueToDrawValue(ACanvas: TcxCanvas;
const AEditValue: TcxEditValue; AViewInfo: TcxCustomEditViewInfo);
begin
if PreviewMode then
TcxCustomCheckBoxViewInfo(AViewInfo).State := cbsChecked
else
TcxCustomCheckBoxViewInfo(AViewInfo).State := Properties.GetState(AEditValue);
if IsInplace and not Properties.IsEmbeddedEdit then
TcxCustomCheckBoxViewInfo(AViewInfo).Text := '';
CalculateCustomCheckBoxViewInfo(ACanvas, Self, TcxCustomCheckBoxViewInfo(AViewInfo));
end;
function TcxCustomCheckBoxViewData.GetBorderStyle: TcxEditBorderStyle;
begin
Result := ebsNone;
end;
function TcxCustomCheckBoxViewData.InternalGetEditConstantPartSize(ACanvas: TcxCanvas;
AIsInplace: Boolean; AEditSizeProperties: TcxEditSizeProperties;
var MinContentSize: TSize; AViewInfo: TcxCustomEditViewInfo): TSize;
var
ACheckBoxViewInfo: TcxCustomCheckBoxViewInfo;
ASize1, ASize2: TSize;
AText: string;
begin
Result := inherited InternalGetEditConstantPartSize(ACanvas, AIsInplace,
AEditSizeProperties, MinContentSize, AViewInfo);
ACheckBoxViewInfo := TcxCustomCheckBoxViewInfo(AViewInfo);
with ACheckBoxViewInfo.CheckBoxRect do
ASize1 := Size(Right - Left, Bottom - Top);
if IsInplace then
if (ACheckBoxViewInfo.Alignment <> taCenter) and (ACheckBoxViewInfo.Text <> '') then
begin
ACanvas.Font := Style.GetVisibleFont;
ASize1.cx := ACheckBoxViewInfo.TextRect.Left - ACheckBoxViewInfo.Bounds.Left +
ACanvas.TextWidth(RemoveAccelChars(ACheckBoxViewInfo.Text)) +
(ACheckBoxViewInfo.Bounds.Right - ACheckBoxViewInfo.TextRect.Right);
end
else
ASize1.cx := ASize1.cx + 2 * 2;
if IsInplace then
ASize1.cy := ASize1.cy + (1 - ACheckBoxViewInfo.CheckBorderOffset) * 2
else
ASize1.cy := ASize1.cy + 2 * 2;
if (Properties.Alignment = taCenter) or IsInplace then
AText := 'Gg'
else
AText := RemoveAccelChars(TcxCustomCheckBox(Edit).Caption);
if not Enabled and not IsNativeStyle(Style.LookAndFeel) then
Dec(AEditSizeProperties.Width);
ASize2 := GetTextEditContentSize(ACanvas, Self, AText,
DrawTextFlagsTocxTextOutFlags(GetDrawTextFlags) or CXTO_SINGLELINE or CXTO_CHARBREAK,
AEditSizeProperties, 0, False);
if ASize1.cy < ASize2.cy then
ASize1.cy := ASize2.cy;
Result.cx := Result.cx + ASize1.cx;
Result.cy := Result.cy + ASize1.cy;
end;
function TcxCustomCheckBoxViewData.GetDrawTextFlags: Integer;
const
AHorzAlignmentFlags: array [TcxEditHorzAlignment] of Integer = (
cxAlignLeft, cxAlignLeft, cxAlignHCenter
);
begin
with Properties.InternalAlignment do
begin
Result := AHorzAlignmentFlags[Horz];
Result := Result or cxSingleLine;
end;
Result := Result or cxShowPrefix;
if Properties.MultiLine then
begin
Result := Result and (not cxSingleLine);
Result := Result or cxDontClip;
Result := Result or cxWordBreak;
end;
if IsInplace or not Properties.MultiLine then
Result := Result or cxAlignVCenter
else
Result := Result or cxAlignTop;
end;
function TcxCustomCheckBoxViewData.GetIsEditClass: Boolean;
begin
Result := True;
end;
function TcxCustomCheckBoxViewData.IsCheckPressed: Boolean;
begin
Result := (Edit <> nil) and TcxCustomCheckBox(Edit).FIsCheckPressed;
end;
function TcxCustomCheckBoxViewData.GetProperties: TcxCustomCheckBoxProperties;
begin
Result := TcxCustomCheckBoxProperties(FProperties);
end;
{ TcxCheckBoxStyle }
function TcxCheckBoxStyle.HasBorder: Boolean;
begin
Result := False;
end;
{ TcxCustomCheckBoxProperties }
constructor TcxCustomCheckBoxProperties.Create(AOwner: TPersistent);
begin
inherited Create(AOwner);
FDisplayChecked := cxGetResourceString(@cxSEditCheckBoxChecked);
FDisplayUnchecked := cxGetResourceString(@cxSEditCheckBoxUnchecked);
FDisplayGrayed := cxGetResourceString(@cxSEditCheckBoxGrayed);
FGlyphCount := 6;
FNullStyle := nssGrayedChecked;
FValueChecked := True;
FValueGrayed := Null;
FValueUnchecked := False;
end;
destructor TcxCustomCheckBoxProperties.Destroy;
begin
if FGlyph <> nil then
FreeAndNil(FGlyph);
inherited Destroy;
end;
procedure TcxCustomCheckBoxProperties.Assign(Source: TPersistent);
begin
if Source is TcxCustomCheckBoxProperties then
begin
BeginUpdate;
try
inherited Assign(Source);
with Source as TcxCustomCheckBoxProperties do
begin
Self.AllowGrayed := AllowGrayed;
Self.DisplayChecked := DisplayChecked;
Self.DisplayGrayed := DisplayGrayed;
Self.DisplayUnchecked := DisplayUnchecked;
Self.FullFocusRect := FullFocusRect;
Self.Glyph := Glyph;
Self.GlyphCount := GlyphCount;
Self.MultiLine := MultiLine;
Self.NullStyle := NullStyle;
Self.UseAlignmentWhenInplace := UseAlignmentWhenInplace;
Self.SetStateValues(ValueChecked, ValueGrayed, ValueUnchecked);
end;
finally
EndUpdate;
end
end
else
inherited Assign(Source);
end;
function TcxCustomCheckBoxProperties.CanCompareEditValue: Boolean;
begin
Result := True;
end;
function TcxCustomCheckBoxProperties.CompareDisplayValues(
const AEditValue1, AEditValue2: TcxEditValue): Boolean;
begin
Result := GetState(AEditValue1) = GetState(AEditValue2);
end;
class function TcxCustomCheckBoxProperties.GetContainerClass: TcxContainerClass;
begin
Result := TcxCheckBox;
end;
function TcxCustomCheckBoxProperties.GetDisplayText(const AEditValue: TcxEditValue;
AFullText: Boolean = False; AIsInplace: Boolean = True): WideString;
begin
case GetState(AEditValue) of
cbsChecked:
Result := FDisplayChecked;
cbsUnchecked:
Result := FDisplayUnchecked;
cbsGrayed:
Result := FDisplayGrayed;
end;
end;
class function TcxCustomCheckBoxProperties.GetStyleClass: TcxCustomEditStyleClass;
begin
Result := TcxCheckBoxStyle;
end;
function TcxCustomCheckBoxProperties.GetSpecialFeatures: TcxEditSpecialFeatures;
begin
Result := inherited GetSpecialFeatures + [esfNoContentPart];
end;
function TcxCustomCheckBoxProperties.GetSupportedOperations: TcxEditSupportedOperations;
begin
Result := [esoAlwaysHotTrack, esoEditing, esoFiltering, esoHotTrack,
esoShowingCaption, esoSorting, esoTransparency];
end;
class function TcxCustomCheckBoxProperties.GetViewInfoClass: TcxContainerViewInfoClass;
begin
Result := TcxCustomCheckBoxViewInfo;
end;
function TcxCustomCheckBoxProperties.IsActivationKey(AKey: Char): Boolean;
begin
Result := AKey = ' ';
end;
function TcxCustomCheckBoxProperties.IsEditValueValid(var EditValue: TcxEditValue; AEditFocused: Boolean): Boolean;
begin
Result := inherited IsEditValueValid(EditValue, AEditFocused);
if Result then
Result := not CheckValue(EditValue);
end;
function TcxCustomCheckBoxProperties.IsResetEditClass: Boolean;
begin
Result := True;
end;
procedure TcxCustomCheckBoxProperties.PrepareDisplayValue(const AEditValue:
TcxEditValue; var DisplayValue: TcxEditValue; AEditFocused: Boolean);
begin
if VarEqualsExact(AEditValue, FValueChecked) then
DisplayValue := Integer(cbsChecked)
else
if VarEqualsExact(AEditValue, FValueUnchecked) then
DisplayValue := Integer(cbsUnchecked)
else
DisplayValue := Integer(cbsGrayed);
end;
function TcxCustomCheckBoxProperties.CanValidate: Boolean;
begin
Result := True;
end;
procedure TcxCustomCheckBoxProperties.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('Caption', ReadCaption, nil, False);
end;
class function TcxCustomCheckBoxProperties.GetViewDataClass: TcxCustomEditViewDataClass;
begin
Result := TcxCustomCheckBoxViewData;
end;
function TcxCustomCheckBoxProperties.HasDisplayValue: Boolean;
begin
Result := True;
end;
function TcxCustomCheckBoxProperties.CheckValue(const AValue: TcxEditValue): Boolean;
begin
Result := not(InternalVarEqualsExact(AValue, FValueChecked) or InternalVarEqualsExact(AValue,
FValueGrayed) or InternalVarEqualsExact(AValue, FValueUnchecked));
end;
function TcxCustomCheckBoxProperties.GetState(
const AEditValue: TcxEditValue): TcxCheckBoxState;
var
ADisplayValue: TcxEditValue;
begin
PrepareDisplayValue(AEditValue, ADisplayValue, False);
Result := TcxCheckBoxState(Integer(ADisplayValue));
end;
function TcxCustomCheckBoxProperties.InternalGetGlyph: TBitmap;
begin
if FGlyph = nil then
begin
FGlyph := TBitmap.Create;
FGlyph.OnChange := GlyphChanged;
end;
Result := FGlyph;
end;
function TcxCustomCheckBoxProperties.IsEmbeddedEdit: Boolean;
begin
Result := False;
end;
function TcxCustomCheckBoxProperties.GetAlignment: TAlignment;
begin
Result := inherited Alignment.Horz;
end;
function TcxCustomCheckBoxProperties.GetGlyph: TBitmap;
begin
Result := InternalGetGlyph;
end;
function TcxCustomCheckBoxProperties.GetInternalAlignment: TcxEditAlignment;
begin
Result := inherited Alignment;
end;
procedure TcxCustomCheckBoxProperties.GlyphChanged(Sender: TObject);
begin
Changed;
end;
function TcxCustomCheckBoxProperties.IsAlignmentStored: Boolean;
begin
Result := inherited Alignment.IsHorzStored;
end;
function TcxCustomCheckBoxProperties.IsDisplayCheckedStored: Boolean;
begin
Result := not InternalCompareString(FDisplayChecked,
cxGetResourceString(@cxSEditCheckBoxChecked), True);
end;
function TcxCustomCheckBoxProperties.IsDisplayGrayedStored: Boolean;
begin
Result := not InternalCompareString(FDisplayGrayed,
cxGetResourceString(@cxSEditCheckBoxGrayed), True);
end;
function TcxCustomCheckBoxProperties.IsDisplayUncheckedStored: Boolean;
begin
Result := not InternalCompareString(FDisplayUnchecked,
cxGetResourceString(@cxSEditCheckBoxUnchecked), True);
end;
function TcxCustomCheckBoxProperties.IsLoading: Boolean;
begin
Result := (GetOwnerComponent(Self) <> nil) and (csLoading in GetOwnerComponent(Self).ComponentState);
end;
function TcxCustomCheckBoxProperties.IsValueCheckedStored: Boolean;
begin
Result := not InternalVarEqualsExact(FValueChecked, True);
end;
function TcxCustomCheckBoxProperties.IsValueGrayedStored: Boolean;
begin
Result := not VarIsNull(FValueGrayed);
end;
function TcxCustomCheckBoxProperties.IsValueUncheckedStored: Boolean;
begin
Result := not InternalVarEqualsExact(FValueUnchecked, False);
end;
// obsolete
procedure TcxCustomCheckBoxProperties.ReadCaption(Reader: TReader);
begin
Caption := Reader.ReadString;
end;
procedure TcxCustomCheckBoxProperties.SetAlignment(Value: TAlignment);
begin
inherited Alignment.Horz := Value;
end;
// obsolete
procedure TcxCustomCheckBoxProperties.SetCaption(const Value: TCaption);
begin
FIsCaptionAssigned := True;
if not InternalCompareString(Value, FCaption, True) then
begin
FCaption := Value;
Changed;
end;
end;
procedure TcxCustomCheckBoxProperties.SetFullFocusRect(Value: Boolean);
begin
if Value <> FFullFocusRect then
begin
FFullFocusRect := Value;
Changed;
end;
end;
procedure TcxCustomCheckBoxProperties.SetGlyph(Value: TBitmap);
begin
if Value = nil then
FreeAndNil(FGlyph)
else
Glyph.Assign(Value);
Changed;
end;
procedure TcxCustomCheckBoxProperties.SetGlyphCount(Value: Integer);
begin
if FGlyphCount <> Value then
begin
FGlyphCount := Value;
if FGlyph <> nil then
Changed;
end;
end;
procedure TcxCustomCheckBoxProperties.SetMultiLine(Value: Boolean);
begin
if Value <> FMultiLine then
begin
FMultiLine := Value;
Changed;
end;
end;
procedure TcxCustomCheckBoxProperties.SetNullStyle(Value: TcxCheckBoxNullValueShowingStyle);
begin
if Value <> FNullStyle then
begin
FNullStyle := Value;
Changed;
end;
end;
procedure TcxCustomCheckBoxProperties.SetStateValues(const AValueChecked, AValueGrayed, AValueUnchecked: TcxEditValue);
var
AIsValuesValid: Boolean;
begin
AIsValuesValid := not(InternalVarEqualsExact(AValueChecked, AValueGrayed) or
InternalVarEqualsExact(AValueGrayed, AValueUnchecked) or
InternalVarEqualsExact(AValueChecked, AValueUnchecked) or
VarIsNull(AValueChecked) or VarIsNull(AValueUnchecked));
if AIsValuesValid then
begin
FValueChecked := AValueChecked;
FValueGrayed := AValueGrayed;
FValueUnchecked := AValueUnchecked;
Changed;
end;
end;
procedure TcxCustomCheckBoxProperties.SetUseAlignmentWhenInplace(Value: Boolean);
begin
if Value <> FUseAlignmentWhenInplace then
begin
FUseAlignmentWhenInplace := Value;
Changed;
end;
end;
procedure TcxCustomCheckBoxProperties.SetValueChecked(const Value: TcxEditValue);
begin
if IsLoading or CheckValue(Value) and not VarIsNull(Value) then
begin
FValueChecked := Value;
Changed;
end;
end;
procedure TcxCustomCheckBoxProperties.SetValueGrayed(const Value: TcxEditValue);
begin
if IsLoading or CheckValue(Value) then
begin
FValueGrayed := Value;
Changed;
end;
end;
procedure TcxCustomCheckBoxProperties.SetValueUnchecked(const Value: TcxEditValue);
begin
if IsLoading or CheckValue(Value) and not VarIsNull(Value) then
begin
FValueUnchecked := Value;
Changed;
end;
end;
{ TcxCustomCheckBox }
procedure TcxCustomCheckBox.Clear;
begin
Checked := False;
end;
class function TcxCustomCheckBox.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxCustomCheckBoxProperties;
end;
procedure TcxCustomCheckBox.PrepareEditValue(const ADisplayValue: TcxEditValue;
out EditValue: TcxEditValue; AEditFocused: Boolean);
begin
case TcxCheckBoxState(Integer(ADisplayValue)) of
cbsUnchecked:
EditValue := ActiveProperties.FValueUnchecked;
cbsChecked:
EditValue := ActiveProperties.FValueChecked;
cbsGrayed:
EditValue := ActiveProperties.FValueGrayed;
end;
end;
procedure TcxCustomCheckBox.ActionChange(Sender: TObject; CheckDefaults: Boolean);
begin
inherited ActionChange(Sender, CheckDefaults);
if (IsLoading or FIsLoaded) and FIsLoadingStateAssigned or not(Sender is TCustomAction) then
Exit;
if not CheckDefaults or (Checked = False) then
TcxCheckBoxActionLink(ActionLink).InternalSetChecked(TCustomAction(Sender).Checked);
end;
function TcxCustomCheckBox.CanHaveTransparentBorder: Boolean;
begin
Result := not IsInplace and not ActiveProperties.IsEmbeddedEdit or
inherited CanHaveTransparentBorder;
end;
function TcxCustomCheckBox.DefaultParentColor: Boolean;
begin
Result := True;
end;
procedure TcxCustomCheckBox.DoEditKeyDown(var Key: Word; Shift: TShiftState);
begin
inherited DoEditKeyDown(Key, Shift);
if Key = 0 then
Exit;
case Key of
VK_SPACE:
begin
with ViewInfo do
if CheckBoxState in [ecsNormal, ecsHot] then
begin
FIsCheckPressed := True;
CheckBoxState := ecsPressed;
ShortRefreshContainer(False);
Key := 0;
end;
end;
end;
end;
procedure TcxCustomCheckBox.DoEditKeyPress(var Key: Char);
begin
inherited DoEditKeyPress(Key);
if Key = #0 then
Exit;
if IsInplace and (Key = #32) and (ViewInfo.CheckBoxState in [ecsNormal, ecsHot]) then
begin
Toggle;
Key := #0;
end;
end;
procedure TcxCustomCheckBox.DoEditKeyUp(var Key: Word; Shift: TShiftState);
begin
inherited DoEditKeyUp(Key, Shift);
if Key = 0 then
Exit;
case Key of
VK_SPACE:
begin
if ViewInfo.CheckBoxState = ecsPressed then
begin
FIsCheckPressed := False;
ViewInfo.CheckBoxState := ecsNormal;
InvalidateCheckRect;
Toggle;
end;
end;
end;
end;
procedure TcxCustomCheckBox.DoExit;
begin
FIsCheckPressed := False;
inherited DoExit;
end;
procedure TcxCustomCheckBox.FillSizeProperties(var AEditSizeProperties: TcxEditSizeProperties);
begin
AEditSizeProperties := DefaultcxEditSizeProperties;
if not ActiveProperties.MultiLine then
AEditSizeProperties.MaxLineCount := 1;
AEditSizeProperties.Width := cxRectWidth(ViewInfo.TextRect);
end;
function TcxCustomCheckBox.GetActionLinkClass: TControlActionLinkClass;
begin
Result := TcxCheckBoxActionLink;
end;
function TcxCustomCheckBox.GetEditStateColorKind: TcxEditStateColorKind;
begin
Result := cxEditStateColorKindMap[Enabled];
end;
function TcxCustomCheckBox.GetShadowBounds: TRect;
begin
if not IsInplace and not ActiveProperties.IsEmbeddedEdit and
ViewInfo.NativeStyle and Style.TransparentBorder then
begin
Result := GetControlRect(Self);
InflateRect(Result, -cxContainerMaxBorderWidth, -cxContainerMaxBorderWidth);
end
else
Result := inherited GetShadowBounds;
end;
procedure TcxCustomCheckBox.Initialize;
begin
inherited Initialize;
ControlStyle := ControlStyle - [csDoubleClicks];
Width := 121;
PrepareEditValue(Integer(cbsUnchecked), FEditValue, False);
end;
function TcxCustomCheckBox.InternalGetNotPublishedStyleValues: TcxEditStyleValues;
begin
Result := inherited InternalGetNotPublishedStyleValues;
Include(Result, svEdges);
end;
procedure TcxCustomCheckBox.InternalSetEditValue(const Value: TcxEditValue;
AValidateEditValue: Boolean);
var
APrevState: TcxCheckBoxState;
begin
APrevState := State;
inherited InternalSetEditValue(Value, AValidateEditValue);
if APrevState <> State then
begin
ViewInfo.State := State;
Click;
DoChange;
end;
ShortRefreshContainer(False);
end;
function TcxCustomCheckBox.IsClickEnabledDuringLoading: Boolean;
begin
Result := IsDBEdit;
end;
function TcxCustomCheckBox.IsNativeBackground: Boolean;
begin
Result := IsNativeStyle and ParentBackground and not IsInplace and
not Transparent;
end;
procedure TcxCustomCheckBox.Loaded;
begin
FIsLoaded := True;
LockChangeEvents(True);
LockClick(True);
try
inherited Loaded;
if FIsLoadingStateAssigned then
State := FLoadingState
else
if not IsDBEdit then
State := cbsUnchecked;
finally
LockClick(False);
LockChangeEvents(False, False);
FIsLoaded := False;
end;
end;
procedure TcxCustomCheckBox.ProcessViewInfoChanges(APrevViewInfo: TcxCustomEditViewInfo;
AIsMouseDownUpEvent: Boolean);
begin
if (TcxCustomCheckBoxViewInfo(APrevViewInfo).CheckBoxState = ecsPressed) and
(ViewInfo.CheckBoxState = ecsHot) then
Toggle;
end;
procedure TcxCustomCheckBox.PropertiesChanged(Sender: TObject);
begin
if ActiveProperties.FIsCaptionAssigned then
begin
Caption := ActiveProperties.Caption;
ActiveProperties.FIsCaptionAssigned := False;
end;
if ViewInfo.State <> State then
begin
ViewInfo.State := State;
InvalidateCheckRect;
if not AreChangeEventsLocked then
begin
Click;
DoChange;
end;
end;
inherited PropertiesChanged(Sender);
end;
procedure TcxCustomCheckBox.TextChanged;
begin
inherited TextChanged;
ViewInfo.Text := Caption;
Invalidate;
end;
procedure TcxCustomCheckBox.InvalidateCheckRect;
begin
InvalidateRect(ViewInfo.CheckBoxRect, False);
end;
procedure TcxCustomCheckBox.Toggle;
begin
LockChangeEvents(True);
try
KeyboardAction := True;
try
begin
case State of
cbsUnchecked:
if ActiveProperties.AllowGrayed then
State := cbsGrayed
else
State := cbsChecked;
cbsChecked:
State := cbsUnchecked;
cbsGrayed:
State := cbsChecked;
end;
end;
finally
KeyboardAction := False;
end;
if ActiveProperties.ImmediatePost and CanPostEditValue and ValidateEdit(True) then
InternalPostEditValue;
finally
LockChangeEvents(False);
end;
end;
function TcxCustomCheckBox.GetChecked: Boolean;
begin
Result := State = cbsChecked;
end;
function TcxCustomCheckBox.GetProperties: TcxCustomCheckBoxProperties;
begin
Result := TcxCustomCheckBoxProperties(FProperties);
end;
function TcxCustomCheckBox.GetActiveProperties: TcxCustomCheckBoxProperties;
begin
Result := TcxCustomCheckBoxProperties(InternalGetActiveProperties);
end;
function TcxCustomCheckBox.GetState: TcxCheckBoxState;
begin
Result := ActiveProperties.GetState(EditValue);
end;
function TcxCustomCheckBox.GetStyle: TcxCheckBoxStyle;
begin
Result := TcxCheckBoxStyle(FStyles.Style);
end;
function TcxCustomCheckBox.GetViewInfo: TcxCustomCheckBoxViewInfo;
begin
Result := TcxCustomCheckBoxViewInfo(FViewInfo);
end;
function TcxCustomCheckBox.IsStateStored: Boolean;
const
AStates: array[Boolean] of TcxCheckBoxState = (cbsUnchecked, cbsChecked);
begin
Result := not (Action is TCustomAction) or
(State <> AStates[TCustomAction(Action).Checked]);
end;
procedure TcxCustomCheckBox.SetChecked(Value: Boolean);
begin
if Value then
State := cbsChecked
else
State := cbsUnchecked;
end;
procedure TcxCustomCheckBox.SetProperties(Value: TcxCustomCheckBoxProperties);
begin
FProperties.Assign(Value);
end;
procedure TcxCustomCheckBox.SetState(Value: TcxCheckBoxState);
var
AEditValue: TcxEditValue;
begin
if IsLoading then
begin
FLoadingState := Value;
FIsLoadingStateAssigned := True;
end
else
if Value <> State then
begin
PrepareEditValue(Integer(Value), AEditValue, InternalFocused);
InternalEditValue := AEditValue;
end;
end;
procedure TcxCustomCheckBox.SetStyle(Value: TcxCheckBoxStyle);
begin
FStyles.Style := Value;
end;
procedure TcxCustomCheckBox.WMLButtonUp(var Message: TWMLButtonUp);
begin
ControlState := ControlState - [csClicked];
inherited;
end;
procedure TcxCustomCheckBox.CMDialogChar(var Message: TCMDialogChar);
begin
with Message do
if IsAccel(CharCode, Caption) {D3 - bug "&&"} and CanFocus then
begin
SetFocus;
if Focused then
Toggle;
Result := 1;
end
else
inherited;
end;
procedure TcxCustomCheckBox.CMParentColorChanged(var Message: TMessage);
begin
inherited;
if ViewInfo.NativeStyle and ParentBackground then
Invalidate;
end;
{ TcxCheckBox }
class function TcxCheckBox.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxCheckBoxProperties;
end;
function TcxCheckBox.GetActiveProperties: TcxCheckBoxProperties;
begin
Result := TcxCheckBoxProperties(InternalGetActiveProperties);
end;
function TcxCheckBox.GetProperties: TcxCheckBoxProperties;
begin
Result := TcxCheckBoxProperties(FProperties);
end;
procedure TcxCheckBox.SetProperties(Value: TcxCheckBoxProperties);
begin
FProperties.Assign(Value);
end;
{ TcxFilterCheckBoxHelper }
class procedure TcxFilterCheckBoxHelper.GetFilterValue(AEdit: TcxCustomEdit;
AEditProperties: TcxCustomEditProperties; var V: Variant; var S: TCaption);
begin
with TcxComboBox(AEdit) do
begin
case ItemIndex of
-1:
V := Null;
0:
V := TcxCustomCheckBoxProperties(AEditProperties).ValueChecked;
1:
V := TcxCustomCheckBoxProperties(AEditProperties).ValueUnchecked;
end;
if ItemIndex = -1 then
S := ''
else
S := TcxCustomCheckBoxProperties(AEditProperties).GetDisplayText(V);
end;
end;
class function TcxFilterCheckBoxHelper.GetSupportedFilterOperators(
AProperties: TcxCustomEditProperties;
AValueTypeClass: TcxValueTypeClass;
AExtendedSet: Boolean = False): TcxFilterControlOperators;
begin
Result := [fcoEqual, fcoNotEqual, fcoBlanks, fcoNonBlanks];
end;
class procedure TcxFilterCheckBoxHelper.InitializeProperties(AProperties,
AEditProperties: TcxCustomEditProperties; AHasButtons: Boolean);
var
ACheckBoxProperties: TcxCustomCheckBoxProperties;
begin
ACheckBoxProperties := TcxCustomCheckBoxProperties(AEditProperties);
with TcxComboBoxProperties(AProperties).Items do
begin
Clear;
Add(ACheckBoxProperties.GetDisplayText(ACheckBoxProperties.ValueChecked));
Add(ACheckBoxProperties.GetDisplayText(ACheckBoxProperties.ValueUnchecked));
end;
TcxComboBoxProperties(AProperties).DropDownListStyle := lsFixedList;
TcxComboBoxProperties(AProperties).IDefaultValuesProvider := nil;
ClearPropertiesEvents(AProperties);
end;
class procedure TcxFilterCheckBoxHelper.SetFilterValue(AEdit: TcxCustomEdit;
AEditProperties: TcxCustomEditProperties; AValue: Variant);
const
AItemIndexMap: array [TcxCheckBoxState] of Integer = (1, 0, -1);
var
V: TcxEditValue;
begin
AEditProperties.PrepareDisplayValue(AValue, V, AEdit.Focused);
TcxComboBox(AEdit).ItemIndex := AItemIndexMap[TcxCheckBoxState((V))];
end;
class function TcxFilterCheckBoxHelper.UseDisplayValue: Boolean;
begin
Result := True;
end;
{ TcxCheckBoxActionLink }
procedure TcxCheckBoxActionLink.AssignClient(AClient: TObject);
begin
inherited AssignClient(AClient);
FClient := AClient as TcxCustomCheckBox;
end;
function TcxCheckBoxActionLink.IsCheckedLinked: Boolean;
begin
Result := inherited IsCheckedLinked and (FClient.State <> cbsGrayed) and
(FClient.Checked = TCustomAction(Action).Checked);
end;
procedure TcxCheckBoxActionLink.SetChecked(Value: Boolean);
begin
if IsCheckedLinked then
InternalSetChecked(Value);
end;
procedure TcxCheckBoxActionLink.InternalSetChecked(Value: Boolean);
begin
FClient.LockClick(True);
FClient.LockChangeEvents(True);
try
FClient.Checked := Value;
finally
FClient.LockChangeEvents(False, False);
FClient.LockClick(False);
end;
end;
initialization
GetRegisteredEditProperties.Register(TcxCheckBoxProperties, scxSEditRepositoryCheckBoxItem);
FilterEditsController.Register(TcxCheckBoxProperties, TcxFilterCheckBoxHelper);
PrepareCheckMask;
finalization
FilterEditsController.Unregister(TcxCheckBoxProperties, TcxFilterCheckBoxHelper);
FreeAndNil(FCheckMask);
end.