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

如何在Delphi 10.2中实现类似Office2016的带BorderIcons的无边框窗体

实现Delphi 10.2窗体类似Office 2016外观的方案

我之前折腾过类似的需求,给你分享几个在Delphi 10.2里实现Office 2016风格窗体的靠谱方案,分标题栏自定义和阴影效果两部分来说:

一、自定义无标题栏但保留最小化/最大化/关闭按钮

方法1:自绘标题栏与按钮(无需第三方组件)

如果你不想依赖第三方样式或组件,纯自绘是最灵活的方式:

  1. 隐藏默认标题栏:
    直接设BorderStyle为bsNone会连系统按钮一起丢,更稳妥的是用API修改窗口样式,保留系统按钮但隐藏标题栏:

    procedure TMainForm.FormCreate(Sender: TObject);
    var
      WinStyle: DWORD;
    begin
      WinStyle := GetWindowLongPtr(Handle, GWL_STYLE);
      // 去掉标题栏,保留最小化、最大化、系统菜单按钮
      WinStyle := WinStyle and not WS_CAPTION or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_SYSMENU;
      SetWindowLongPtr(Handle, GWL_STYLE, WinStyle);
      // 调整客户区大小,把原来标题栏的空间利用起来
      AdjustClientRect;
    end;
    
  2. 做可拖动的自定义标题栏:
    拖个TPanel到窗体顶部,设Align=alTop,高度30左右(和Office 2016标题栏差不多)。然后重写WM_NCHITTEST消息,让这个Panel区域能拖动窗体:

    procedure TMainForm.WMNCHitTest(var Message: TWMNCHitTest);
    var
      Pt: TPoint;
    begin
      inherited;
      Pt := ScreenToClient(Point(Message.XPos, Message.YPos));
      // 判断点击位置是否在标题栏Panel内
      if (Pt.Y >= 0) and (Pt.Y <= pnlTitleBar.Height) then
        Message.Result := HTCAPTION;
    end;
    
  3. 自绘带hover效果的系统按钮:
    别用图片切换状态了,自绘按钮更流畅还没闪烁。比如继承TButton写个关闭按钮:

    type
      TOfficeCloseButton = class(TButton)
      private
        FIsHovered: Boolean;
        procedure WMMouseEnter(var Message: TMessage); message WM_MOUSEENTER;
        procedure WMMouseLeave(var Message: TMessage); message WM_MOUSELEAVE;
      protected
        procedure Paint; override;
      end;
    
    procedure TOfficeCloseButton.WMMouseEnter(var Message: TMessage);
    begin
      inherited;
      FIsHovered := True;
      Invalidate;
    end;
    
    procedure TOfficeCloseButton.WMMouseLeave(var Message: TMessage);
    begin
      inherited;
      FIsHovered := False;
      Invalidate;
    end;
    
    procedure TOfficeCloseButton.Paint;
    var
      Canvas: TCanvas;
      Rect: TRect;
    begin
      Canvas := Self.Canvas;
      Canvas.Brush.Style := bsClear;
      Canvas.Pen.Style := psClear;
    
      Rect := ClientRect;
    
      // Hover时显示Office风格的红色背景,正常用默认按钮色
      if FIsHovered then
        Canvas.Brush.Color := $FFE81123
      else
        Canvas.Brush.Color := clBtnFace;
    
      Canvas.FillRect(Rect);
    
      // 绘制白色叉号
      Canvas.Pen.Color := clWhite;
      Canvas.Pen.Width := 2;
      Canvas.MoveTo(Rect.Left + 8, Rect.Top + 8);
      Canvas.LineTo(Rect.Right - 8, Rect.Bottom - 8);
      Canvas.MoveTo(Rect.Right - 8, Rect.Top + 8);
      Canvas.LineTo(Rect.Left + 8, Rect.Bottom - 8);
    end;
    

    最大化、最小化按钮同理,换成对应的图标(横线、方框)就行,hover状态也可以用类似的逻辑改背景色。

方法2:用VCL Styles快速搞定

Delphi 10.2自带VCL Styles支持,找个适配Office 2016的样式文件(.vsf)导入项目,然后:

  • 把窗体Caption设为空,调整ClientHeight去掉默认标题栏的空间。
  • 样式自带的系统按钮已经做好了hover状态,不用自己写任何绘制代码,效果还很贴合Office风格,省事儿得很。

二、实现Office 2016风格的窗体阴影

Office 2016的阴影是系统级的柔和阴影,用Windows的DWM API就能实现:

  1. 先检查DWM是否可用:
    毕竟Win7以下系统不支持DWM,加个判断:

    function IsDWMEnabled: Boolean;
    var
        Enabled: BOOL;
    begin
        Result := DwmIsCompositionEnabled(Enabled) = S_OK and Enabled;
    end;
    
  2. 启用阴影效果:
    在窗体OnCreate事件里调用API:

    procedure TMainForm.FormCreate(Sender: TObject);
    var
        DWMAttribute: DWORD;
        ExStyle: DWORD;
    begin
        if IsDWMEnabled then
        begin
            // 开启DWM渲染
            DWMAttribute := 1;
            DwmSetWindowAttribute(Handle, DWMA_NCRENDERING_ENABLED, @DWMAttribute, SizeOf(DWMAttribute));
            // 设置主窗口类型的阴影,和Office风格一致
            DWMAttribute := DWMSBT_MAINWINDOW;
            DwmSetWindowAttribute(Handle, DWMA_SHADOW, @DWMAttribute, SizeOf(DWMAttribute));
        end;
    
        // 如果是bsNone样式,加个WS_EX_WINDOWEDGE扩展样式,不然阴影可能不显示
        ExStyle := GetWindowLongPtr(Handle, GWL_EXSTYLE);
        ExStyle := ExStyle or WS_EX_WINDOWEDGE;
        SetWindowLongPtr(Handle, GWL_EXSTYLE, ExStyle);
    end;
    
  3. 小提示:

    • 阴影会自动适配系统主题,和Office 2016的阴影效果一致。
    • 如果是高DPI环境,记得开启Delphi的PerMonitorV2 DPI感知,避免阴影位置偏移。

额外注意

  • 自绘按钮时记得把DoubleBuffered设为True,能有效避免闪烁。
  • 测试时多切换系统主题,确保样式在不同主题下都正常显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:08:38