📄 tabs.pas
字号:
H := FTabHeight - 1;
TempList := TImageList.CreateSize(EdgeWidth, FTabHeight); {exceptions}
except
FTabHeight := SaveHeight;
raise;
end;
ImageList.Free;
ImageList := TempList;
Working := TBitmap.Create;
try
Working.Width := EdgeWidth;
Working.Height := FTabHeight;
MaskColor := clOlive;
for EdgePart := Low(TEdgePart) to High(TEdgePart) do
begin
with Working.Canvas do
begin
Brush.Color := MaskColor;
Brush.Style := bsSolid;
FillRect(Rect(0, 0, EdgeWidth, FTabHeight));
end;
case EdgePart of
epSelectedLeft: DrawSL(Working.Canvas);
epUnselectedLeft: DrawUL(Working.Canvas);
epSelectedRight: DrawSR(Working.Canvas);
epUnselectedRight: DrawUR(Working.Canvas);
end;
ImageList.AddMasked(Working, MaskColor);
end;
finally
Working.Free;
end;
end;
procedure TTabSet.PaintEdge(X, Y, H: Integer; Edge: TEdgeType);
begin
MemBitmap.Canvas.Brush.Color := clWhite;
MemBitmap.Canvas.Font.Color := clBlack;
case Edge of
etFirstIsSel:
ImageList.Draw(MemBitmap.Canvas, X, Y, Ord(epSelectedLeft));
etLastIsSel:
ImageList.Draw(MemBitmap.Canvas, X, Y, Ord(epSelectedRight));
etFirstNotSel:
ImageList.Draw(MemBitmap.Canvas, X, Y, Ord(epUnselectedLeft));
etLastNotSel:
ImageList.Draw(MemBitmap.Canvas, X, Y, Ord(epUnselectedRight));
etNotSelToSel:
begin
ImageList.Draw(MemBitmap.Canvas, X, Y, Ord(epUnselectedRight));
ImageList.Draw(MemBitmap.Canvas, X, Y, Ord(epSelectedLeft));
end;
etSelToNotSel:
begin
ImageList.Draw(MemBitmap.Canvas, X, Y, Ord(epUnselectedLeft));
ImageList.Draw(MemBitmap.Canvas, X, Y, Ord(epSelectedRight));
end;
etNotSelToNotSel:
begin
ImageList.Draw(MemBitmap.Canvas, X, Y, Ord(epUnselectedLeft));
ImageList.Draw(MemBitmap.Canvas, X, Y, Ord(epUnselectedRight));
end;
end;
end;
procedure TTabSet.CreateBrushPattern(Bitmap: TBitmap);
var
X, Y: Integer;
begin
Bitmap.Width := 8;
Bitmap.Height := 8;
with Bitmap.Canvas do
begin
Brush.Style := bsSolid;
Brush.Color := FBackgroundColor;
FillRect(Rect(0, 0, Width, Height));
if FDitherBackground then
for Y := 0 to 7 do
for X := 0 to 7 do
if (Y mod 2) = (X mod 2) then { toggles between even/odd pixles }
Pixels[X, Y] := clWhite; { on even/odd rows }
end;
end;
procedure TTabSet.FixTabPos;
var
FLastVisibleTab: Integer;
function GetRightSide: Integer;
begin
Result := Width - EndMargin;
if AutoScroll and (FVisibleTabs < Tabs.Count - 1) then
Dec(Result, Scroller.Width + 4);
end;
function ReverseCalcNumTabs(Start, Stop: Integer; Canvas: TCanvas;
Last: Integer): Integer;
var
W: Integer;
begin
if HandleAllocated then
begin
Result := Last;
while (Start >= Stop) and (Result >= 0) do
with Canvas do
begin
W := TextWidth(Tabs[Result]);
if (FStyle = tsOwnerDraw) then
MeasureTab(Result, W);
Dec(Start, W + EdgeWidth); { next usable position }
if Start >= Stop then Dec(Result);
end;
if (Start < Stop) or (Result < 0) then Inc(Result);
end else Result := FFirstIndex;
end;
begin
if Tabs.Count > 0 then
begin
FLastVisibleTab := FFirstIndex + FVisibleTabs - 1;
if FTabIndex > FLastVisibleTab then
FFirstIndex := ReverseCalcNumTabs(GetRightSide, StartMargin + EdgeWidth,
Canvas, FTabIndex)
else if (FTabIndex >= 0) and (FTabIndex < FFirstIndex) then
FFirstIndex := FTabIndex;
end;
end;
procedure TTabSet.SetSelectedColor(Value: TColor);
begin
if Value <> FSelectedColor then
begin
FSelectedColor := Value;
CreateEdgeParts;
Invalidate;
end;
end;
procedure TTabSet.SetUnselectedColor(Value: TColor);
begin
if Value <> FUnselectedColor then
begin
FUnselectedColor := Value;
CreateEdgeParts;
Invalidate;
end;
end;
procedure TTabSet.SetBackgroundColor(Value: TColor);
begin
if Value <> FBackgroundColor then
begin
FBackgroundColor := Value;
CreateBrushPattern(BrushBitmap);
MemBitmap.Canvas.Brush.Style := bsSolid;
Invalidate;
end;
end;
procedure TTabSet.SetDitherBackground(Value: Boolean);
begin
if Value <> FDitherBackground then
begin
FDitherBackground := Value;
CreateBrushPattern(BrushBitmap);
MemBitmap.Canvas.Brush.Style := bsSolid;
Invalidate;
end;
end;
procedure TTabSet.SetAutoScroll(Value: Boolean);
begin
if Value <> FAutoScroll then
begin
FAutoScroll := Value;
Scroller.Visible := False;
ShowWindow(Scroller.Handle, SW_HIDE);
Invalidate;
end;
end;
procedure TTabSet.SetStartMargin(Value: Integer);
begin
if Value <> FStartMargin then
begin
FStartMargin := Value;
Invalidate;
end;
end;
procedure TTabSet.SetEndMargin(Value: Integer);
begin
if Value <> FEndMargin then
begin
FEndMargin := Value;
Invalidate;
end;
end;
function TTabSet.CanChange(NewIndex: Integer): Boolean;
begin
Result := True;
if Assigned(FOnChange) then
FOnChange(Self, NewIndex, Result);
end;
procedure TTabSet.SetTabIndex(Value: Integer);
begin
if Value <> FTabIndex then
begin
if (Value < -1) or (Value >= Tabs.Count) then
raise Exception.CreateRes(@SInvalidTabIndex);
if CanChange(Value) then
begin
FTabIndex := Value;
FixTabPos;
Click;
Invalidate;
end;
end;
end;
procedure TTabSet.SelectNext(Direction: Boolean);
var
NewIndex: Integer;
begin
if Tabs.Count > 1 then
begin
NewIndex := TabIndex;
if Direction then
Inc(NewIndex)
else Dec(NewIndex);
if NewIndex = Tabs.Count then
NewIndex := 0
else if NewIndex < 0 then
NewIndex := Tabs.Count - 1;
SetTabIndex(NewIndex);
end;
end;
procedure TTabSet.SetFirstIndex(Value: Integer);
begin
if (Value >= 0) and (Value < Tabs.Count) then
begin
FFirstIndex := Value;
Invalidate;
end;
end;
procedure TTabSet.SetTabList(Value: TStrings);
begin
FTabs.Assign(Value);
FTabIndex := -1;
if FTabs.Count > 0 then TabIndex := 0
else Invalidate;
end;
{function TTabSet.GetTabCount: Integer;
begin
Result := FTabs.Count;
end;
function TTabSet.GetTabName(Value: Integer): String;
begin
if (Value >= 0) and (Value < Tabs.Count) then Result := Tabs[Value]
else Result := '';
end;
procedure TTabSet.SetTabName(Value: Integer; const AName: String);
begin
if (Value >= 0) and (Value < Tabs.Count) and (GetTabName(Value) <> AName) then
Tabs[Value] := AName;
end;}
procedure TTabSet.SetTabStyle(Value: TTabStyle);
begin
if Value <> FStyle then
begin
FStyle := Value;
CreateEdgeParts;
Invalidate;
end;
end;
procedure TTabSet.SetTabHeight(Value: Integer);
var
SaveHeight: Integer;
begin
if Value <> FOwnerDrawHeight then
begin
SaveHeight := FOwnerDrawHeight;
try
FOwnerDrawHeight := Value;
CreateEdgeParts;
Invalidate;
except
FOwnerDrawHeight := SaveHeight;
raise;
end;
end;
end;
procedure TTabSet.DrawTab(TabCanvas: TCanvas; R: TRect; Index: Integer;
Selected: Boolean);
begin
if Assigned(FOnDrawTab) then
FOnDrawTab(Self, TabCanvas, R, Index, Selected);
end;
procedure TTabSet.GetChildren(Proc: TGetChildProc; Root: TComponent);
begin
end;
procedure TTabSet.MeasureTab(Index: Integer; var TabWidth: Integer);
begin
if Assigned(FOnMeasureTab) then
FOnMeasureTab(Self, Index, TabWidth);
end;
procedure TTabSet.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
TabPos: TTabPos;
I: Integer;
Extra: Integer;
MinLeft: Integer;
MaxRight: Integer;
begin
inherited MouseDown(Button, Shift, X, Y);
if (Button = mbLeft) and (Y <= FTabHeight) then
begin
if Y < FTabHeight div 2 then Extra := EdgeWidth div 3
else Extra := EdgeWidth div 2;
for I := 0 to TabPositions.Count - 1 do
begin
Pointer(TabPos) := TabPositions[I];
MinLeft := TabPos.StartPos - Extra;
MaxRight := TabPos.StartPos + TabPos.Size + Extra;
if (X >= MinLeft) and (X <= MaxRight) then
begin
SetTabIndex(FirstIndex + I);
Break;
end;
end;
end;
end;
procedure TTabSet.WMSize(var Message: TWMSize);
var
NumVisTabs, LastTabPos: Integer;
function CalcNumTabs(Start, Stop: Integer; Canvas: TCanvas;
First: Integer): Integer;
begin
Result := First;
while (Start < Stop) and (Result < Tabs.Count) do
with Canvas do
begin
Inc(Start, ItemWidth(Result) + EdgeWidth); { next usable position }
if Start <= Stop then Inc(Result);
end;
end;
begin
inherited;
if Tabs.Count > 1 then
begin
LastTabPos := Width - EndMargin;
NumVisTabs := CalcNumTabs(StartMargin + EdgeWidth, LastTabPos, Canvas, 0);
if (FTabIndex = Tabs.Count) or (NumVisTabs > FVisibleTabs) or
(NumVisTabs = Tabs.Count) then FirstIndex := Tabs.Count - NumVisTabs;
FDoFix := True;
end;
Invalidate;
end;
procedure TTabSet.CMSysColorChange(var Message: TMessage);
begin
inherited;
CreateEdgeParts;
CreateBrushPattern(BrushBitmap);
MemBitmap.Canvas.Brush.Style := bsSolid;
{ Windows follows this message with a WM_PAINT }
end;
procedure TTabSet.CMFontChanged(var Message: TMessage);
begin
inherited;
Canvas.Font := Font;
CreateEdgeParts;
Invalidate;
end;
procedure TTabSet.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
Message.Result := DLGC_WANTALLKEYS;
end;
procedure TTabSet.CMDialogChar(var Message: TCMDialogChar);
var
I: Integer;
begin
for I := 0 to FTabs.Count - 1 do
begin
if IsAccel(Message.CharCode, FTabs[I]) then
begin
Message.Result := 1;
if FTabIndex <> I then
SetTabIndex(I);
Exit;
end;
end;
inherited;
end;
procedure TTabSet.DefineProperties(Filer: TFiler);
begin
{ Can be removed after version 1.0 }
if Filer is TReader then inherited DefineProperties(Filer);
Filer.DefineProperty('TabOrder', ReadIntData, nil, False);
Filer.DefineProperty('TabStop', ReadBoolData, nil, False);
end;
procedure TTabSet.ReadIntData(Reader: TReader);
begin
Reader.ReadInteger;
end;
procedure TTabSet.ReadBoolData(Reader: TReader);
begin
Reader.ReadBoolean;
end;
function TTabSet.MinClientRect: TRect;
begin
Result := MinClientRect(Tabs.Count, False);
end;
function TTabSet.MinClientRect(IncludeScroller: Boolean): TRect;
begin
Result := MinClientRect(Tabs.Count, IncludeScroller);
end;
function TTabSet.MinClientRect(TabCount: Integer; IncludeScroller: Boolean): TRect;
var
I: Integer;
begin
Result := Rect(0, 0, StartMargin, FTabHeight + 5);
for I := 0 to TabCount - 1 do
Inc(Result.Right, ItemWidth(I) + EdgeWidth);
Inc(Result.Right, EndMargin);
if IncludeScroller then
Inc(Result.Right, Scroller.Width + 4);
end;
function TTabSet.ItemWidth(Index: Integer): Integer;
begin
with Canvas do
Result := TextWidth(Tabs[Index]);
if (FStyle = tsOwnerDraw) then
MeasureTab(Index, Result);
end;
procedure TTabSet.SetSoftTop(const Value: Boolean);
begin
if Value <> SoftTop then
begin
FSoftTop := Value;
CreateEdgeParts;
Invalidate;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -