📄 jvxchecklistbox.pas
字号:
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvxCheckListBox.pas, released on 2003-10-19.
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 2001,2002 SGB Software
All Rights Reserved.
Contributor(s):
Polaris Software
Peter Thornqvist [peter3 at sourceforge dot net]
Andreas Hausladen (XP theming)
Changes:
2003-10-19:
* Moved TJvxCustomListBox and TJvxCheckListBox from JvxCtrls to this unit
2004-10-07:
* Changed by hofi
TJvxCheckListBox
procedure DrawCheck(R: TRect; AState: TCheckBoxState; Enabled: Boolean);
now protected to support possible call from derived classes.
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
// $Id: JvxCheckListBox.pas,v 1.42 2005/02/18 14:17:30 ahuser Exp $
unit JvxCheckListBox;
{$I jvcl.inc}
interface
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
Windows, Messages, Classes, Controls, Graphics, StdCtrls, Forms,
{$IFDEF HAS_UNIT_RTLCONSTS}
RTLConsts,
{$ENDIF HAS_UNIT_RTLCONSTS}
JvAppStorage, JvFormPlacement, JvComponent;
type
TGetItemWidthEvent = procedure(Control: TWinControl; Index: Integer;
var Width: Integer) of object;
TJvxCustomListBox = class(TJvWinControl)
private
FItems: TStrings;
FBorderStyle: TBorderStyle;
FCanvas: TControlCanvas;
FColumns: Integer;
FItemHeight: Integer;
FStyle: TListBoxStyle;
FIntegralHeight: Boolean;
FMultiSelect: Boolean;
FSorted: Boolean;
FExtendedSelect: Boolean;
FTabWidth: Integer;
FSaveItems: TStringList;
FSaveTopIndex: Integer;
FSaveItemIndex: Integer;
FAutoScroll: Boolean;
FGraySelection: Boolean;
FMaxItemWidth: Integer;
FOnDrawItem: TDrawItemEvent;
FOnMeasureItem: TMeasureItemEvent;
FOnGetItemWidth: TGetItemWidthEvent;
procedure ResetHorizontalExtent;
procedure SetHorizontalExtent;
function GetCanvas: TCanvas;
function GetAutoScroll: Boolean;
function GetItemHeight: Integer; virtual;
function GetItemIndex: Integer;
function GetSelCount: Integer;
function GetSelected(Index: Integer): Boolean;
function GetTopIndex: Integer;
procedure SetAutoScroll(Value: Boolean);
procedure SetBorderStyle(Value: TBorderStyle);
procedure SetColumnWidth;
procedure SetColumns(Value: Integer);
procedure SetExtendedSelect(Value: Boolean);
procedure SetIntegralHeight(Value: Boolean);
procedure SetItemHeight(Value: Integer);
procedure SetItemIndex(Value: Integer);
procedure SetMultiSelect(Value: Boolean);
procedure SetSelected(Index: Integer; Value: Boolean);
procedure SetSorted(Value: Boolean);
procedure SetStyle(Value: TListBoxStyle);
procedure SetTabWidth(Value: Integer);
procedure SetTopIndex(Value: Integer);
procedure SetGraySelection(Value: Boolean);
procedure SetOnDrawItem(Value: TDrawItemEvent);
procedure SetOnGetItemWidth(Value: TGetItemWidthEvent);
procedure WMPaint(var Msg: TWMPaint); message WM_PAINT;
procedure CNCommand(var Msg: TWMCommand); message CN_COMMAND;
procedure CNDrawItem(var Msg: TWMDrawItem); message CN_DRAWITEM;
procedure CNMeasureItem(var Msg: TWMMeasureItem); message CN_MEASUREITEM;
procedure WMLButtonDown(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
procedure CMCtl3DChanged(var Msg: TMessage); message CM_CTL3DCHANGED;
protected
procedure BoundsChanged; override;
procedure FocusKilled(NextWnd: HWND); override;
procedure FocusSet(PrevWnd: HWND); override;
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
procedure DestroyWnd; override;
function CreateItemList: TStrings; virtual;
function GetItemWidth(Index: Integer): Integer; virtual;
procedure WndProc(var Msg: TMessage); override;
procedure DragCanceled; override;
procedure DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState); virtual;
procedure MeasureItem(Index: Integer; var Height: Integer); virtual;
function GetItemData(Index: Integer): Longint; dynamic;
procedure SetItemData(Index: Integer; AData: Longint); dynamic;
function GetItems: TStrings; virtual;
procedure SetItems(Value: TStrings); virtual;
procedure ResetContent; dynamic;
procedure DeleteString(Index: Integer); dynamic;
property AutoScroll: Boolean read GetAutoScroll write SetAutoScroll default False;
property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
property Columns: Integer read FColumns write SetColumns default 0;
property ExtendedSelect: Boolean read FExtendedSelect write SetExtendedSelect default True;
property GraySelection: Boolean read FGraySelection write SetGraySelection default False;
property IntegralHeight: Boolean read FIntegralHeight write SetIntegralHeight default False;
property ItemHeight: Integer read GetItemHeight write SetItemHeight;
property MultiSelect: Boolean read FMultiSelect write SetMultiSelect default False;
property ParentColor default False;
property Sorted: Boolean read FSorted write SetSorted default False;
property Style: TListBoxStyle read FStyle write SetStyle default lbStandard;
property TabWidth: Integer read FTabWidth write SetTabWidth default 0;
property OnDrawItem: TDrawItemEvent read FOnDrawItem write SetOnDrawItem;
property OnMeasureItem: TMeasureItemEvent read FOnMeasureItem write FOnMeasureItem;
property OnGetItemWidth: TGetItemWidthEvent read FOnGetItemWidth write SetOnGetItemWidth;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Clear;
procedure DefaultDrawText(X, Y: Integer; const S: string);
function ItemAtPos(Pos: TPoint; Existing: Boolean): Integer;
function ItemRect(Index: Integer): TRect;
property Canvas: TCanvas read GetCanvas;
property Items: TStrings read GetItems write SetItems;
property ItemIndex: Integer read GetItemIndex write SetItemIndex;
property SelCount: Integer read GetSelCount;
property Selected[Index: Integer]: Boolean read GetSelected write SetSelected;
property TopIndex: Integer read GetTopIndex write SetTopIndex;
end;
TCheckKind = (ckCheckBoxes, ckRadioButtons, ckCheckMarks);
TChangeStateEvent = procedure(Sender: TObject; Index: Integer) of object;
TJvxCheckListBox = class(TJvxCustomListBox)
private
FAllowGrayed: Boolean;
FCheckKind: TCheckKind;
FSaveStates: TList;
FDrawBitmap: TBitmap;
FCheckWidth, FCheckHeight: Integer;
FReserved: Integer;
FInUpdateStates: Boolean;
FIniLink: TJvIniLink;
FOnClickCheck: TNotifyEvent;
FOnStateChange: TChangeStateEvent;
procedure ResetItemHeight;
function GetItemHeight: Integer; override;
procedure SetCheckKind(Value: TCheckKind);
procedure SetChecked(Index: Integer; AChecked: Boolean);
function GetChecked(Index: Integer): Boolean;
procedure SetState(Index: Integer; AState: TCheckBoxState);
function GetState(Index: Integer): TCheckBoxState;
procedure SetItemEnabled(Index: Integer; Value: Boolean);
function GetItemEnabled(Index: Integer): Boolean;
function GetAllowGrayed: Boolean;
procedure ToggleClickCheck(Index: Integer);
procedure InvalidateCheck(Index: Integer);
procedure InvalidateItem(Index: Integer);
function CreateCheckObject(Index: Integer): TObject;
function FindCheckObject(Index: Integer): TObject;
function GetCheckObject(Index: Integer): TObject;
function IsCheckObject(Index: Integer): Boolean;
procedure ReadVersion(Reader: TReader);
procedure WriteVersion(Writer: TWriter);
procedure ReadCheckData(Reader: TReader);
procedure WriteCheckData(Writer: TWriter);
function GetStorage: TJvFormPlacement;
procedure SetStorage(Value: TJvFormPlacement);
procedure IniSave(Sender: TObject);
procedure IniLoad(Sender: TObject);
procedure UpdateCheckStates;
function GetCheckedIndex: Integer;
procedure SetCheckedIndex(Value: Integer);
procedure CNDrawItem(var Msg: TWMDrawItem); message CN_DRAWITEM;
protected
procedure FontChanged; override;
function CreateItemList: TStrings; override;
procedure DrawItem(Index: Integer; Rect: TRect;
State: TOwnerDrawState); override;
procedure DefineProperties(Filer: TFiler); override;
function GetItemWidth(Index: Integer): Integer; override;
function GetItemData(Index: Integer): Longint; override;
procedure SetItemData(Index: Integer; AData: Longint); override;
procedure KeyPress(var Key: Char); override;
procedure Loaded; override;
procedure DrawCheck(R: TRect; AState: TCheckBoxState; Enabled: Boolean);
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure ResetContent; override;
procedure DeleteString(Index: Integer); override;
procedure ClickCheck; dynamic;
procedure ChangeItemState(Index: Integer); dynamic;
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
procedure DestroyWnd; override;
procedure WMDestroy(var Msg: TWMDestroy); message WM_DESTROY;
function GetCheckWidth: Integer;
procedure SetItems(Value: TStrings); override;
procedure InternalLoad(const Section: string);
procedure InternalSave(const Section: string);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure LoadFromAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
procedure SaveToAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
procedure Load;
procedure Save;
procedure ApplyState(AState: TCheckBoxState; EnabledOnly: Boolean);
property Checked[Index: Integer]: Boolean read GetChecked write SetChecked;
property State[Index: Integer]: TCheckBoxState read GetState write SetState;
property EnabledItem[Index: Integer]: Boolean read GetItemEnabled write SetItemEnabled;
published
property AllowGrayed: Boolean read GetAllowGrayed write FAllowGrayed default False;
property CheckKind: TCheckKind read FCheckKind write SetCheckKind default ckCheckBoxes;
property CheckedIndex: Integer read GetCheckedIndex write SetCheckedIndex default -1;
property IniStorage: TJvFormPlacement read GetStorage write SetStorage;
property Align;
property AutoScroll default True;
property BorderStyle;
property Color;
property Columns;
property DragCursor;
property DragMode;
property Enabled;
property ExtendedSelect;
property Font;
property GraySelection;
property Anchors;
property BiDiMode;
property Constraints;
property DragKind;
property ParentBiDiMode;
property ImeMode;
property ImeName;
property IntegralHeight;
property ItemHeight;
property Items stored False;
property MultiSelect;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Sorted;
property Style;
property TabOrder;
property TabStop default True;
property TabWidth;
property Visible;
property OnStateChange: TChangeStateEvent read FOnStateChange write FOnStateChange;
property OnClickCheck: TNotifyEvent read FOnClickCheck write FOnClickCheck;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnDrawItem;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnGetItemWidth;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMeasureItem;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
property OnContextPopup;
property OnMouseWheelDown;
property OnMouseWheelUp;
property OnEndDock;
property OnStartDock;
end;
const
clbDefaultState = cbUnchecked;
clbDefaultEnabled = True;
function CheckBitmap: TBitmap;
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$RCSfile: JvxCheckListBox.pas,v $';
Revision: '$Revision: 1.42 $';
Date: '$Date: 2005/02/18 14:17:30 $';
LogPath: 'JVCL\run'
);
{$ENDIF UNITVERSIONING}
implementation
{$IFDEF MSWINDOWS}
{$R ..\Resources\JvxCheckListBox.res}
{$ENDIF MSWINDOWS}
{$IFDEF UNIX}
{$R ../Resources/JvxCheckListBox.res}
{$ENDIF UNIX}
uses
SysUtils, Consts, Math,
JvConsts, JvJVCLUtils, JvThemes;
//=== { TJvListBoxStrings } ==================================================
type
TJvListBoxStrings = class(TStrings)
private
ListBox: TJvxCustomListBox;
protected
function Get(Index: Integer): string; override;
function GetCount: Integer; override;
function GetObject(Index: Integer): TObject; override;
procedure PutObject(Index: Integer; AObject: TObject); override;
procedure SetUpdateState(Updating: Boolean); override;
public
function Add(const S: string): Integer; override;
procedure Clear; override;
procedure Delete(Index: Integer); override;
procedure Insert(Index: Integer; const S: string); override;
end;
function TJvListBoxStrings.GetCount: Integer;
begin
Result := SendMessage(ListBox.Handle, LB_GETCOUNT, 0, 0);
end;
function TJvListBoxStrings.Get(Index: Integer): string;
var
Len: Integer;
Text: array [0..4095] of Char;
begin
Len := SendMessage(ListBox.Handle, LB_GETTEXT, Index, LPARAM(@Text));
if Len < 0 then
Error(SListIndexError, Index);
SetString(Result, Text, Len);
end;
function TJvListBoxStrings.GetObject(Index: Integer): TObject;
begin
Result := TObject(ListBox.GetItemData(Index));
if Longint(Result) = LB_ERR then
Error(SListIndexError, Index);
end;
procedure TJvListBoxStrings.PutObject(Index: Integer; AObject: TObject);
begin
ListBox.SetItemData(Index, Longint(AObject));
end;
function TJvListBoxStrings.Add(const S: string): Integer;
begin
Result := SendMessage(ListBox.Handle, LB_ADDSTRING, 0, LPARAM(PChar(S)));
if Result < 0 then
raise EOutOfResources.CreateRes(@SInsertLineError);
end;
procedure TJvListBoxStrings.Insert(Index: Integer; const S: string);
begin
if SendMessage(ListBox.Handle, LB_INSERTSTRING, Index, LPARAM(PChar(S))) < 0 then
raise EOutOfResources.CreateRes(@SInsertLineError);
end;
procedure TJvListBoxStrings.Delete(Index: Integer);
begin
ListBox.DeleteString(Index);
end;
procedure TJvListBoxStrings.Clear;
begin
ListBox.ResetContent;
end;
procedure TJvListBoxStrings.SetUpdateState(Updating: Boolean);
begin
SendMessage(ListBox.Handle, WM_SETREDRAW, Ord(not Updating), 0);
if not Updating then
ListBox.Refresh;
end;
//=== { TJvxCustomListBox } ==================================================
{ TJvxCustomListBox implementation copied from STDCTRLS.PAS and modified }
procedure ListIndexError(Index: Integer);
function ReturnAddr: Pointer;
asm
MOV EAX,[EBP+4]
end;
begin
raise EStringListError.CreateResFmt(@SListIndexError, [Index]) at ReturnAddr;
end;
constructor TJvxCustomListBox.Create(AOwner: TComponent);
const
ListBoxStyle = [csSetCaption, csDoubleClicks];
begin
inherited Create(AOwner);
if NewStyleControls then
ControlStyle := ListBoxStyle
else
ControlStyle := ListBoxStyle + [csFramed];
Width := 121;
Height := 97;
TabStop := True;
ParentColor := False;
FItems := CreateItemList;
TJvListBoxStrings(FItems).ListBox := Self;
FCanvas := TControlCanvas.Create;
FCanvas.Control := Self;
FItemHeight := 16;
FBorderStyle := bsSingle;
FExtendedSelect := True;
end;
destructor TJvxCustomListBox.Destroy;
begin
// (ahuser) moved inherited to the top otherwise it will raise an AV in csDesigning
inherited Destroy;
FCanvas.Free;
FItems.Free;
FSaveItems.Free;
end;
function TJvxCustomListBox.CreateItemList: TStrings;
begin
Result := TJvListBoxStrings.Create;
end;
function TJvxCustomListBox.GetCanvas: TCanvas;
begin
Result := FCanvas;
end;
function TJvxCustomListBox.GetItemData(Index: Integer): Longint;
begin
Result := SendMessage(Handle, LB_GETITEMDATA, Index, 0);
end;
procedure TJvxCustomListBox.SetItemData(Index: Integer; AData: Longint);
begin
SendMessage(Handle, LB_SETITEMDATA, Index, AData);
end;
procedure TJvxCustomListBox.DeleteString(Index: Integer);
begin
SendMessage(Handle, LB_DELETESTRING, Index, 0);
end;
procedure TJvxCustomListBox.SetHorizontalExtent;
begin
SendMessage(Handle, LB_SETHORIZONTALEXTENT, FMaxItemWidth, 0);
end;
function TJvxCustomListBox.GetItemWidth(Index: Integer): Integer;
var
ATabWidth: Longint;
S: string;
begin
Result := 0;
if csDestroying in ComponentState then
Exit;
if (Style <> lbStandard) and Assigned(FOnGetItemWidth) and
Assigned(FOnDrawItem) then
FOnGetItemWidth(Self, Index, Result)
else
begin
S := Items[Index] + 'x';
if TabWidth > 0 then
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -