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

Delphi中如何检测触摸屏按钮长按事件以控制电机运行?

解决Delphi触摸屏按钮长按触发右键的问题

方法一:自定义触摸感知按钮

通过重写按钮的WndProc处理Windows原生触摸消息(WM_TOUCH),将触摸事件转换为标准的OnMouseDown/OnMouseUp事件,和鼠标操作逻辑统一:

  1. 创建一个继承自TButton的自定义控件,注册触摸窗口并处理WM_TOUCH消息,代码示例如下:
unit TouchButton;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, StdCtrls;

type
  TTouchButton = class(TButton)
  private
    procedure WMTouch(var Message: TMessage); message WM_TOUCH;
  protected
    procedure WndProc(var Message: TMessage); override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

implementation

const
  WM_TOUCH = $0240;
  TOUCHEVENTF_DOWN = $0001;
  TOUCHEVENTF_UP = $0002;

type
  TOUCHINPUT = record
    x: Longint;
    y: Longint;
    hSource: THandle;
    dwID: DWORD;
    dwFlags: DWORD;
    dwMask: DWORD;
    dwTime: DWORD;
    dwExtraInfo: Pointer;
    cxContact: DWORD;
    cyContact: DWORD;
  end;

constructor TTouchButton.Create(AOwner: TComponent);
begin
  inherited;
  RegisterTouchWindow(Handle, 0);
end;

procedure TTouchButton.WndProc(var Message: TMessage);
begin
  inherited;
  if Message.Msg = WM_TOUCH then
    WMTouch(Message);
end;

procedure TTouchButton.WMTouch(var Message: TMessage);
var
  InputCount: Integer;
  Inputs: array of TOUCHINPUT;
  Pt: TPoint;
begin
  InputCount := Message.WParam;
  SetLength(Inputs, InputCount);
  try
    if GetTouchInputInfo(Message.LParam, InputCount, @Inputs[0], SizeOf(TOUCHINPUT)) then
    begin
      Pt.x := Inputs[0].x div 100;
      Pt.y := Inputs[0].y div 100;
      Pt := ScreenToClient(Pt);

      if (Inputs[0].dwFlags and TOUCHEVENTF_DOWN) <> 0 then
        MouseDown(mbLeft, 0, Pt.x, Pt.y)
      else if (Inputs[0].dwFlags and TOUCHEVENTF_UP) <> 0 then
        MouseUp(mbLeft, 0, Pt.x, Pt.y);

      CloseTouchInputHandle(Message.LParam);
      Message.Result := 0;
    end;
  finally
    SetLength(Inputs, 0);
  end;
end;

end.
  1. 将窗体上的TButton替换为这个TTouchButton,原有的OnMouseDown/OnMouseUp事件逻辑无需修改,触摸操作会自动触发对应事件。

方法二:阻止右键菜单弹出

触摸屏长按触发右键的核心是系统会弹出上下文菜单,通过拦截按钮的OnContextPopup事件,阻止菜单弹出即可保留长按的按下状态:

procedure TForm1.Button1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
begin
  Handled := True; // 标记事件已处理,阻止右键菜单弹出
end;

这个方法简单直接,但仅适用于系统将触摸长按识别为右键的场景,若触摸事件未正确触发MouseDown,仍需结合方法一使用。

方法三:利用Delphi触摸手势组件(适用于新版本)

在Delphi XE2及以上版本,可使用TTouchGestureManager组件:

  • 将TTouchGestureManager添加到窗体
  • 选中按钮,在Object Inspector的GestureManager属性中关联该组件
  • 禁用系统默认的长按右键手势,或自定义手势事件逻辑

不过此方法依赖Delphi版本,且配置相对繁琐,推荐优先使用前两种方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 06:45:33