是否可以控制选项卡在JvDockServer组件中的显示方式?

Al *_*l C 3 delphi tabs jedi

如果在JVCL的JvDocking示例代码中运行AdvanceDemo,并选择了VSNetStyle,则可以将第二个表单拖到主表单上; 将显示带有第二个表单标题的选项卡.如果然后将另一个表单拖到主表单的同一侧,则将创建另一个选项卡.两个标签将重叠:

重叠标签的屏幕截图

有没有办法控制这两个标签重叠多少?我希望标签足够分开,以便用户可以阅读两个标签上的文字.

谢谢,一如既往 - Al C.

NGL*_*GLN 5

正如ain评论的那样,我也认为这是一个错误.更确切地说,TJvDockVSChannel.Paint中的一个错误是绘制标签(内部标签称为).这样的块有一个受保护的属性InactiveBlockWidth,其名称建议控制其宽度.该属性适用于选项卡本身,但标题在TJvDockVSChannel.Paint中再次移动相同的数量,这在我看来是问题.

您可以通过分配DockServer的OnFinishSetDockPanelSize事件来进行如下实验:

type
  TJvDockVSBlockAccess = class(TJvDockVSBlock);

procedure TMainForm.lbDockServer1FinishSetDockPanelSize(
  DockPanel: TJvDockPanel);
var
  Channel: TJvDockVSChannel;
  Block: TJvDockVSBlockAccess;
  i: Integer;
begin
  if DockPanel is TJvDockVSNETPanel then
  begin
    Channel := TJvDockVSNETPanel(DockPanel).VSChannel;
    for i := 0 to Channel.BlockCount - 1 do
    begin
      Block := TJvDockVSBlockAccess(Channel.Block[i]);
      Block.InactiveBlockWidth := 100;
    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

由于这是目前受保护的属性,因此可能表明其功能正在构建中.我想Jedi的开发团队现在决定只绘制每个非活动选项卡的字形,因为缺少动态处理选项卡宽度的完整实现.例如,您应该能够设置每个选项卡的最小宽度,并且当条形(即它所在的容器)更改高度时,所有选项卡应相应地加宽或缩小.

编辑:

由于灵活的设计,您可以通过设置DockServer的DockPanelClass属性来解决该问题.我想必须设置属性befóre设置Style属性.它涉及重写整个Paint例程,因为InactiveBlockWidth也用在GetBlockRect中,而GetBlockRect又不是虚拟的:

type
  TJvDockVSBlockAccess = class(TJvDockVSBlock);

  THackJvDockVSNETPanel = class(TJvDockVSNETPanel)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  THackJvDockVSChannel = class(TJvDockVSChannel)
  protected
    procedure Paint; override;
    procedure ResetBlock; override;
    procedure Resize; override;
  end;

const
  InactiveTabWidth = 100;

{ TMainForm }

procedure TMainForm.FormCreate(Sender: TObject);
begin
  ...
  JvDockVSNetStyle1.DockPanelClass := THackJvDockVSNETPanel;
end;

{ THackJvDockVSNETPanel }

constructor THackJvDockVSNETPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  VSChannelClass := THackJvDockVSChannel;
end;

{ THackJvDockVSChannel }

procedure THackJvDockVSChannel.Paint;
var
  I: Integer;

  procedure DrawSingleBlock(Block: TJvDockVSBlockAccess);
  var
    DrawRect: TRect;
    I: Integer;
    OldGraphicsMode: Integer;
    VisiblePaneCount: Integer;

    procedure AdjustImagePos;
    begin
      if Align = alLeft then
      begin
        Inc(DrawRect.Left, 3);
        Inc(DrawRect.Top, 4);
      end
      else if Align = alTop then
      begin
        Inc(DrawRect.Left, 4);
        Inc(DrawRect.Top, 2);
      end
      else if Align = alRight then
      begin
        Inc(DrawRect.Left, 4);
        Inc(DrawRect.Top, 4);
      end
      else if Align = alBottom then
      begin
        Inc(DrawRect.Left, 4);
        Inc(DrawRect.Top, 3);
      end;
    end;

  begin
    VisiblePaneCount := 0;
    for I := 0 to Block.VSPaneCount - 1 do
    begin
      if not Block.VSPane[I].Visible then
        Continue;
      GetBlockRect(Block, I, DrawRect);
      Canvas.Brush.Color := TabColor;
      Canvas.FillRect(DrawRect);
      Canvas.Brush.Color := clGray;
      Canvas.FrameRect(DrawRect);
      AdjustImagePos;
      Block.ImageList.Draw(Canvas, DrawRect.Left, DrawRect.Top, I);
      if Align in [alTop, alBottom] then
        Inc(DrawRect.Left, 24)
      else if Align in [alLeft, alRight] then
      begin
        Inc(DrawRect.Top, 24);
        if Align = alLeft then
          DrawRect.Left := 15
        else
          DrawRect.Left := 20;
        DrawRect.Right := DrawRect.Left + (DrawRect.Bottom - DrawRect.Top);
      end;
      Canvas.Brush.Color := TabColor;
      Canvas.Pen.Color := clBlack;
      Dec(DrawRect.Right, 3);
      OldGraphicsMode := SetGraphicsMode(Canvas.Handle, GM_ADVANCED);
      Canvas.Brush.Style := bsClear;
      DrawText(Canvas.Handle, PChar(Block.VSPane[I].DockForm.Caption), -1,
        DrawRect, DT_END_ELLIPSIS or DT_NOCLIP);
      SetGraphicsMode(Canvas.Handle, OldGraphicsMode);
      Inc(VisiblePaneCount);
    end;
    if VisiblePaneCount > 0 then
      CurrentPos := CurrentPos + BlockInterval;
  end;

begin
  ResetBlock;
  CurrentPos := BlockStartOffset;
  for I := 0 to BlockCount - 1 do
    DrawSingleBlock(TJvDockVSBlockAccess(Block[I]));
end;

procedure THackJvDockVSChannel.ResetBlock;
var
  I: Integer;
begin
  inherited ResetBlock;
  for I := 0 to BlockCount - 1 do
    TJvDockVSBlockAccess(Block[I]).InactiveBlockWidth := InactiveTabWidth;
end;

procedure THackJvDockVSChannel.Resize;
begin
  { Here you could widen or narrow the tabs according the total space and
    depending on the number of tabs }
  inherited Resize;
end;
Run Code Online (Sandbox Code Playgroud)

加宽标签的示例