📄 rxctrls.pas
字号:
property Flat: Boolean read FFlat write SetFlat default False;
property Font;
property Glyph: TBitmap read GetGlyph write SetGlyph;
property GrayedInactive: Boolean read FInactiveGrayed write SetInactiveGrayed
default True;
property InitPause: Word read FInitRepeatPause write FInitRepeatPause default 500;
property Layout: TButtonLayout read FLayout write SetLayout default blGlyphTop;
property Margin: Integer read FMargin write SetMargin default -1;
property MarkDropDown: Boolean read FMarkDropDown write SetMarkDropDown default True;
property ModalResult: TModalResult read FModalResult write FModalResult default 0;
property NumGlyphs: TRxNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
property ParentFont;
property ParentShowHint default False;
property RepeatInterval: Word read FRepeatPause write FRepeatPause default 100;
property ShowHint default True;
property Spacing: Integer read FSpacing write SetSpacing default 1;
property Style: TButtonStyle read FStyle write SetStyle default bsAutoDetect;
property Transparent: Boolean read FTransparent write SetTransparent default False;
property WordWrap: Boolean read GetWordWrap write SetWordWrap default False;
property Visible;
property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
{$IFDEF RX_D4}
property OnEndDock;
property OnStartDock;
{$ENDIF}
end;
{ TButtonImage }
TButtonImage = class(TObject)
private
FGlyph: TObject;
FButtonSize: TPoint;
FCaption: TCaption;
function GetNumGlyphs: TRxNumGlyphs;
procedure SetNumGlyphs(Value: TRxNumGlyphs);
function GetWordWrap: Boolean;
procedure SetWordWrap(Value: Boolean);
function GetAlignment: TAlignment;
procedure SetAlignment(Value: TAlignment);
function GetGlyph: TBitmap;
procedure SetGlyph(Value: TBitmap);
public
constructor Create;
destructor Destroy; override;
procedure Invalidate;
procedure DrawEx(Canvas: TCanvas; X, Y, Margin, Spacing: Integer;
Layout: TButtonLayout; AFont: TFont; Images: TImageList;
ImageIndex: Integer; Flags: Word);
procedure Draw(Canvas: TCanvas; X, Y, Margin, Spacing: Integer;
Layout: TButtonLayout; AFont: TFont; Flags: Word);
property Alignment: TAlignment read GetAlignment write SetAlignment;
property Caption: TCaption read FCaption write FCaption;
property Glyph: TBitmap read GetGlyph write SetGlyph;
property NumGlyphs: TRxNumGlyphs read GetNumGlyphs write SetNumGlyphs;
property ButtonSize: TPoint read FButtonSize write FButtonSize;
property WordWrap: Boolean read GetWordWrap write SetWordWrap;
end;
{ TRxButtonGlyph }
TRxButtonGlyph = class
private
FOriginal: TBitmap;
FGlyphList: TImageList;
FIndexs: array[TRxButtonState] of Integer;
FTransparentColor: TColor;
FNumGlyphs: TRxNumGlyphs;
FWordWrap: Boolean;
FAlignment: TAlignment;
FOnChange: TNotifyEvent;
procedure GlyphChanged(Sender: TObject);
procedure SetGlyph(Value: TBitmap);
procedure SetNumGlyphs(Value: TRxNumGlyphs);
function MapColor(Color: TColor): TColor;
protected
procedure MinimizeCaption(Canvas: TCanvas; const Caption: string;
Buffer: PChar; MaxLen, Width: Integer);
function CreateButtonGlyph(State: TRxButtonState): Integer;
function CreateImageGlyph(State: TRxButtonState; Images: TImageList;
Index: Integer): Integer;
procedure CalcButtonLayout(Canvas: TCanvas; const Client: TRect;
var Caption: string; Layout: TButtonLayout; Margin, Spacing: Integer;
PopupMark: Boolean; var GlyphPos: TPoint; var TextBounds: TRect;
Flags: Word; Images: TImageList; ImageIndex: Integer);
public
constructor Create;
destructor Destroy; override;
procedure Invalidate;
function DrawButtonGlyph(Canvas: TCanvas; X, Y: Integer;
State: TRxButtonState): TPoint;
function DrawButtonImage(Canvas: TCanvas; X, Y: Integer; Images: TImageList;
ImageIndex: Integer; State: TRxButtonState): TPoint;
function DrawEx(Canvas: TCanvas; const Client: TRect; const Caption: string;
Layout: TButtonLayout; Margin, Spacing: Integer; PopupMark: Boolean;
Images: TImageList; ImageIndex: Integer; State: TRxButtonState;
Flags: Word): TRect;
procedure DrawButtonText(Canvas: TCanvas; const Caption: string;
TextBounds: TRect; State: TRxButtonState; Flags: Word);
procedure DrawPopupMark(Canvas: TCanvas; X, Y: Integer;
State: TRxButtonState);
function Draw(Canvas: TCanvas; const Client: TRect; const Caption: string;
Layout: TButtonLayout; Margin, Spacing: Integer; PopupMark: Boolean;
State: TRxButtonState; Flags: Word): TRect;
property Alignment: TAlignment read FAlignment write FAlignment;
property Glyph: TBitmap read FOriginal write SetGlyph;
property NumGlyphs: TRxNumGlyphs read FNumGlyphs write SetNumGlyphs;
property WordWrap: Boolean read FWordWrap write FWordWrap;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
function DrawShadowText(DC: HDC; Str: PChar; Count: Integer; var Rect: TRect;
Format: Word; ShadowSize: Byte; ShadowColor: TColorRef;
ShadowPos: TShadowPosition): Integer;
function CheckBitmap: TBitmap;
implementation
{$R *.R32}
uses
SysUtils, Dialogs, CommCtrl,
{$IFDEF RX_D4} ImgList, ActnList, {$ENDIF}
rxVCLUtils, rxMaxMin, Consts, rxAppUtils;
const
Alignments: array [TAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER);
WordWraps: array[Boolean] of Word = (0, DT_WORDBREAK);
{ TTextListBox }
procedure TTextListBox.SetHorizontalExtent;
begin
SendMessage(Handle, LB_SETHORIZONTALEXTENT, FMaxWidth, 0);
end;
function TTextListBox.GetItemWidth(Index: Integer): Integer;
var
ATabWidth: Longint;
S: string;
begin
S := Items[Index] + 'x';
if TabWidth > 0 then begin
ATabWidth := Round((TabWidth * Canvas.TextWidth('0')) * 0.25);
Result := LoWord(GetTabbedTextExtent(Canvas.Handle, @S[1], Length(S),
1, ATabWidth));
end
else Result := Canvas.TextWidth(S);
end;
procedure TTextListBox.ResetHorizontalExtent;
var
I: Integer;
begin
FMaxWidth := 0;
for I := 0 to Items.Count - 1 do
FMaxWidth := Max(FMaxWidth, GetItemWidth(I));
SetHorizontalExtent;
end;
procedure TTextListBox.WndProc(var Message: TMessage);
begin
case Message.Msg of
LB_ADDSTRING, LB_INSERTSTRING:
begin
inherited WndProc(Message);
FMaxWidth := Max(FMaxWidth, GetItemWidth(Message.Result));
SetHorizontalExtent;
end;
LB_DELETESTRING:
begin
if GetItemWidth(Message.wParam) >= FMaxWidth then begin
Perform(WM_HSCROLL, SB_TOP, 0);
inherited WndProc(Message);
ResetHorizontalExtent;
end
else inherited WndProc(Message);
end;
LB_RESETCONTENT:
begin
FMaxWidth := 0;
SetHorizontalExtent;
Perform(WM_HSCROLL, SB_TOP, 0);
inherited WndProc(Message);
end;
WM_SETFONT:
begin
inherited WndProc(Message);
Canvas.Font.Assign(Self.Font);
ResetHorizontalExtent;
Exit;
end;
else inherited WndProc(Message);
end;
end;
{ TRxCustomListBox implementation copied from STDCTRLS.PAS and modified }
{ TRxListBoxStrings }
{.$Define RLBS_calc_hints}
//set it to free hints array if the last hint was wiped out
//to me, having an array of nil's is not too hard to novadays PC
const MaxStrArrSz = MaxInt div sizeof(PString) - 1;
type
TStringArr = array [0..MaxStrArrSz] of string;
PStringArr = ^TStringArr;
type
TRxListBoxStrings = class(TStrings)
private
ListBox: TRxCustomListBox;
FHintCapacity : integer;
FHintStrings : pstringarr;
{$IfDef RLBS_calc_hints}
FHintSetQuantity: integer;
{$EndIf}
protected
{$IFNDEF RX_D3}
procedure Error(Msg: Word; Data: Integer);
{$ENDIF}
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;
procedure InternalSetHint(Index: Integer; Hint: String);
procedure AllocHints(dropAll: boolean = false);
procedure DropHints;
procedure InsertHintCell(Index: Integer);
procedure DeleteHintCell(Index: integer);
public
function GetHint(Index: Integer): string;
procedure SetHint(Index: Integer; Hint: String);
constructor Create;
destructor Destroy; override;
procedure Assign(Source: TPersistent); 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;
{$IFNDEF RX_D3}
procedure TRxListBoxStrings.Error(Msg: Word; Data: Integer);
function ReturnAddr: Pointer;
asm
MOV EAX,[EBP+4]
end;
begin
raise EStringListError.CreateFmt('%s: %d', [LoadStr(Msg),
Data]) at ReturnAddr;
end;
{$ENDIF}
function TRxListBoxStrings.GetCount: Integer;
begin
Result := SendMessage(ListBox.Handle, LB_GETCOUNT, 0, 0);
end;
function TRxListBoxStrings.Get(Index: Integer): string;
var
Len: Integer;
Text: array[0..4095] of Char;
begin
Len := SendMessage(ListBox.Handle, LB_GETTEXT, Index,
LongInt(@Text));
if Len < 0 then Error(SListIndexError, Index);
SetString(Result, Text, Len);
end;
function TRxListBoxStrings.GetObject(Index: Integer): TObject;
begin
Result := TObject(ListBox.GetItemData(Index));
if Longint(Result) = LB_ERR then Error(SListIndexError, Index);
end;
procedure TRxListBoxStrings.PutObject(Index: Integer; AObject: TObject);
begin
ListBox.SetItemData(Index, LongInt(AObject));
end;
function TRxListBoxStrings.Add(const S: string): Integer;
begin
Result := SendMessage(ListBox.Handle, LB_ADDSTRING, 0, LongInt(PChar(S)));
if Result < 0 then raise EOutOfResources.Create(ResStr(SInsertLineError));
InsertHintCell(Result);
end;
procedure TRxListBoxStrings.Insert(Index: Integer; const S: string);
begin
if SendMessage(ListBox.Handle, LB_INSERTSTRING, Index,
Longint(PChar(S))) < 0 then
raise EOutOfResources.Create(ResStr(SInsertLineError));
InsertHintCell(Index);
end;
procedure TRxListBoxStrings.Delete(Index: Integer);
begin
ListBox.DeleteString(Index);
end;
procedure TRxListBoxStrings.Clear;
begin
ListBox.ResetContent;
DropHints;
end;
procedure TRxListBoxStrings.SetUpdateState(Updating: Boolean);
begin
SendMessage(ListBox.Handle, WM_SETREDRAW, Ord(not Updating), 0);
if not Updating then ListBox.Refresh;
end;
procedure TRxListBoxStrings.AllocHints(dropAll: boolean);
var sz: integer; i: integer; p:pstring;
begin
{$IfDef RLBS_calc_hints}
if FHintCapacity = 0 then FHintQuantity := 0;
{$Endif}
if dropAll then sz:=0 else sz:=GetCount;
if sz=FHintCapacity then exit;
if sz<FHintCapacity then
if FHintStrings <> nil then begin
p:=@FHintStrings^[sz];
for i:=sz to FHintCapacity-1 do begin
p^:=''; Inc(p); // freeing our references to ANSI strings. No use for FillChar
end;
end;
ReallocMem(FHintStrings,sz*sizeof(FHintStrings^[0]));
if sz>FHintCapacity then
FillChar(pointer(FHintStrings^[FHintCapacity]),(sz-FHintCapacity)*sizeof(FHintStrings^[0]),0);
FHintCapacity := sz;
{$IfDef RLBS_calc_hints}
if FHintCapacity = 0 then FHintQuantity := 0;
{$Endif}
end;
procedure TRxListBoxStrings.DropHints;
begin
AllocHints(true);
end;
procedure TRxListBoxStrings.DeleteHintCell(Index: integer);
begin
if FHintStrings = nil then exit;
if(Index<0) or (Index>=FhintCapacity) then exit;
InternalSetHint(Index,''); //clearing link to ANSIstring
system.Move(FHintStrings^[1+Index],FHintStrings^[Index],
(FHintCapacity-Index-1)*sizeof(FHintStrings^[0]));
Pointer(FHintStrings^[FHintCapacity-1]):=nil;
AllocHints;
end;
procedure TRxListBoxStrings.InsertHintCell(Index: Integer);
var PrevCap:integer;
begin
if FHintStrings = nil then exit; //will be alocated later on demand
PrevCap:=FHintCapacity;
{if FHintCapacity<GetCount then} AllocHints;
if Index>=PrevCap then exit; // no need in scrolling
if Index < 0 then exit;
system.Move(FHintStrings^[Index],FHintStrings^[1+Index],
(FHintCapacity-Index-1)*sizeof(FHintStrings^[0]) );
Pointer(FHintStrings^[Index]):=nil;
end;
function TRxListBoxStrings.GetHint(Index: Integer): string;
begin
Result:='';
if FHintCapacity=0 then exit;
if (Index<0) or (Index>=FHintCapacity) then Error(SListIndexError, Index);
If Assigned(FhintStrings) then Result:=FHintStrings^[Index];
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -