📄 tflattabcontrolunit.pas
字号:
end;
procedure TFlatTabControl.SetTabs (Value: TStrings);
var
counter: Integer;
begin
FTabs.Assign(Value);
if FTabs.Count = 0 then // no tabs? then active tab = 0
FActiveTab := 0
else
begin
if (FTabs.Count - 1) < FActiveTab then // if activeTab > last-tab the activeTab = last-tab
FActiveTab := FTabs.Count - 1;
for counter := 0 to FTabs.Count - 1 do
FTabs[counter] := Trim(FTabs[counter]); // delete all spaces at left and right
end;
SetTabRect;
Invalidate;
end;
procedure TFlatTabControl.SetTabHeight (Value: Integer);
begin
if Value < 0 then Value := 0; // TabHeigh can't negative
FTabHeight := Value;
SetTabRect;
Invalidate;
end;
procedure TFlatTabControl.SetTabSpacing (Value: Integer);
begin
if Value < 1 then Value := 1; // minimal tabspacing = 1 dot
FTabSpacing := Value;
SetTabRect;
Invalidate;
end;
procedure TFlatTabControl.SetTabRect;
var
TabCount: Integer;
TabRect: ^TRect;
position: TPoint;
CaptionTextWidth: Integer;
CaptionTextString: string;
begin
// set the font and clear the tab-rect-list
canvas.font := self.font;
FTabsRect.Clear;
// set left/top position for the the first tab
case FTabPosition of
tpTop:
position := Point(ClientRect.left, ClientRect.top);
tpBottom:
position := Point(ClientRect.left, ClientRect.bottom - FTabHeight);
end;
for TabCount := 0 to (FTabs.Count - 1) do
begin
New(TabRect); // create a new Tab-Rect
if Pos('&', FTabs[TabCount]) <> 0 then // if & in an caption
begin
CaptionTextString := FTabs[TabCount]; // read the caption text
Delete(CaptionTextString, Pos('&', FTabs[TabCount]), 1); // delete the &
CaptionTextWidth := canvas.TextWidth(CaptionTextString); // calc the caption-width withou the &
end
else // else calc the caption-width
CaptionTextWidth := canvas.TextWidth(FTabs[TabCount]);
case FTabPosition of // set the rect
tpTop:
TabRect^ := Rect(position.x, position.y, position.x + CaptionTextWidth + 20, FTabHeight);
tpBottom:
TabRect^ := Rect(position.x, position.y, position.x + CaptionTextWidth + 20, position.y + FTabHeight);
end;
position := Point(position.x + CaptionTextWidth + 20 + FTabSpacing, position.y); // set left/top position for next rect
FTabsRect.Add(TabRect); // add the tab-rect to the tab-rect-list
end;
end;
procedure TFlatTabControl.CMDialogChar (var Message: TCMDialogChar);
var
currentTab: Integer;
begin
with Message do
begin
if FTabs.Count > 0 then
begin
for currentTab := 0 to FTabs.Count - 1 do
begin
if IsAccel(CharCode, FTabs[currentTab]) then
begin
if (FActiveTab <> currentTab) then
begin
SetActiveTab(currentTab);
SetFocus;
end;
Result := 1;
break;
end;
end;
end
else
inherited;
end;
end;
procedure TFlatTabControl.Paint;
var
abc: TBitmap;
TabCount: Integer;
TempRect: ^TRect;
begin
abc := TBitmap.Create; // create memory-bitmap to draw flicker-free
try
abc.Height := ClientRect.Bottom;
abc.Width := ClientRect.Right;
abc.Canvas.Font := Self.Font;
// Clear Background
abc.canvas.Brush.Color := TForm(Parent).Color;
abc.canvas.FillRect(ClientRect);
// Draw Border
if FTabs.Count = 0 then
begin
abc.canvas.Brush.Color := FBorderColor;
abc.canvas.FrameRect(ClientRect)
end
else
begin
abc.canvas.Pen.Color := FBorderColor;
TempRect := FTabsRect.Items[FActiveTab];
if ClientRect.left <> TempRect^.left then // if Active Tab not first tab then __|Tab|___
begin
case FTabPosition of
tpTop:
begin
abc.Canvas.Polyline([Point(ClientRect.left, ClientRect.top + FTabHeight), Point(TempRect^.Left, ClientRect.top + FTabHeight)]);
abc.Canvas.Polyline([Point(TempRect^.Right-1, ClientRect.top + FTabHeight), Point(ClientRect.right, ClientRect.top + FTabHeight)]);
end;
tpBottom:
begin
abc.Canvas.Polyline([Point(ClientRect.left, ClientRect.bottom - FTabHeight - 1), Point(TempRect^.Left, ClientRect.bottom - FTabHeight - 1)]);
abc.Canvas.Polyline([Point(TempRect^.Right-1, ClientRect.bottom - FTabHeight - 1), Point(ClientRect.right, ClientRect.bottom - FTabHeight - 1)]);
end;
end;
end
else // else |Tab|___
case FTabPosition of
tpTop:
abc.Canvas.Polyline([Point(TempRect^.Right-1, ClientRect.top + FTabHeight), Point(ClientRect.right, ClientRect.top + FTabHeight)]);
tpBottom:
abc.Canvas.Polyline([Point(TempRect^.Right-1, ClientRect.bottom - FTabHeight - 1), Point(ClientRect.right, ClientRect.bottom - FTabHeight - 1)]);
end;
// border of the control
case FTabPosition of
tpTop:
abc.Canvas.Polyline([Point(ClientRect.left, ClientRect.top + FTabHeight), Point(ClientRect.left, ClientRect.bottom - 1), Point(ClientRect.right - 1, ClientRect.bottom - 1), Point(ClientRect.right - 1, ClientRect.top + FTabHeight)]);
tpBottom:
abc.Canvas.Polyline([Point(ClientRect.left, ClientRect.bottom - FTabHeight - 1), Point(ClientRect.left, ClientRect.top), Point(ClientRect.right - 1, ClientRect.top), Point(ClientRect.right - 1, ClientRect.bottom - FTabHeight - 1)]);
end;
end;
case FTabPosition of
tpTop:
begin
abc.canvas.brush.color := Color;
abc.Canvas.FillRect(Rect(ClientRect.left + 1, ClientRect.top + FTabHeight + 1, ClientRect.right - 1, ClientRect.bottom - 1));
end;
tpBottom:
begin
abc.canvas.brush.color := Color;
abc.Canvas.FillRect(Rect(ClientRect.left + 1, ClientRect.top + 1, ClientRect.right - 1, ClientRect.bottom - FTabHeight - 1));
end;
end;
// Draw Tabs
for TabCount := 0 to FTabs.Count - 1 do
begin
TempRect := FTabsRect.Items[TabCount];
abc.canvas.brush.style := bsclear;
abc.canvas.pen.color := clBlack;
if TabCount = FActiveTab then // if Active Tab not first tab then draw border |^^^|
begin
abc.canvas.font.color := self.font.color;
abc.canvas.brush.color := Color;
abc.canvas.pen.color := FBorderColor;
case FTabPosition of
tpTop:
begin
abc.Canvas.FillRect(Rect(TempRect^.left, TempRect^.top, TempRect^.right - 1, TempRect^.bottom + 1));
abc.Canvas.Polyline([Point(TempRect^.Left, TempRect^.Bottom), Point(TempRect^.Left, TempRect^.Top), Point(TempRect^.Right-1, TempRect^.Top), Point(TempRect^.Right-1, TempRect^.Bottom)]);
end;
tpBottom:
begin
abc.Canvas.FillRect(Rect(TempRect^.left, TempRect^.top - 1, TempRect^.right - 1, TempRect^.bottom));
abc.Canvas.Polyline([Point(TempRect^.Left, TempRect^.top - 1), Point(TempRect^.Left, TempRect^.bottom - 1), Point(TempRect^.Right-1, TempRect^.bottom - 1), Point(TempRect^.Right-1, TempRect^.top - 1)]);
end;
end;
end
else // else only fill the tab
begin
abc.canvas.font.color := color;
abc.canvas.brush.color := FUnselectedColor;
abc.Canvas.FillRect(TempRect^);
end;
if (TabCount = FActiveTab) and not Enabled then
begin
abc.Canvas.Font.Color := FUnselectedColor;
DrawText(abc.canvas.Handle, PChar(FTabs[TabCount]), Length(FTabs[TabCount]), TempRect^, DT_CENTER or DT_VCENTER or DT_SINGLELINE)
end
else
DrawText(abc.canvas.Handle, PChar(FTabs[TabCount]), Length(FTabs[TabCount]), TempRect^, DT_CENTER or DT_VCENTER or DT_SINGLELINE);
end;
canvas.CopyRect(ClientRect, abc.canvas, ClientRect); // Copy bitmap to screen
finally
abc.free; // delete the bitmap
end;
end;
procedure TFlatTabControl.MouseDown (Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
cursorPos: TPoint;
currentTab: Integer;
currentRect: ^TRect;
begin
GetCursorPos(cursorPos);
cursorPos := ScreenToClient(cursorPos);
if FTabs.Count > 0 then
begin
for currentTab := 0 to FTabs.Count - 1 do
begin
currentRect := FTabsRect.Items[currentTab];
if PtInRect(currentRect^, cursorPos) then
if (FActiveTab <> currentTab) then // only change when new tab selected
begin
SetActiveTab(currentTab);
SetFocus;
end;
end;
end;
inherited;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -