Note
RegisterTouchWindow
must be called on every window that will be used for touch input. This means that if you have an application that has multiple windows within it,RegisterTouchWindow
must be called on every window in that application that uses touch features. Also, an application can callRegisterTouchWindow
any number of times for the same window if it desires to change the modifier flags. A window can be marked as no longer requiring touch input using theUnregisterTouchWindow
function.
You would also have to subclass each Panel to handle the WM_TOUCH
message for each panel, since it will be sent directly to each registered Panel and not to the Form.
If you want every Panel on the Form to be touch-capable, a simple interposer class will suffice:
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
type
// 继承于panel 当然也可以是 form
TPanel = class(Vcl.ExtCtrls.TPanel)
protected
procedure CreateWnd; override; // 关键覆盖这两个方法
procedure DestroyWnd; override; //
procedure WMTouch(var Message: TMessage); message WM_TOUCH; // 接收touch事件
end;
TForm1 = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
Panel3: TPanel;
end;
var
Form1: TForm1;
implementation
type
TOUCHINPUT = record
x: Integer;
y: Integer;
hSource: THandle;
dwID: DWORD;
dwFlags: DWORD;
dwMask: DWORD;
dwTime: DWORD;
dwExtraInfo: ULONG_PTR;
cxContact: DWORD;
cyContact: DWORD;
end;
procedure TPanel.CreateWnd;
begin
inherited;
RegisterTouchWindow(Handle, 0);
end;
procedure TPanel.DestroyWnd;
begin
UnregisterTouchWindow(Handle);
inherited;
end;
procedure TPanel.WMTouch(var Message: TMessage);
function TouchPointToPoint(const TouchPoint: TTouchInput): TPoint;
begin
Result := Point(TouchPoint.X div 100, TouchPoint.Y div 100);
PhysicalToLogicalPoint(Handle, Result);
end;
var
TouchInputs: array of TTouchInput;
TouchInput: TTouchInput;
Handled: Boolean;
Point: TPoint;
begin
Handled := False;
SetLength(TouchInputs, Message.WParam);
GetTouchInputInfo(Message.LParam, Message.WParam,
@TouchInputs[0], SizeOf(TTouchInput));
try
for TouchInput in TouchInputs do
begin
Point := TouchPointToPoint(TouchInput);
if PtInRect(BoundsRect, Point) then
begin
//labelX.Caption := 'Touch ID: ' + IntToStr(TouchInput.dwID);
Top := Point.Y - 100;
end;
Handled := True;
end;
finally
if Handled then
CloseTouchInputHandle(Message.LParam)
else
inherited;
end;
end;
end.