📄 mmbutton.pas
字号:
{========================================================================}
{= (c) 1995-98 SwiftSoft Ronald Dittrich =}
{========================================================================}
{= All Rights Reserved =}
{========================================================================}
{= D 01099 Dresden = Tel.: +0351-8012255 =}
{= Loewenstr.7a = info@swiftsoft.de =}
{========================================================================}
{= Actual versions on http://www.swiftsoft.de/mmtools.html =}
{========================================================================}
{= This code is for reference purposes only and may not be copied or =}
{= distributed in any format electronic or otherwise except one copy =}
{= for backup purposes. =}
{= =}
{= No Delphi Component Kit or Component individually or in a collection=}
{= subclassed or otherwise from the code in this unit, or associated =}
{= .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed =}
{= without express permission from SwiftSoft. =}
{= =}
{= For more licence informations please refer to the associated =}
{= HelpFile. =}
{========================================================================}
{= $Date: 20.01.1998 - 18:00:00 $ =}
{========================================================================}
unit MMButton;
{$C PRELOAD}
{$I COMPILER.INC}
interface
uses
{$IFDEF WIN32}
Windows,
{$ELSE}
WinTypes,
WinProcs,
{$ENDIF}
Messages,
Classes,
Controls,
Forms,
Graphics,
StdCtrls,
ExtCtrls,
Buttons,
MMObj,
MMUtils;
type
TMMSpeedButton = class(TMMGraphicControl)
private
FGroupIndex: Integer;
FGlyph : Pointer;
FDown : Boolean;
FAllowAllUp: Boolean;
FLayout : TButtonLayout;
FSpacing : Integer;
FMargin : Integer;
FBevel : TBevelStyle;
FPattern : TBitmap;
FDownColor : TColor;
FBevelColor: TColor;
procedure CreateBrushPattern;
procedure GlyphChanged(Sender: TObject);
procedure UpdateExclusive;
function GetGlyph: TBitmap;
procedure SetGlyph(Value: TBitmap);
function GetNumGlyphs: TNumGlyphs;
procedure SetNumGlyphs(Value: TNumGlyphs);
procedure SetDown(Value: Boolean);
procedure SetAllowAllUp(Value: Boolean);
procedure SetGroupIndex(Value: Integer);
procedure SetLayout(Value: TButtonLayout);
procedure SetSpacing(Value: Integer);
procedure SetMargin(Value: Integer);
procedure SetBevel(Value: TBevelStyle);
procedure SetDownColor(Value: TColor);
procedure SetBevelColor(Value: TColor);
procedure WMLButtonDblClk(var Message: TWMLButtonDown); message WM_LBUTTONDBLCLK;
procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
procedure CMButtonPressed(var Message: TMessage); message CM_BUTTONPRESSED;
{$IFDEF WIN32}
procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW;
{$ENDIF}
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
procedure CMSysColorChange(var Message: TMessage); message CM_SYSCOLORCHANGE;
function DrawButtonFace(Canvas: TCanvas; const Client: TRect;
BevelStyle: TBevelStyle; IsDown: Boolean): TRect;
protected
FState: TButtonState;
FDragging: Boolean;
function GetPalette: HPALETTE; override;
procedure Paint; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure DrawGlyph(Canvas: TCanvas; const Client: TRect);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Click; override;
published
property OnClick;
property OnDblClick;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property AllowAllUp: Boolean read FAllowAllUp write SetAllowAllUp default False;
property GroupIndex: Integer read FGroupIndex write SetGroupIndex default 0;
{ Ensure group index is declared before Down }
property Down: Boolean read FDown write SetDown default False;
property Caption;
property Enabled;
property Font;
property Glyph: TBitmap read GetGlyph write SetGlyph;
property Layout: TButtonLayout read FLayout write SetLayout default blGlyphLeft;
property Margin: Integer read FMargin write SetMargin default -1;
property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
property ParentFont;
property ParentShowHint;
property ShowHint;
property Spacing: Integer read FSpacing write SetSpacing default 4;
property Visible;
property Bevel: TBevelStyle read FBevel write SetBevel default bsRaised;
property DownColor: TColor read FDownColor write SetDownColor default clWhite;
property BevelColor: TColor read FBevelColor write SetBevelColor default clBlack;
end;
implementation
uses Consts, SysUtils, MMString;
{$IFNDEF WIN32}
{ TBitPool }
const
BitsPerInt = SizeOf(Integer) * 8;
type
TBitEnum = 0..BitsPerInt - 1;
TBitSet = set of TBitEnum;
TBitPool = class
private
FSize: Integer;
FBits: Pointer;
procedure SetSize(Value: Integer);
procedure SetBit(Index: Integer; Value: Boolean);
function GetBit(Index: Integer): Boolean;
public
destructor Destroy; override;
function OpenBit: Integer;
property Bits[Index: Integer]: Boolean read GetBit write SetBit; default;
property Size: Integer read FSize write SetSize;
end;
{$ELSE}
type
TBitPool = class(TBits);
{$ENDIF}
type
TGlyphList = class(TImageList)
private
Used: TBitPool;
FCount: Integer;
function AllocateIndex: Integer;
public
constructor Create(AWidth, AHeight: Integer);
destructor Destroy; override;
function Add(Image, Mask: TBitmap): Integer;
function AddMasked(Image: TBitmap; MaskColor: TColor): Integer;
procedure Delete(Index: Integer);
property Count: Integer read FCount;
end;
TGlyphCache = class
private
GlyphLists: TList;
public
constructor Create;
destructor Destroy; override;
function GetList(AWidth, AHeight: Integer): TGlyphList;
procedure ReturnList(List: TGlyphList);
function Empty: Boolean;
end;
TButtonGlyph = class
private
FOriginal: TBitmap;
FGlyphList: TGlyphList;
FIndexs: array[TButtonState] of Integer;
FTransparentColor: TColor;
FNumGlyphs: TNumGlyphs;
FOnChange: TNotifyEvent;
procedure GlyphChanged(Sender: TObject);
procedure SetGlyph(Value: TBitmap);
procedure SetNumGlyphs(Value: TNumGlyphs);
procedure Invalidate;
function CreateButtonGlyph(State: TButtonState): Integer;
procedure DrawButtonGlyph(Canvas: TCanvas; X, Y: Integer;
State: TButtonState);
procedure DrawButtonText(Canvas: TCanvas; const Caption: string;
TextBounds: TRect; State: TButtonState);
procedure CalcButtonLayout(Canvas: TCanvas; const Client: TRect;
const Caption: string; Layout: TButtonLayout; Margin, Spacing: Integer;
var GlyphPos: TPoint; var TextBounds: TRect);
public
constructor Create;
destructor Destroy; override;
{ return the text rectangle }
function Draw(Canvas: TCanvas; const Client: TRect;
const Caption: string; Layout: TButtonLayout;
Margin, Spacing: Integer; State: TButtonState): TRect;
property Glyph: TBitmap read FOriginal write SetGlyph;
property NumGlyphs: TNumGlyphs read FNumGlyphs write SetNumGlyphs;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
{$IFNDEF WIN32}
type
PBitArray = ^TBitArray;
TBitArray = array[0..4096] of TBitSet;
destructor TBitPool.Destroy;
begin
SetSize(0);
inherited Destroy;
end;
procedure TBitPool.SetSize(Value: Integer);
var
NewMem: Pointer;
NewMemSize: Integer;
OldMemSize: Integer;
function Min(X, Y: Integer): Integer;
begin
Result := X;
if X > Y then Result := Y;
end;
begin
if Value <> Size then
begin
NewMemSize := ((Value + BitsPerInt - 1) div BitsPerInt) * SizeOf(Integer);
OldMemSize := ((Size + BitsPerInt - 1) div BitsPerInt) * SizeOf(Integer);
if NewMemSize <> OldMemSize then
begin
NewMem := nil;
if NewMemSize <> 0 then
begin
GetMem(NewMem, NewMemSize);
FillChar(NewMem^, NewMemSize, 0);
end
else NewMem := nil;
if OldMemSize <> 0 then
begin
if NewMem <> nil then
Move(FBits^, NewMem^, Min(OldMemSize, NewMemSize));
FreeMem(FBits, OldMemSize);
end;
FBits := NewMem;
end;
FSize := Value;
end;
end;
procedure TBitPool.SetBit(Index: Integer; Value: Boolean);
begin
if Value then
Include(PBitArray(FBits)^[Index div BitsPerInt], Index mod BitsPerInt)
else
Exclude(PBitArray(FBits)^[Index div BitsPerInt], Index mod BitsPerInt);
end;
function TBitPool.GetBit(Index: Integer): Boolean;
begin
Result := Index mod BitsPerInt in PBitArray(FBits)^[Index div BitsPerInt];
end;
function TBitPool.OpenBit: Integer;
var
I: Integer;
B: TBitSet;
J: TBitEnum;
E: Integer;
begin
E := (Size + BitsPerInt - 1) div BitsPerInt - 1;
for I := 0 to E do
if PBitArray(FBits)^[I] <> [0..BitsPerInt - 1] then
begin
B := PBitArray(FBits)^[I];
for J := Low(J) to High(J) do
begin
if not (J in B) then
begin
Result := I * BitsPerInt + J;
if Result >= Size then Result := Size;
Exit;
end;
end;
end;
Result := Size;
end;
{$ENDIF}
{ TGlyphList }
constructor TGlyphList.Create(AWidth, AHeight: Integer);
begin
{$IFDEF WIN32}
inherited CreateSize(AWidth, AHeight);
{$ELSE}
inherited Create(AWidth, AHeight);
{$ENDIF}
Used := TBitPool.Create;
end;
destructor TGlyphList.Destroy;
begin
Used.Free;
inherited Destroy;
end;
function TGlyphList.AllocateIndex: Integer;
begin
Result := Used.OpenBit;
if Result >= Used.Size then
begin
Result := inherited Add(nil, nil);
Used.Size := Result + 1;
end;
Used[Result] := True;
end;
function TGlyphList.Add(Image, Mask: TBitmap): Integer;
begin
Result := AllocateIndex;
Replace(Result, Image, Mask);
Inc(FCount);
end;
function TGlyphList.AddMasked(Image: TBitmap; MaskColor: TColor): Integer;
begin
Result := AllocateIndex;
ReplaceMasked(Result, Image, MaskColor);
Inc(FCount);
end;
procedure TGlyphList.Delete(Index: Integer);
begin
if Used[Index] then
begin
Dec(FCount);
Used[Index] := False;
end;
end;
{ TGlyphCache }
constructor TGlyphCache.Create;
begin
inherited Create;
GlyphLists := TList.Create;
end;
destructor TGlyphCache.Destroy;
begin
GlyphLists.Free;
inherited Destroy;
end;
function TGlyphCache.GetList(AWidth, AHeight: Integer): TGlyphList;
var
I: Integer;
begin
for I := GlyphLists.Count - 1 downto 0 do
begin
Result := GlyphLists[I];
with Result do
if (AWidth = Width) and (AHeight = Height) then Exit;
end;
Result := TGlyphList.Create(AWidth, AHeight);
GlyphLists.Add(Result);
end;
procedure TGlyphCache.ReturnList(List: TGlyphList);
begin
if List = nil then Exit;
if List.Count = 0 then
begin
GlyphLists.Remove(List);
List.Free;
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -