![]() |
WM_TOUCH und GetTouchInputInfo
Hallo miteinander ! :)
Ich habe mich in den letzten Tagen mit der Funktion GetTouchInputInfo und der Windows Message WM_TOUCH beschäftigt. Und schon sämtliche Foren und Artikel durchstöbert. Leider wurde ich nicht fündig und erhoffe mir nun hier eine Lösung zu meinem Problem. Ich möchte eigentlich nur 1-5 Finger auswerten um dann meine eigene Funktionen zu schreiben. Über die msg bekomme ich standartmäßig nur die Koordinaten des ersten Fingers heraus, aber keine Flags und auch nicht die anderen Finger, deswegen habe ich nach einer Funktion gesucht die mir alle Informationen zur verfügung stellt - GetTouchInputInfo. Aber bei dem Aufruf von GetTouchInputInfo bekomme ich immer als Rückgabewert "False" zurück, was soviel heißt wie "ERROR_INVALID_HANDLE". Ich habe schon sämtliche castings getestet (THandle/Uint64/Uint32/int64/int64(msg.lParam)), aber immer bekomme ich ungültiger Handle zurück. Ich bin im Prinzip so vorgegangen wie "ich2" vor 9 Jahren: ![]() Allerdings musste ich die user32.dll nicht importieren, da sie ja schon in der Winapi.Windows enthalten ist. Ich benutze einen SIEMENS IPC 477e Pro mit Multitouch auf dem die Anwendung laufen soll. (Touch wird erkannt, habe schon eine andere Anwendung darauf getestet) Und Programmiert wird mit Delphi 10.3.1 Rio auf Windows 10. Den Code habe ich auch schon mit Delphi 2010 getestet - Allerdings bekomme ich da den selben Fehler.
Code:
Viele Grüße Hofes
unit Unit1;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.AppEvnts, Vcl.StdCtrls; type TForm1 = class(TForm) Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure AppMessage(var Msg: tagMSG; var Handled: Boolean); public touchinput : array of TTouchInput; succes : boolean; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.AppMessage(var Msg: tagMSG; var Handled: Boolean); var le, i, lp : integer; begin if Msg.message = WM_TOUCH then begin Handled:= false; lp := Msg.lParam; SetLength(touchinput, msg.wParam); succes := GetTouchInputInfo(Msg.lParam, Msg.wParam, @Touchinput[0], SizeOf(TTouchinput)); le := GetLastError; //Hier erscheint immer der ErrorCode 6 - "ERROR_INVALID_HANDLE" //ShowMessage(BoolToStr(succes)); Memo1.Clear; Memo1.Lines.Add('suceeded: ' + BoolToStr(succes)); Memo1.Lines.Add('lasterror: ' + IntToStr(le)); Memo1.Lines.Add('msg.wparam: ' + IntToStr(Msg.wParam)); Memo1.Lines.Add('msg.lparam: ' + IntToStr(Msg.lParam)); Memo1.Lines.Add('msg.hwnd: ' + IntToStr(msg.hwnd)); for i := 0 to msg.wParam - 1 do begin memo1.Lines.Add(IntToStr(Touchinput[i].cxContact)); memo1.Lines.Add(IntToStr(Touchinput[i].cyContact)); end; Handled:= true; end; end; procedure TForm1.FormCreate(Sender: TObject); begin //ShowMessage(IntToStr(GetSystemMetrics(SM_DIGITIZER))); RegisterTouchWindow ( Form1.Handle, 0 ); Application.OnMessage:= AppMessage; end; end. |
AW: WM_TOUCH und GetTouchInputInfo
Wie ist es denn so?
Delphi-Quellcode:
procedure TForm1.AppMessage(var Msg: tagMSG; var Handled: Boolean);
var le: DWORD; i: integer; lp: HTOUCHINPUT; begin if Msg.message = WM_TOUCH then begin Handled := false; lp := Msg.lParam; SetLength(touchinput, Msg.wParam); SetLastError(0); succes := GetTouchInputInfo(lp, UINT(Msg.wParam), @touchinput[0], SizeOf(TTouchinput)); Memo1.Clear; if succes then begin Memo1.Lines.Add('suceeded: ' + BoolToStr(succes)); Memo1.Lines.Add('msg.wparam: ' + IntToStr(Msg.wParam)); Memo1.Lines.Add('msg.lparam: ' + IntToStr(Msg.lParam)); Memo1.Lines.Add('msg.hwnd: ' + IntToStr(Msg.hwnd)); for i := 0 to Msg.wParam - 1 do begin Memo1.Lines.Add(IntToStr(touchinput[i].cxContact)); Memo1.Lines.Add(IntToStr(touchinput[i].cyContact)); end; Handled := true; end else begin Memo1.Lines.Add(SysErrorMessage(GetLastError)); end; if Handled then begin CloseTouchInputHandle(lp); end; end; end; |
AW: WM_TOUCH und GetTouchInputInfo
"Der Vorgang wurde erflogreich beendet" wird mir in die Memo1 geschrieben.
Aber succes ist noch immer false. |
AW: WM_TOUCH und GetTouchInputInfo
Keine Ahnung ob du das schon getan hast.
Aber bevor du WM_TOUCH korrekt auswerten kannst musst du das entsprechende Window vorher für TOUCH registrieren. Siehe.. ![]() gruss |
AW: WM_TOUCH und GetTouchInputInfo
Genau, weil standartmäßig ist WM_GESUTRE aktiv. Das mache ich schon im onCreate vom Form.
Würde ich das Window/Handle nicht für Touch registrieren, dann würde ich auch keine WM_TOUCH messages bekommen.
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin //ShowMessage(IntToStr(GetSystemMetrics(SM_DIGITIZER))); RegisterTouchWindow(Form1.Handle, 0); Application.OnMessage:= AppMessage; end; |
AW: WM_TOUCH und GetTouchInputInfo
Zitat:
Nur als Nachtrag ist es denn das AktiveWindow? Meines Erachtens sollte man das nicht in Create machen. Fenster erstellen dann abfragen GetActiveWindow und dann dein Window für Touch registrieren. Vielleicht hilft es. ![]() gruss |
AW: WM_TOUCH und GetTouchInputInfo
Code:
du meinst wohl so oder? (Hat aber auch nichts geändert :( )
procedure TForm1.FormActivate(Sender: TObject);
begin RegisterTouchWindow(GetActiveWindow, 0 ); end; Sollte eigentlich keine Rolle spielen. Wie gesagt, wenn das Window nicht für den Touch registriert wurde, dann würde garkeine WM_TOUCH Message kommen. Zu dem Link: Ich hab ein Beispiel von C# getestet. Das Programm benutzt ja genau die selbe Funktion ![]() Und das funktioniert auf dem TouchPanel. Kann es sein dass die Message zwischenzeitlich schon wo anderst verwertet wird, und der Handle dadurch invalid wird? |
AW: WM_TOUCH und GetTouchInputInfo
Ich kenne das Programm nicht daher kann ich nur Vermutungen anstellen. Sorry.
Du kannst Touch für deine Form registrieren was ist aber wenn anschließend die Memo dein aktives Window ist? bsp. wenn es den Focus hat? Und dann? Wie gesagt eine Vermutung. gruss |
AW: WM_TOUCH und GetTouchInputInfo
Kann ich mir nicht vorstellen, habe auch schon ohne dem Memo getestet und
die Werte einfach in die Caption eines Labels geschrieben - Macht keinen unterschied |
AW: WM_TOUCH und GetTouchInputInfo
Zitat:
Ich frage mich nur noch eins wenn ich auf einem Button klicke welche Message wird dann gesendet die deiner Form oder die des Button. Und welche Winproc ist dann dafür zuständig die des Button(Fenster) oder die deiner Form(Fenster). Beides sind Fenster welches ist dann das Aktive? gruss |
AW: WM_TOUCH und GetTouchInputInfo
Zitat:
|
AW: WM_TOUCH und GetTouchInputInfo
Das ist schwierig. Auf meinem Rechner habe ich kein TouchDisplay und auf der Siemens Kiste mit Multitouch ist kein Delphi installiert ...
Wie könnte ich das noch nachschauen ? |
AW: WM_TOUCH und GetTouchInputInfo
|
AW: WM_TOUCH und GetTouchInputInfo
Ich hoffe das ist das was du meintest.
Bekomme beim touchen dann genau das hier raus: (0021DB2D){MultiTouch.exe} [0061EB2D] Unknown function at TMethodImplementationIntercept + $1583FD (0021BD1F){MultiTouch.exe} [0061CD1F] Unknown function at TMethodImplementationIntercept + $1565EF (0021DB38){MultiTouch.exe} [0061EB38] Unknown function at TMethodImplementationIntercept + $158408 //hier wird gettouchinputinfo() ausgeführt (0021DB2D){MultiTouch.exe} [0061EB2D] Unknown function at TMethodImplementationIntercept + $1583FD (0021BD1F){MultiTouch.exe} [0061CD1F] Unknown function at TMethodImplementationIntercept + $1565EF (0021DB38){MultiTouch.exe} [0061EB38] Unknown function at TMethodImplementationIntercept + $158408 Der Vorgang wurde erfolgreich beendet
Code:
procedure TForm1.AppMessage(var Msg: tagMSG; var Handled: Boolean);
var le: DWORD; i: integer; lp: HTOUCHINPUT; begin if Msg.message = WM_TOUCH then begin Handled := false; lp := Msg.lParam; SetLength(touchinput, Msg.wParam); Memo1.Clear; SetLastError(0); Memo1.Lines.Add(GetCurrentStack); succes := GetTouchInputInfo(lp, UINT(Msg.wParam), @touchinput[0], SizeOf(TTouchinput)); Memo1.Lines.Add(GetCurrentStack); if succes then begin Memo1.Lines.Add('suceeded: ' + BoolToStr(succes)); Memo1.Lines.Add('msg.wparam: ' + IntToStr(Msg.wParam)); Memo1.Lines.Add('msg.lparam: ' + IntToStr(Msg.lParam)); Memo1.Lines.Add('msg.lparam: ' + IntToStr(lp)); Memo1.Lines.Add('msg.hwnd: ' + IntToStr(Msg.hwnd)); for i := 0 to Msg.wParam - 1 do begin Memo1.Lines.Add(IntToStr(touchinput[i].cxContact)); Memo1.Lines.Add(IntToStr(touchinput[i].cyContact)); end; Handled := true; end else begin Memo1.Lines.Add(SysErrorMessage(GetLastError)); end; if Handled then begin CloseTouchInputHandle(lp); end; end; end; |
AW: WM_TOUCH und GetTouchInputInfo
Ich hoffes das ist das was du meintest :gruebel:
Code:
(0021DB2D){MultiTouch.exe} [0061EB2D] Unknown function at TMethodImplementationIntercept + $1583FD
(0021BD1F){MultiTouch.exe} [0061CD1F] Unknown function at TMethodImplementationIntercept + $1565EF (0021DB38){MultiTouch.exe} [0061EB38] Unknown function at TMethodImplementationIntercept + $158408 //hier wird gettouchinputinfo ausgeführt (0021DB2D){MultiTouch.exe} [0061EB2D] Unknown function at TMethodImplementationIntercept + $1583FD (0021BD1F){MultiTouch.exe} [0061CD1F] Unknown function at TMethodImplementationIntercept + $1565EF (0021DB38){MultiTouch.exe} [0061EB38] Unknown function at TMethodImplementationIntercept + $158408 Der Vorgang wurde erfolgreich beendet
Code:
procedure TForm1.AppMessage(var Msg: tagMSG; var Handled: Boolean);
var le: DWORD; i: integer; lp: HTOUCHINPUT; begin if Msg.message = WM_TOUCH then begin Handled := false; lp := Msg.lParam; SetLength(touchinput, Msg.wParam); Memo1.Clear; SetLastError(0); Memo1.Lines.Add(GetCurrentStack); succes := GetTouchInputInfo(lp, UINT(Msg.wParam), @touchinput[0], SizeOf(TTouchinput)); Memo1.Lines.Add(GetCurrentStack); if succes then begin Memo1.Lines.Add('suceeded: ' + BoolToStr(succes)); Memo1.Lines.Add('msg.wparam: ' + IntToStr(Msg.wParam)); Memo1.Lines.Add('msg.lparam: ' + IntToStr(Msg.lParam)); Memo1.Lines.Add('msg.lparam: ' + IntToStr(lp)); Memo1.Lines.Add('msg.hwnd: ' + IntToStr(Msg.hwnd)); for i := 0 to Msg.wParam - 1 do begin Memo1.Lines.Add(IntToStr(touchinput[i].cxContact)); Memo1.Lines.Add(IntToStr(touchinput[i].cyContact)); end; Handled := true; end else begin Memo1.Lines.Add(SysErrorMessage(GetLastError) ); end; if Handled then begin CloseTouchInputHandle(lp); end; end; end; |
AW: WM_TOUCH und GetTouchInputInfo
Das ist ein bisschen nichtssagend. Hast du einen Debug-Build oder ein Release-Build rüberkopiert?
|
AW: WM_TOUCH und GetTouchInputInfo
Ich habe die Lösung zu meinem Problem gestern nachmittag noch herausgefunden und auch gepostet.
Aber aus irgendeinem Grund ist der bis jetzt noch nicht erschienen.. Und ich möchte es nicht nochmal posten. Sonst passiert das selbe wie gestern - dass ich zwei mal das selbe schreibe. Wie wird denn sowas gehandhabt ? Ich habe auch schon versucht den gestrigen doppelt geposteten Beitrag zu löschen - ohne Erflog :? Gruß Hofes |
AW: WM_TOUCH und GetTouchInputInfo
Zitat:
Oder man meldet den Beitrag siehe der Button unter deinen Beitrag "Report!". Selber löschen kannst du nichts lediglich deinen Beitrag editieren bzw.. den Inhalt davon innerhalb 24Stunden löschen solange der "Bearbeiten" Button sichtbar ist. Du kannst auch über den Report Button eine Anfrage stellen warum dein Beitrag nicht erschienen ist. Mitunter wird hier Spam aussortiert nach welchen Kriterien hier vorgegangen wird.. keine Ahnung bin kein Mod\Admin. gruss |
AW: WM_TOUCH und GetTouchInputInfo
Liste der Anhänge anzeigen (Anzahl: 1)
Interssant :) da sagt mir das Hint aber was anderes :-D
Dann werd ich die Lösung von gestern nochmal posten müssen.. @TiGü Ja stimmt, das war in Release compiliert, mit Debug kommt auch nicht so viel mehr raus... Es ist so das GetTouchInputInfo mag aus irgendeinem Grund den Message Typ "tagMSG" nicht (kommt vom TApplicationEvents bzw Application.OnMessage). Wenn ich nun eine Prozedur direkt mit dem WM_TOUCH verknüpfe bekomm ich den Message Typ "TMessage". Diesen frisst die GetTouchInputInfo Funktion...
Code:
Das ist im Prinzip genau dasselbe wie "ich2" vor 9 Jahren.
procedure wmTouch(var msg : TMessage); message WM_TOUCH;
//.. //.. procedure TfrmMain.wmTouch(var Msg: TMessage); function tptp(const TouchPoint: TTouchInput): TPoint; begin Result := Point(TouchPoint.X div 100, TouchPoint.Y div 100); PhysicalToLogicalPoint(self.Handle, Result); end; var TouchInputs: array of TTouchInput; counter: Integer; Handled: Boolean; P: TPoint; begin Handled := False; SetLength(TouchInputs, Msg.WParam); GetTouchInputInfo(Msg.LParam, Msg.WParam, @TouchInputs[0], SizeOf(TTouchInput)); try frmMainDisp.Memo1.clear; for counter := 0 to Length(TouchInputs)-1 do begin P := tptp(Touchinputs[counter]); frmMainDisp.Memo1.Lines.Add('X'+ IntToStr(counter) + ': ' +IntToStr(p.x)); frmMainDisp.Memo1.Lines.Add('Y'+ IntToStr(counter) + ': ' +IntToStr(p.y)); end; Handled := True; finally if Handled then CloseTouchInputHandle(Msg.LParam) else inherited; end; end; Nur das ich die falschen Messages erhalten habe.. Gruß Hofes |
AW: WM_TOUCH und GetTouchInputInfo
Delphi-Quellcode:
procedure TForm1.AppMessage(var Msg: tagMSG; var Handled: Boolean);
Nun ja! Habe noch nirgends gesehen das man die Windows Messagen auf diese Art überschreibt. Destotrotz war wohl blind das ich das nicht gesehen habe. Viel Erfolg weiterhin. Zitat:
Sollte man vielleicht mal ändern. ;) Ich meine den Hint! gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz