WM_TOUCH erhalten

Antworten
compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

WM_TOUCH erhalten

Beitrag von compmgmt »

Moin,

seit einigen Tagen verzweifle ich daran die WM_TOUCH Message zu erhalten. Nach etlichen Google-Recherchen welche mich unter anderem zum englischen Lazarusforum, Delphi-Praxis, dem MSDN Forum u.a. geführt hatten erstelle ich nun mal selbst einen Beitrag dazu.

Angeblich ist die Sache realtiv einfach: Man ruft einmal RegisterTouchWindow auf und erhält ab dann die WM_TOUCH Message. Nur ist das bei mir nicht der Fall. Gleiches mit der WM_POINTER*** Message. Hab dazu mal ein Testprojekt erstellt:

Code: Alles auswählen

...
const
  TWF_FINETOUCH = $00000001;
  TWF_WANTPALM = $00000002;
  WM_TOUCH = $00000240;
  WM_POINTERDOWN = $00000246;
 
function RegisterTouchWindow(h: HWND; ulFlags: ULONG): BOOL; stdcall; external user32;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  public
    procedure WMTouch(var TheMessage: TLMessage); message WM_TOUCH;
    procedure WMPointerdown(var TheMessage: TLMessage); message WM_POINTERDOWN;
    procedure WndProc(var TheMessage: TLMessage); override;
  end;
 
...
 
implementation
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  if not RegisterTouchWindow(Handle, TWF_WANTPALM) then ShowMessage('Error: ' + IntToStr(GetLastError));
end;
 
procedure TForm1.WMTouch(var TheMessage: TLMessage);
begin
  ShowMessage('Touched');
end;
 
procedure TForm1.WMPointerdown(var TheMessage: TLMessage);
begin
  ShowMessage('Pointer down');
end;
 
procedure TForm1.WndProc(var TheMessage: TLMessage);
begin
  if (TheMessage.msg <> $20) and (TheMessage.msg <> $84) and (TheMessage.msg <> $B012) then begin
    WriteLn('0x' + IntToHex(TheMessage.msg, 8));
  end;
  inherited WndProc(TheMessage);
end;
 
end.
Das komplette Projekt befindet sich als ZIP im Anhang.

Im Terminal wird niemals "0x00000240" wenn ich mit dem Finger auf das Display tippe oder wische. Es wird immer nur 0x00000200 (Cursor Move), 0x00000201 (LMB Down), 0x00000202 (LMB Up) und 0x00000215. Also exakt die gleichen Messages wie bei normalen Mausaktionen.

Verwendete Hardware: Lenovo Yoga 520

P.S.: Im testprojekt ist WM_CONTEXTMENU nur drin, um zu testen ob überhaupt Messages korrekt ankommen.


- Patrick
Dateianhänge
TouchTest.zip
Testprojekt WM_TOUCH
(3.99 KiB) 270-mal heruntergeladen

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: WM_TOUCH erhalten

Beitrag von sstvmaster »

Schau mal hier wird damit sogar gemalt, ist zwar D7 aber vielleicht hilfts: http://www.tecepe.com.br/d7gestures/

Und hier auch noch was: https://www.delphipraxis.net/156146-mul ... i-7-a.html
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: WM_TOUCH erhalten

Beitrag von Michl »

Ich kann es hier nicht testen, doch probier mal, ob es bei dir so geht? Dein Projekt geändert anbei.
Dateianhänge
Touchtest2.zip
(2.56 KiB) 285-mal heruntergeladen

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: WM_TOUCH erhalten

Beitrag von compmgmt »

Michl hat geschrieben:Ich kann es hier nicht testen, doch probier mal, ob es bei dir so geht? Dein Projekt geändert anbei.

Vielen Dank, das hat mir sehr weitergeholfen.

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: WM_TOUCH erhalten

Beitrag von Michl »

Das ist gut.

Daß nicht alle Systemmessages durchgeleitet werden, ist leider ein Limit der systemübergreifenden Programmierung.
Der Sammelbugreport für ähnliche Probleme ist hier: https://bugs.freepascal.org/view.php?id=30415
Die Dokumentation dazu ist hier: http://wiki.lazarus.freepascal.org/Win32/64_Interface#Processing_non-user_messages_in_your_window

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Wal
Beiträge: 3
Registriert: So 16. Jan 2022, 09:49

Re: WM_TOUCH erhalten

Beitrag von Wal »

Das Beispiel funktioniert so wie es soll, aber ...
Wird ein z.B. ein Panel auf die Form gelegt geht es nicht mehr, auch nicht mit dem Panelhandle.
Ich habe mich an einem Fullscreenbrowser mit dem WebView4Delphi Projekt versucht was super funktioniert.
Das einzige Problem das ich habe ist der Touchscreen von meinem Windows Tablet, mache ich eine Wischfunktion um einen Webslider zu ziehen, ziehe ich die Webviewkomponente mit. Durch das Testprogramm oben konnte ich sehen, das ich die $401 Meldung vom Touch abfangen muss, damit die nicht weiter verarbeitet wird.
Da es eine Fullscreenanwendung ist könnte das auch Global abfangen, aber wie mache ich das ?

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: WM_TOUCH erhalten

Beitrag von Michl »

Ich kann es leider nicht testen, jedoch müsstest du das Handle der Webviewkomponente registrieren (wie im Testprojekt), wenn es das ist, was du per Touch bedienen willst: https://docs.microsoft.com/en-us/window ... ouchwindow
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 call RegisterTouchWindow any number of times for the same window if it desires to change the modifier flags.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Antworten