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

自定义标题栏拖动时,如何触发Windows 11窗口停靠提示?

自定义标题栏实现Windows 11窗口停靠界面的解决方案

问题描述

我在开发的应用中实现了自定义标题栏,并为标题栏创建了双击和鼠标按下的自定义事件,代码如下:

procedure TAdvCustomForm.TitleBarDblClick( Sender : TObject );
begin
  if( WindowState <> TWindowState.wsMaximized ) then
  begin
    Winapi.Windows.ReleaseCapture();
    Perform( wm_SysCommand, SC_MAXIMIZE, 0 );
    SizeGrip.Visible := False;
  end
  else
  begin
    Winapi.Windows.ReleaseCapture();
    Perform( wm_SysCommand, SC_RESTORE, 0 );
    SizeGrip.Visible := True;
  end;
end;

procedure TAdvCustomForm.TitleBarMouseDown( Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer );
const
  SC_DRAG = $F012; //stumbled on by accident
begin
  if( Button = TMouseButton.mbLeft ) then
  begin
    self.DoubleBuffered := True;
    Winapi.Windows.ReleaseCapture();
    Perform( wm_SysCommand, SC_DRAG, 0 );
    self.DoubleBuffered := False;
  end;
end;

目前无法找到拖动窗口时显示Windows 11窗口停靠界面的方法,请问应如何修改鼠标按下事件来实现该功能?

解决方案

原代码中使用的SC_DRAG($F012)是一种非原生的窗口拖动实现,不会触发Windows 11的Snap Layouts(窗口停靠界面)。要实现原生的拖动及停靠功能,需要将拖动逻辑替换为系统原生的标题栏消息处理:

修改后的TitleBarMouseDown事件代码如下:

procedure TAdvCustomForm.TitleBarMouseDown( Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer );
begin
  if( Button = TMouseButton.mbLeft ) then
  begin
    ReleaseCapture();
    // 发送WM_NCLBUTTONDOWN消息,指定HTCAPTION表示点击标题栏区域
    SendMessage( Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0 );
  end;
end;

关键说明

  • 移除了DoubleBuffered的临时设置,原生拖动逻辑不需要此操作
  • 使用WM_NCLBUTTONDOWN配合HTCAPTION参数,让系统认为是在原生标题栏上按下鼠标,从而触发包括窗口拖动、停靠在内的所有系统级交互
  • 保留ReleaseCapture()确保鼠标捕获状态正确传递给系统

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 05:30:47