Delphi 11.2下FMX应用macOS窗体边框(非客户区)自定义问题
FMX macOS自定义窗体工具栏实现方案
核心结论
FMX的windowborderstyle元素仅在Windows平台生效,macOS平台原生不支持通过StyleBook直接自定义窗体标题栏/工具栏。但可以通过以下两种方案实现类似效果:
方案1:隐藏原生标题栏,完全自定义工具栏
基础设置
- 将窗体的
TitleBar属性设为False,隐藏系统原生标题栏。 - 在窗体顶部添加
TToolBar控件,根据需求添加按钮(最小化、最大化、关闭)、标题文本等元素。
- 将窗体的
补充窗口行为逻辑
- 实现窗体拖拽移动:在Toolbar的
OnMouseDown和OnMouseMove事件中添加代码:procedure TMainForm.ToolBarMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin if Button = mbLeft then ReleaseCapture; end; procedure TMainForm.ToolBarMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); begin if ssLeft in Shift then Perform(WM_NCLBUTTONDOWN, HTCAPTION, 0); end; - 实现窗口缩放/关闭:通过调用
WindowState属性或Close方法实现对应功能,macOS下需注意全屏模式的适配(可通过WindowState := wsFullScreen切换)。
- 实现窗体拖拽移动:在Toolbar的
方案2:通过Cocoa API修改原生标题栏样式
利用FMX与macOS原生NSWindow的交互,修改标题栏为透明并延伸内容区域,再叠加自定义控件:
调用原生API配置窗口
uses Macapi.AppKit, Macapi.Foundation, FMX.Platform.Mac; procedure TMainForm.FormCreate(Sender: TObject); var LNSWindow: NSWindow; begin LNSWindow := WindowHandleToPlatform(Self.Handle).Wnd; // 开启标题栏透明和全屏内容视图模式 LNSWindow.setTitlebarAppearsTransparent(True); LNSWindow.setStyleMask(LNSWindow.styleMask or NSFullSizeContentViewWindowMask); // 移除内容区域与标题栏的间距,让自定义控件能覆盖标题栏 LNSWindow.setContentBorderThickness(0, NSMinYEdge); end;添加自定义控件
在窗体顶部添加TToolBar或其他容器控件,调整位置覆盖原标题栏区域,设置与整体UI匹配的样式即可。
关于官方样式与系统应用的说明
- Embarcadero的Polar Dark样式在macOS未修改标题栏,是因为FMX的
windowborderstyle仅针对Windows平台的窗口边框做了样式封装,macOS的标题栏由系统NSWindow控制,不在该样式元素的覆盖范围内。 - macOS系统偏好设置属于原生Cocoa应用,直接使用了Apple提供的NSWindow自定义标题栏API,而非跨平台框架的封装能力,这也是它能实现自定义样式的原因。
内容的提问来源于stack exchange,提问作者bas
相关产品推荐
相关产品推荐

