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

使用DWM_WINDOW_CORNER_PREFERENCE后,Delphi工具窗口高度异常问题

Win11下调用SetRoundedCorners后工具提示窗口高度翻倍的问题解决

问题背景

我在Delphi中开发了一个无标题、无边框的小型工具提示窗口,FormCreate中的初始设置如下:

SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
BorderIcons := BorderIcons - [biMaximize];

原本通过CreateRoundRectRgn实现圆角,但边缘不够平滑;改用Win11原生的SetRoundedCorners辅助函数后,窗口高度变为原来的两倍且呈方形,需要排查问题成因并修复。

问题成因

  1. 窗口样式与DWM渲染冲突:Win11的DWM圆角API依赖标准窗口的非客户区渲染逻辑,而无边框(bsNone)+WS_EX_TOOLWINDOW的组合会导致DWM错误计算窗口尺寸——系统默认会为标准窗口预留非客户区空间,无边框窗口无此区域,调用圆角API时会误将客户区高度叠加非客户区高度,造成窗口高度翻倍。
  2. 调用时机过早:在FormCreate中调用SetRoundedCorners时,窗口尚未完成初始化,尺寸、样式等属性未完全确定,DWM无法正确识别窗口边界,引发渲染异常。
  3. 自定义区域干扰:残留的CreateRoundRectRgn+SetWindowRgn代码会覆盖DWM的圆角处理逻辑,同时自定义区域会干扰DWM对窗口尺寸的判断。

解决方案

步骤1:清理冲突代码

移除原有的自定义圆角区域代码:

// 删除以下两行代码
RRShape := CreateRoundRectRgn(1, 1, Width - 1, height - 1, 100, 100);
SetWindowRgn(Handle,RRShape,True);

步骤2:调整窗口样式与DWM渲染设置

在FormCreate中补充正确的窗口样式,并启用DWM非客户区渲染:

procedure TForm1.FormCreate(Sender: TObject);
var
  NCRenderingPolicy: DWORD;
begin
  // 给当前工具窗口设置扩展样式(而非Application主窗口)
  SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
  // 移除最大化按钮
  BorderIcons := BorderIcons - [biMaximize];
  // 设置无边框样式
  BorderStyle := bsNone;
  // 启用DWM非客户区渲染,确保圆角功能生效
  NCRenderingPolicy := DWMNCRP_ENABLED;
  DwmSetWindowAttribute(Handle, DWMWA_NCRENDERING_POLICY, @NCRenderingPolicy, SizeOf(NCRenderingPolicy));
end;

步骤3:延迟调用SetRoundedCorners

将圆角设置代码移到FormShow事件中,确保窗口完全初始化后再应用圆角:

procedure TForm1.FormShow(Sender: TObject);
begin
  SetRoundedCorners(Self.Handle, RoundedCornerSmall);
end;

额外注意事项

  • 确保Delphi版本支持Dwmapi单元(RAD Studio 10.3及以上版本通常自带),若版本较低需手动引入Dwmapi.dll的函数声明。
  • Win11的原生圆角效果仅对顶层窗口生效,且需确保系统设置中未关闭圆角功能(设置>个性化>窗口>圆角)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 23:10:10