📄 tabs.pas
字号:
{*******************************************************}
{ }
{ Borland Delphi Visual Component Library }
{ }
{ Copyright (c) 1995-2001 Borland Software Corporation }
{ }
{*******************************************************}
{****************************************************************************}
{ }
{ Limitation on Distribution of Programs Created with this Source Code File: }
{ ========================================================================== }
{ }
{ For distribution of an application which you create with this Source }
{ Code File, your application may not be a general-purpose, interactive }
{ spreadsheet program, or a substitute for or generally competitive }
{ with Quattro Pro. }
{ }
{****************************************************************************}
{ Implements tab control }
unit Tabs;
{$T-,H+,X+}
interface
uses Windows, Classes, Graphics, Forms, Controls, Messages;
type
TScrollBtn = (sbLeft, sbRight);
TScroller = class(TCustomControl)
private
{ property usage }
FMin: Longint;
FMax: Longint;
FPosition: Longint;
FOnClick: TNotifyEvent;
FChange: Integer;
{ private usage }
Bitmap: TBitmap;
Pressed: Boolean;
Down: Boolean;
Current: TScrollBtn;
pWidth: Integer;
pHeight: Integer;
{ property access methods }
procedure SetMin(Value: Longint);
procedure SetMax(Value: Longint);
procedure SetPosition(Value: Longint);
{ private methods }
function CanScrollLeft: Boolean;
function CanScrollRight: Boolean;
procedure DoMouseDown(X: Integer);
procedure WMLButtonDown(var Message: TWMLButtonDown);
message WM_LBUTTONDOWN;
procedure WMLButtonDblClk(var Message: TWMLButtonDblClk);
message WM_LBUTTONDBLCLK;
procedure WMMouseMove(var Message: TWMMouseMove);
message WM_MOUSEMOVE;
procedure WMLButtonUp(var Message: TWMLButtonUp);
message WM_LBUTTONUP;
procedure WMSize(var Message: TWMSize);
message WM_SIZE;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Paint; override;
published
property OnClick: TNotifyEvent read FOnClick write FOnClick;
property Min: Longint read FMin write SetMin default 0;
property Max: Longint read FMax write SetMax default 0;
property Position: Longint read FPosition write SetPosition default 0;
property Change: Integer read FChange write FChange default 1;
end;
TTabSet = class;
TTabList = class(TStringList)
private
Tabs: TTabSet;
public
procedure Insert(Index: Integer; const S: string); override;
procedure Delete(Index: Integer); override;
function Add(const S: string): Integer; override;
procedure Put(Index: Integer; const S: string); override;
procedure Clear; override;
procedure AddStrings(Strings: TStrings); override;
end;
{ eash TEdgeType is made up of one or two of these parts }
TEdgePart = (epSelectedLeft, epUnselectedLeft, epSelectedRight,
epUnselectedRight);
{ represents the intersection between two tabs, or the edge of a tab }
TEdgeType = (etNone, etFirstIsSel, etFirstNotSel, etLastIsSel, etLastNotSel,
etNotSelToSel, etSelToNotSel, etNotSelToNotSel);
TTabStyle = (tsStandard, tsOwnerDraw);
TMeasureTabEvent = procedure(Sender: TObject; Index: Integer;
var TabWidth: Integer) of object;
TDrawTabEvent = procedure(Sender: TObject; TabCanvas: TCanvas; R: TRect;
Index: Integer; Selected: Boolean) of object;
TTabChangeEvent = procedure(Sender: TObject; NewTab: Integer;
var AllowChange: Boolean) of object;
TTabSet = class(TCustomControl)
private
{ property instance variables }
FStartMargin: Integer;
FEndMargin: Integer;
FTabs: TStrings;
FTabIndex: Integer;
FFirstIndex: Integer;
FVisibleTabs: Integer;
FSelectedColor: TColor;
FUnselectedColor: TColor;
FBackgroundColor: TColor;
FDitherBackground: Boolean;
FAutoScroll: Boolean;
FStyle: TTabStyle;
FOwnerDrawHeight: Integer;
FOnMeasureTab: TMeasureTabEvent;
FOnDrawTab: TDrawTabEvent;
FOnChange: TTabChangeEvent;
{ private instance variables }
ImageList: TImageList;
MemBitmap: TBitmap; { used for off-screen drawing }
BrushBitmap: TBitmap; { used for background pattern }
TabPositions: TList;
FTabHeight: Integer;
FScroller: TScroller;
FDoFix: Boolean;
FSoftTop: Boolean;
{ property access methods }
procedure SetSelectedColor(Value: TColor);
procedure SetUnselectedColor(Value: TColor);
procedure SetBackgroundColor(Value: TColor);
procedure SetDitherBackground(Value: Boolean);
procedure SetAutoScroll(Value: Boolean);
procedure SetStartMargin(Value: Integer);
procedure SetEndMargin(Value: Integer);
procedure SetTabIndex(Value: Integer);
procedure SetFirstIndex(Value: Integer);
procedure SetTabList(Value: TStrings);
// function GetTabCount: Integer;
// function GetTabName(Value: Integer): String;
// procedure SetTabName(Value: Integer; const AName: String);
procedure SetTabStyle(Value: TTabStyle);
procedure SetTabHeight(Value: Integer);
{ private methods }
procedure WMSize(var Message: TWMSize); message WM_SIZE;
procedure CMSysColorChange(var Message: TMessage); message CM_SYSCOLORCHANGE;
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure PaintEdge(X, Y, H: Integer; Edge: TEdgeType);
procedure CreateBrushPattern(Bitmap: TBitmap);
function CalcTabPositions(Start, Stop: Integer; Canvas: TCanvas;
First: Integer): Integer;
procedure CreateScroller;
procedure InitBitmaps;
procedure DoneBitmaps;
procedure CreateEdgeParts;
procedure FixTabPos;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
procedure ScrollClick(Sender: TObject);
procedure ReadIntData(Reader: TReader);
procedure ReadBoolData(Reader: TReader);
procedure SetSoftTop(const Value: Boolean);
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure Paint; override;
procedure DrawTab(TabCanvas: TCanvas; R: TRect; Index: Integer;
Selected: Boolean); virtual;
function CanChange(NewIndex: Integer): Boolean;
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
procedure MeasureTab(Index: Integer; var TabWidth: Integer); virtual;
procedure DefineProperties(Filer: TFiler); override;
property Scroller: TScroller read FScroller;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function ItemAtPos(Pos: TPoint): Integer;
function ItemRect(Item: Integer): TRect;
function ItemWidth(Index: Integer): Integer;
function MinClientRect: TRect; overload;
function MinClientRect(IncludeScroller: Boolean): TRect; overload;
function MinClientRect(TabCount: Integer; IncludeScroller: Boolean = False): TRect; overload;
procedure SelectNext(Direction: Boolean);
property Canvas;
property FirstIndex: Integer read FFirstIndex write SetFirstIndex default 0;
published
property Align;
property Anchors;
property AutoScroll: Boolean read FAutoScroll write SetAutoScroll default True;
property BackgroundColor: TColor read FBackgroundColor write SetBackgroundColor default clBtnFace;
property Constraints;
property DitherBackground: Boolean read FDitherBackground write SetDitherBackground default True;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property EndMargin: Integer read FEndMargin write SetEndMargin default 5;
property Font;
property ParentBackground default False;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property StartMargin: Integer read FStartMargin write SetStartMargin default 5;
property SelectedColor: TColor read FSelectedColor write SetSelectedColor default clBtnFace;
property SoftTop: Boolean read FSoftTop write SetSoftTop default False;
property Style: TTabStyle read FStyle write SetTabStyle default tsStandard;
property TabHeight: Integer read FOwnerDrawHeight write SetTabHeight default 20;
property Tabs: TStrings read FTabs write SetTabList;
property TabIndex: Integer read FTabIndex write SetTabIndex default -1;
property UnselectedColor: TColor read FUnselectedColor write SetUnselectedColor default clWindow;
property Visible;
property VisibleTabs: Integer read FVisibleTabs;
property OnClick;
property OnChange: TTabChangeEvent read FOnChange write FOnChange;
property OnDragDrop;
property OnDragOver;
property OnDrawTab: TDrawTabEvent read FOnDrawTab write FOnDrawTab;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnMeasureTab: TMeasureTabEvent read FOnMeasureTab write FOnMeasureTab;
property OnStartDock;
property OnStartDrag;
end;
implementation
uses Consts, SysUtils, Themes;
{$R Tabs.res}
const
EdgeWidth = 9; { This controls the angle of the tab edges }
type
TTabPos = packed record
Size, StartPos: Word;
end;
{ TScroller }
constructor TScroller.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle + [csOpaque];
Bitmap := TBitmap.Create;
pWidth := 24;
pHeight := 13;
FMin := 0;
FMax := 0;
FPosition := 0;
FChange := 1;
end;
destructor TScroller.Destroy;
begin
Bitmap.Free;
inherited Destroy;
end;
procedure TScroller.Paint;
begin
with Canvas do
begin
{ paint left button }
if CanScrollLeft then
begin
if Down and (Current = sbLeft) then
Bitmap.LoadFromResourceName(HInstance, 'SBLEFTDN')
else
Bitmap.LoadFromResourceName(HInstance, 'SBLEFT');
end else
Bitmap.LoadFromResourceName(HInstance, 'SBLEFTDIS');
Draw(0, 0, Bitmap);
{ paint right button }
if CanScrollRight then
begin
if Down and (Current = sbRight) then
Bitmap.LoadFromResourceName(HInstance, 'SBRIGHTDN')
else
Bitmap.LoadFromResourceName(HInstance, 'SBRIGHT');
end else
Bitmap.LoadFromResourceName(HInstance, 'SBRIGHTDIS');
Draw((pWidth div 2) - 1, 0, Bitmap);
end;
end;
procedure TScroller.WMSize(var Message: TWMSize);
begin
inherited;
Width := pWidth - 1;
Height := pHeight;
end;
procedure TScroller.SetMin(Value: Longint);
begin
if Value < FMax then FMin := Value;
end;
procedure TScroller.SetMax(Value: Longint);
begin
if Value > FMin then FMax := Value;
end;
procedure TScroller.SetPosition(Value: Longint);
begin
if Value <> FPosition then
begin
if Value < Min then Value := Min;
if Value > Max then Value := Max;
FPosition := Value;
Invalidate;
if Assigned(FOnClick) then
FOnClick(Self);
end;
end;
function TScroller.CanScrollLeft: Boolean;
begin
Result := Position > Min;
end;
function TScroller.CanScrollRight: Boolean;
begin
Result := Position < Max;
end;
procedure TScroller.DoMouseDown(X: Integer);
begin
if X < pWidth div 2 then Current := sbLeft
else Current := sbRight;
case Current of
sbLeft: if not CanScrollLeft then Exit;
sbRight: if not CanScrollRight then Exit;
end;
Pressed := True;
Down := True;
Invalidate;
SetCapture(Handle);
end;
procedure TScroller.WMLButtonDown(var Message: TWMLButtonDown);
begin
DoMouseDown(Message.XPos);
end;
procedure TScroller.WMLButtonDblClk(var Message: TWMLButtonDblClk);
begin
DoMouseDown(Message.XPos);
end;
procedure TScroller.WMMouseMove(var Message: TWMMouseMove);
var
P: TPoint;
R: TRect;
begin
if Pressed then
begin
P := Point(Message.XPos, Message.YPos);
R := Rect(0, 0, pWidth div 2, pHeight);
if Current = sbRight then OffsetRect(R, pWidth div 2, 0);
if PtInRect(R, P) <> Down then
begin
Down := not Down;
Invalidate;
end;
end;
end;
procedure TScroller.WMLButtonUp(var Message: TWMLButtonUp);
var
NewPos: Longint;
begin
ReleaseCapture;
Pressed := False;
if Down then
begin
Down := False;
NewPos := Position;
case Current of
sbLeft: Dec(NewPos, Change);
sbRight: Inc(NewPos, Change);
end;
Position := NewPos;
end;
end;
{ TTabList }
function TTabList.Add(const S: string): Integer;
begin
Result := inherited Add(S);
if Tabs <> nil then
Tabs.Invalidate;
end;
procedure TTabList.Insert(Index: Integer; const S: string);
begin
inherited Insert(Index, S);
if Tabs <> nil then
begin
if Index <= Tabs.FTabIndex then Inc(Tabs.FTabIndex);
Tabs.Invalidate;
end;
end;
procedure TTabList.Delete(Index: Integer);
var
OldIndex: Integer;
begin
OldIndex := Tabs.Tabindex;
inherited Delete(Index);
if OldIndex < Count then Tabs.FTabIndex := OldIndex
else Tabs.FTabIndex := Count - 1;
Tabs.Invalidate;
Tabs.Invalidate;
if OldIndex = Index then Tabs.Click; { deleted selected tab }
end;
procedure TTabList.Put(Index: Integer; const S: string);
begin
inherited Put(Index, S);
if Tabs <> nil then
Tabs.Invalidate;
end;
procedure TTabList.Clear;
begin
inherited Clear;
Tabs.FTabIndex := -1;
Tabs.Invalidate;
end;
procedure TTabList.AddStrings(Strings: TStrings);
begin
SendMessage(Tabs.Handle, WM_SETREDRAW, 0, 0);
inherited AddStrings(Strings);
SendMessage(Tabs.Handle, WM_SETREDRAW, 1, 0);
Tabs.Invalidate;
end;
{ TTabSet }
constructor TTabSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := [csCaptureMouse, csDoubleClicks, csOpaque];
Width := 185;
Height := 21;
TabPositions := TList.Create;
FTabHeight := 20;
FTabs := TTabList.Create;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -