Einzelnen Beitrag anzeigen

Benutzerbild von ich2
ich2

Registriert seit: 7. Dez 2005
Ort: Würzburg
54 Beiträge
 
#1

Multitouch Anwendung unter Delphi 7

  Alt 21. Nov 2010, 20:46
Hallo zusammen...

da ich mir ein Multitouch fähiges Tablet gekönnt habe, will ich natürlich auch gerne diese schöne Eigenschaft ausnutzen. Und das natürlich gerne unter Delphi 7!

Diese ganze Geschichte ist ja in Delphi 2010 bereits fest initialisiert, aber wir schauen einfach nach den nötigen Funktionen und Definitionen und holen sie uns nach Delphi 7. Eine kleine Einführung gibt bereits diese Seite:
http://wiki.helpmvp.com/home/notes/touch

Ich wollte aber noch zusätzlich die Anzahl der Finger und die Positionen der Finger haben, also mußte das Ganze noch mit dem WM_TOUCH -Event erweitert werden...

erstmal ein paar Definitionen:
Delphi-Quellcode:
const
  WM_GESTURENOTIFY = $011A;
  WM_GESTURE = $0119;
  WM_TOUCH = $0240;

  WM_TABLET_DEFBASE = $02C0;
  WM_TABLET_FLICK = WM_TABLET_DEFBASE + 11;

type
  TGestureNotifyStruct = record
    cbSize: UINT; // size, in bytes, of this structure
    dwFlags: DWORD; // unused
    hwndTarget: HWND; // handle to window targeted by the gesture
    ptsLocation: TSmallPoint; // starting location
    dwInstanceID: DWORD; // internally used
  end;
  PGestureNotifyStruct = ^TGestureNotifyStruct;

  TWMGestureNotify = packed record
    Msg: Cardinal;
    Unused: WPARAM;
    NotifyStruct: PGestureNotifyStruct;
    Result: Integer;
  end;

  HTOUCHINPUT = THandle;

type
  PTOUCHINPUT = ^TOUCHINPUT;
  TOUCHINPUT = record
    x: Integer;
    y: Integer;
    hSource: THandle;
    dwID: DWORD;
    dwFlags: DWORD;
    dwMask: DWORD;
    dwTime: DWORD;
    dwExtraInfo: LongInt;
    cxContact: DWORD;
    cyContact: DWORD;
  end;
  TTouchInput = TOUCHINPUT;

...

  TForm1 = class(TForm)
  protected
    procedure WMTOUCH(var Msg: TMessage); message WM_TOUCH;
    procedure WMGestureNotify(var Msg: TWMGestureNotify); message WM_GESTURENOTIFY;
    procedure WMGesture(var Msg: TMessage); message WM_GESTURE;
    procedure WMTabletFlick(var Msg: TMessage); message WM_TABLET_FLICK;
  private
    { Private declarations }
  public
    { Public declarations }
  end;
...dann holen wir uns noch die nötigen Funktionen aus der User32.dll (ACHTUNG: das funktioniert nur unter Windows 7 !!)...

Delphi-Quellcode:
  function CloseTouchInputHandle(hTouchInput: HTOUCHINPUT): BOOL; stdcall;
  function CloseTouchInputHandle; external user32 name 'CloseTouchInputHandle';

  function PhysicalToLogicalPoint(hWnd: HWND; var lpPoint: TPoint): BOOL; stdcall;
  function PhysicalToLogicalPoint; external user32 name 'PhysicalToLogicalPoint';

  function GetTouchInputInfo(hTouchInput: HTOUCHINPUT; cInputs: UINT; pInputs: PTOUCHINPUT; cbSize: Integer): BOOL; stdcall;
  function GetTouchInputInfo; external user32 name 'GetTouchInputInfo';

  function RegisterTouchWindow(hwnd: HWND; ulFlags: Cardinal): BOOL; stdcall;
  function RegisterTouchWindow; external user32 name 'RegisterTouchWindow';

  function UnregisterTouchWindow(hwnd: HWND): BOOL; stdcall;
  function UnregisterTouchWindow; external user32 name 'UnregisterTouchWindow';
...und schon kann man die Eingaben abholen...

Delphi-Quellcode:
procedure TForm1.WMGestureNotify(var Msg: TWMGestureNotify);
begin
  Msg.Result := DefWindowProc(Form1.Handle, Msg.Msg, Msg.Unused, Longint(Msg.NotifyStruct));
end;

procedure TForm1.WMGesture(var Msg: TMessage);
begin
  Msg.Result := DefWindowProc(Form1.Handle, Msg.Msg, Msg.WParam, Msg.LParam);
end;

procedure TForm1.WMTabletFlick(var Msg: TMessage);
begin
  Msg.Result := DefWindowProc(Form1.Handle, Msg.Msg, Msg.WParam, Msg.LParam);
end;

procedure TForm1.WMTOUCH(var Msg: TMessage);
  function TouchPointToPoint(const TouchPoint: TTouchInput): TPoint;
  begin
    Result := Point(TouchPoint.X div 100, TouchPoint.Y div 100);
    PhysicalToLogicalPoint(Form1.Handle, Result);
  end;

var
  TouchInputs: array of TTouchInput;
  counter: Integer;
  Handled: Boolean;
  Point: TPoint;
begin
  Handled := False;
  SetLength(TouchInputs, Msg.WParam);
  GetTouchInputInfo(Msg.LParam, Msg.WParam, @TouchInputs[0], SizeOf(TTouchInput));

  try
    for counter := 1 to Length (TouchInputs) do begin
      Point := TouchPointToPoint(TouchInputs [counter-1]);
      // ...
    end;

    Handled := True;
  finally
    if Handled then
      CloseTouchInputHandle(Msg.LParam)
    else
      inherited;
  end;
end;
...mit dem obigen Code bekommen wir noch keine Fingereingaben...wir müssen noch das Fenster-Handle registrieren...

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  RegisterTouchWindow ( Form1.Handle, 0 );
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  UnRegisterTouchWindow ( Form1.Handle );
end;
...und schon funktioniert es...

viel Spaß beim Spielen
Wissen ist Macht. Das ändert aber so gut wie nichts an der Übermacht der Dummheit.
  Mit Zitat antworten Zitat