You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 10.2.3:如何计算TSpeedButton的精确边框宽度?

如何精确计算Delphi 10.2.3中TSpeedButton的边框宽度

在Delphi 10.2.3里要精准算出TSpeedButton的边框宽度,核心得看它的Flat和Down属性组合,这俩直接决定了控件的绘制逻辑,甚至连文本的起始像素位置都会跟着变(尤其是你提到的Margin≠-1且没设置Glyph的场景)。我给你拆解成具体场景来说:

1. 当Flat属性为False时

这是TSpeedButton的默认状态,不管Down属性是True还是False,边框宽度固定为1像素。
此时文本的起始位置是:控件ClientRect的边缘 + 1像素边框宽度 + Margin值——标准按钮的边框是凸起样式,视觉上有立体感,但实际物理宽度就是1像素。

2. 当Flat属性为True时

这种扁平化状态下,边框的显示会根据按钮的交互状态变化:

  • Down=False(未按下)、未获得焦点、鼠标未悬停:此时控件没有可见边框,边框宽度为0。文本的起始位置就是控件ClientRect的边缘 + Margin值,完全紧贴控件边缘(受Margin控制间距)。
  • Down=True(按下)、获得焦点、或鼠标悬停:这时候会显示1像素的边框,同时文本会向内偏移1像素(因为按下状态下按钮是凹陷绘制的,文本跟着位移)。此时边框宽度为1像素,文本起始位置是:控件ClientRect边缘 +1像素边框 + Margin值 +1像素偏移。

3. 精确计算的代码实现

如果要在运行时动态获取边框宽度,可以结合控件属性直接判断,或者通过绘制逻辑反推。这里给你一个实用的函数(注意MouseInControl是保护属性,外部调用需要用RTTI或者继承控件来访问,或者在事件中记录鼠标状态):

function GetSpeedButtonBorderWidth(ASpeedBtn: TSpeedButton): Integer;
var
  HasHoverOrFocus: Boolean;
begin
  if not ASpeedBtn.Flat then
    Result := 1
  else
  begin
    // 判断是否处于悬停/聚焦状态
    HasHoverOrFocus := ASpeedBtn.Down or ASpeedBtn.Focused;
    // 如果需要判断鼠标悬停,可通过继承控件暴露MouseInControl属性,或者在OnMouseMove/OnMouseLeave中记录
    // 这里暂时简化,只考虑Down和Focused
    if HasHoverOrFocus then
      Result := 1
    else
      Result := 0;
  end;
end;

要是你想更精准地验证文本位置,可以通过DrawText计算文本的绘制矩形,对比控件的ClientRect来反推边框宽度,这种方式能覆盖所有绘制细节。

内容的提问来源于stack exchange,提问作者Jens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:52:58