📄 rxctrls.pas
字号:
{$ENDIF}
{$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;
{$IFDEF WIN32}
procedure DrawEx(Canvas: TCanvas; X, Y, Margin, Spacing: Integer;
Layout: TButtonLayout; AFont: TFont; Images: TImageList;
ImageIndex: Integer; Flags: Word);
{$ENDIF}
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;
{$IFDEF WIN32}
function CreateImageGlyph(State: TRxButtonState; Images: TImageList;
Index: Integer): Integer;
{$ENDIF}
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 {$IFDEF WIN32}; Images: TImageList; ImageIndex: Integer
{$ENDIF});
public
constructor Create;
destructor Destroy; override;
procedure Invalidate;
function DrawButtonGlyph(Canvas: TCanvas; X, Y: Integer;
State: TRxButtonState): TPoint;
{$IFDEF WIN32}
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;
{$ENDIF}
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
{$IFDEF WIN32}
{$R *.R32}
{$ELSE}
{$R *.R16}
{$ENDIF}
uses SysUtils, Dialogs, {$IFDEF WIN32} CommCtrl, {$ELSE} Str16, {$ENDIF}
VCLUtils, MaxMin, Consts, AppUtils {$IFDEF RX_D4}, ImgList,
ActnList {$ENDIF};
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;
{$IFNDEF WIN32}
procedure TTextListBox.SetTabWidth(Value: Integer);
begin
if Value < 0 then Value := 0;
if FTabWidth <> Value then begin
FTabWidth := Value;
RecreateWnd;
end;
end;
procedure TTextListBox.CreateParams(var Params: TCreateParams);
const
TabStops: array[Boolean] of Longword = (0, LBS_USETABSTOPS);
begin
inherited CreateParams(Params);
Params.Style := Params.Style or TabStops[FTabWidth <> 0];
end;
procedure TTextListBox.CreateWnd;
begin
inherited CreateWnd;
if FTabWidth <> 0 then
SendMessage(Handle, LB_SETTABSTOPS, 1, Longint(@FTabWidth));
end;
{$ENDIF}
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 }
type
TRxListBoxStrings = class(TStrings)
private
ListBox: TRxCustomListBox;
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;
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);
{$IFDEF WIN32}
function ReturnAddr: Pointer;
asm
MOV EAX,[EBP+4]
end;
{$ELSE}
function ReturnAddr: Pointer; assembler;
asm
MOV AX,[BP].Word[2]
MOV DX,[BP].Word[4]
end;
{$ENDIF}
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;
{$IFDEF WIN32}
Text: array[0..4095] of Char;
{$ENDIF}
begin
Len := SendMessage(ListBox.Handle, LB_GETTEXT, Index,
{$IFDEF WIN32} LongInt(@Text) {$ELSE} LongInt(@Result) {$ENDIF});
if Len < 0 then Error(SListIndexError, Index);
{$IFDEF WIN32}
SetString(Result, Text, Len);
{$ELSE}
System.Move(Result[0], Result[1], Len);
Result[0] := Char(Len);
{$ENDIF}
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;
{$IFNDEF WIN32}
var
Text: array[0..255] of Char;
{$ENDIF}
begin
{$IFDEF WIN32}
Result := SendMessage(ListBox.Handle, LB_ADDSTRING, 0, LongInt(PChar(S)));
{$ELSE}
Result := SendMessage(ListBox.Handle, LB_ADDSTRING, 0, LongInt(StrPCopy(Text, S)));
{$ENDIF}
if Result < 0 then raise EOutOfResources.Create(ResStr(SInsertLineError));
end;
procedure TRxListBoxStrings.Insert(Index: Integer; const S: string);
{$IFNDEF WIN32}
var
Text: array[0..255] of Char;
{$ENDIF}
begin
if SendMessage(ListBox.Handle, LB_INSERTSTRING, Index,
{$IFDEF WIN32}
Longint(PChar(S))) < 0 then
{$ELSE}
Longint(StrPCopy(Text, S))) < 0 then
{$ENDIF}
raise EOutOfResources.Create(ResStr(SInsertLineError));
end;
procedure TRxListBoxStrings.Delete(Index: Integer);
begin
ListBox.DeleteString(Index);
end;
procedure TRxListBoxStrings.Clear;
begin
ListBox.ResetContent;
end;
procedure TRxListBoxStrings.SetUpdateState(Updating: Boolean);
begin
SendMessage(ListBox.Handle, WM_SETREDRAW, Ord(not Updating), 0);
if not Updating then ListBox.Refresh;
end;
{ TRxCustomListBox }
procedure ListIndexError(Index: Integer);
{$IFDEF WIN32}
function ReturnAddr: Pointer;
asm
MOV EAX,[EBP+4]
end;
{$ELSE}
function ReturnAddr: Pointer; assembler;
asm
MOV AX,[BP].Word[2]
MOV DX,[BP].Word[4]
end;
{$ENDIF}
begin
{$IFDEF RX_D3}
raise EStringListError.CreateFmt(SListIndexError, [Index]) at ReturnAddr;
{$ELSE}
raise EStringListError.CreateFmt('%s: %d', [LoadStr(SListIndexError),
Index]) at ReturnAddr;
{$ENDIF}
end;
constructor TRxCustomListBox.Create(AOwner: TComponent);
const
ListBoxStyle = [csSetCaption, csDoubleClicks];
begin
inherited Create(AOwner);
{$IFDEF WIN32}
if NewStyleControls then ControlStyle := ListBoxStyle
else ControlStyle := ListBoxStyle + [csFramed];
{$ELSE}
ControlStyle := ListBoxStyle + [csFramed];
{$ENDIF}
Width := 121;
Height := 97;
TabStop := True;
ParentColor := False;
FItems := CreateItemList;
TRxListBoxStrings(FItems).ListBox := Self;
FCanvas := TControlCanvas.Create;
TControlCanvas(FCanvas).Control := Self;
FItemHeight := 16;
FBorderStyle := bsSingle;
FExtendedSelect := True;
end;
destructor TRxCustomListBox.Destroy;
begin
inherited Destroy;
FCanvas.Free;
FItems.Free;
FSaveItems.Free;
end;
function TRxCustomListBox.CreateItemList: TStrings;
begin
Result := TRxListBoxStrings.Create;
end;
function TRxCustomListBox.GetItemData(Index: Integer): LongInt;
begin
Result := SendMessage(Handle, LB_GETITEMDATA, Index, 0);
end;
procedure TRxCustomListBox.SetItemData(Index: Integer; AData: LongInt);
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -