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

如何使Panel始终定位在窗体镂空区域的正上方?

实现镂空区域上方的模拟标题栏Panel

嘿,这个需求其实很好实现,核心就是精准计算Panel的位置和尺寸,让它刚好卡在镂空区域的正上方,和镂空区域同宽。我来给你一步步拆解具体做法:

核心思路

要让Panel完美对齐镂空区域正上方,我们需要基于你定义镂空区域的X1、Y1、X2、Y2这四个参数来计算Panel的属性:

  • 宽度:直接和镂空区域保持一致,也就是 X2 - X1
  • 水平位置:和镂空区域左边界对齐,所以Left = X1
  • 垂直位置:在镂空区域的正上方,所以Top = Y1 - Panel的固定高度(因为镂空区域的顶部是Y1,往上挪一个Panel高度就是它的位置)

具体代码实现

首先假设你的Panel控件名叫PanelTitle,并且已经在设计时设置好了固定Height(比如25)。我们可以写一个专门的方法来更新它的位置和尺寸:

procedure TForm1.UpdateTitlePanelPosition;
var
  PanelWidth: Integer;
begin
  // 计算Panel宽度,和镂空区域完全一致
  PanelWidth := X2 - X1;
  PanelTitle.Width := PanelWidth;
  
  // 设置位置:水平对齐镂空左边界,垂直在镂空正上方
  PanelTitle.Left := X1;
  PanelTitle.Top := Y1 - PanelTitle.Height;
  
  // 确保Panel在最顶层,避免被其他控件遮挡
  PanelTitle.BringToFront;
end;

然后把这个方法和你现有的镂空创建代码结合,在生成镂空后立即调用:

var FormRegion, HoleRegion: HRGN;
begin
  FormRegion := CreateRectRgn(0, 0, Form1.Width, Form1.Height);
  HoleRegion := CreateRectRgn(X1, Y1, X2, Y2);
  CombineRgn(FormRegion, FormRegion, HoleRegion, RGN_DIFF);
  SetWindowRgn(Form1.Handle, FormRegion, True);
  
  // 同步更新标题Panel的位置
  UpdateTitlePanelPosition;
end;

额外优化(可选)

如果要让这个模拟标题栏更真实,还可以加上窗口拖动功能——用户点击Panel拖动时,整个Form跟着移动。只需要给Panel添加OnMouseDown事件:

procedure TForm1.PanelTitleMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    ReleaseCapture;
    Perform(WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
  end;
end;

注意事项

  • 如果你的X1、X2、Y1、Y2是动态变化的(比如用户通过鼠标拖动重新定义镂空区域),每次这些参数改变后都要调用UpdateTitlePanelPosition
  • 如果Form允许调整大小,记得在OnResize事件里重新计算镂空区域的位置,再同步更新Panel的位置(确保镂空区域和Panel始终保持对应关系)
  • 确认Panel的Parent属性是Form,这样它的坐标才是相对于Form的正确位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 18:07:27