[gelöst] Maus-Tasten abfragen

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 993
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Linux Mint 20 , FPC 3.3.1 , Lazarus 2.1.0 -Win10 & XE7Pro
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

[gelöst] Maus-Tasten abfragen

Beitrag von kralle »

Moin,

die Linke, die Rechte und die mittlere Maustaste kann man ja über die "OnMousexxxx"-Events abfragen, aber wie komme ich an die Sondertasten der Maus und das am besten auch noch Platformunabhängig?

Gruß Heiko
Zuletzt geändert von kralle am Mi 11. Jan 2017, 17:48, insgesamt 1-mal geändert.
OS: Manjaro Linux, Debian und Windows 10
FPC-Version: 3.2.2 , Lazarus 3.0
+ Delphi XE7SP1

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 993
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Linux Mint 20 , FPC 3.3.1 , Lazarus 2.1.0 -Win10 & XE7Pro
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Maus-Tasten abfragen

Beitrag von kralle »

Moin,

hat noch nie jemand auf die Sondertasten seiner Maus von Lazarus/FPC aus zugegriffen und weiß wie es geht?

Gruß Heiko
OS: Manjaro Linux, Debian und Windows 10
FPC-Version: 3.2.2 , Lazarus 3.0
+ Delphi XE7SP1

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Maus-Tasten abfragen

Beitrag von Mathias »

So viel ich weis, werden die Sondertasten nur vom Maustreiber abgefangen, ausgenommen noch das Maus-Rad.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Maus-Tasten abfragen

Beitrag von Socke »

Die Schwierigkeit ist, dass die zusätzlichen Maustasten (neben Rechts, Links, Mitte, Rad) aus Sicht von Windows gar keine Maustasten sind.

Vielmehr wird daraus in Windows ein sogenannter App-Command generiert. Dazu gehören auch die Multimediatasten auf der Tastatur oder ggf. einer Fernbedienung.
Unter [1] http://stackoverflow.com/questions/2458730/how-to-detect-forward-and-back-mouse-button-events-in-delphi ist die Vorgehensweise unter Delphi beschrieben. D.h. du musst die Windows-Message WM_APPCOMMAND abfangen und deren Parameter wie dort gezeigt auswerten.

Unter Lazarus musst du aber einen anderen Weg gehen um die Windows-Message abzufangen. Dieser ist unter [2] http://wiki.lazarus.freepascal.org/Win32/64_Interface#Processing_non-user_messages_in_your_window beschrieben.

Ein kleines Beispiel mit den Konstanten aus [1] habe ich unten eingefügt (WM_APPCOMMAND ist bereits in der Unit Windows definiert und wurde von mir hier ausgelassen). Hierzu bitte einfach ein neues Projekt (Typ: Anwendung) erstellen.

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  sysutils, Forms, Dialogs, windows;
 
// Siehe http://stackoverflow.com/questions/2458 ... -in-delphi
const
  // Windows 2000, ME, and above
  APPCOMMAND_BROWSER_BACKWARD                   = 1;
  APPCOMMAND_BROWSER_FORWARD                    = 2;
  APPCOMMAND_BROWSER_REFRESH                    = 3;
  APPCOMMAND_BROWSER_STOP                       = 4;
  APPCOMMAND_BROWSER_SEARCH                     = 5;
  APPCOMMAND_BROWSER_FAVORITES                  = 6;
  APPCOMMAND_BROWSER_HOME                       = 7;
  APPCOMMAND_VOLUME_MUTE                        = 8;
  APPCOMMAND_VOLUME_DOWN                        = 9;
  APPCOMMAND_VOLUME_UP                          = 10;
  APPCOMMAND_MEDIA_NEXTTRACK                    = 11;
  APPCOMMAND_MEDIA_PREVIOUSTRACK                = 12;
  APPCOMMAND_MEDIA_STOP                         = 13;
  APPCOMMAND_MEDIA_PLAY_PAUSE                   = 14;
  APPCOMMAND_LAUNCH_MAIL                        = 15;
  APPCOMMAND_LAUNCH_MEDIA_SELECT                = 16;
  APPCOMMAND_LAUNCH_APP1                        = 17;
  APPCOMMAND_LAUNCH_APP2                        = 18;
  APPCOMMAND_BASS_DOWN                          = 19;
  APPCOMMAND_BASS_BOOST                         = 20;
  APPCOMMAND_BASS_UP                            = 21;
  APPCOMMAND_TREBLE_DOWN                        = 22;
  APPCOMMAND_TREBLE_UP                          = 23;
  // Windows XP and above
  APPCOMMAND_MICROPHONE_VOLUME_MUTE             = 24;
  APPCOMMAND_MICROPHONE_VOLUME_DOWN             = 25;
  APPCOMMAND_MICROPHONE_VOLUME_UP               = 26;
  APPCOMMAND_HELP                               = 27;
  APPCOMMAND_FIND                               = 28;
  APPCOMMAND_NEW                                = 29;
  APPCOMMAND_OPEN                               = 30;
  APPCOMMAND_CLOSE                              = 31;
  APPCOMMAND_SAVE                               = 32;
  APPCOMMAND_PRINT                              = 33;
  APPCOMMAND_UNDO                               = 34;
  APPCOMMAND_REDO                               = 35;
  APPCOMMAND_COPY                               = 36;
  APPCOMMAND_CUT                                = 37;
  APPCOMMAND_PASTE                              = 38;
  APPCOMMAND_REPLY_TO_MAIL                      = 39;
  APPCOMMAND_FORWARD_MAIL                       = 40;
  APPCOMMAND_SEND_MAIL                          = 41;
  APPCOMMAND_SPELL_CHECK                        = 42;
  APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE  = 43;
  APPCOMMAND_MIC_ON_OFF_TOGGLE                  = 44;
  APPCOMMAND_CORRECTION_LIST                    = 45;
  // Windows XP SP1 and above
  APPCOMMAND_MEDIA_PLAY                         = 46;
  APPCOMMAND_MEDIA_PAUSE                        = 47;
  APPCOMMAND_MEDIA_RECORD                       = 48;
  APPCOMMAND_MEDIA_FAST_FORWARD                 = 49;
  APPCOMMAND_MEDIA_REWIND                       = 50;
  APPCOMMAND_MEDIA_CHANNEL_UP                   = 51;
  APPCOMMAND_MEDIA_CHANNEL_DOWN                 = 52;
 
  FAPPCOMMAND_MOUSE = $8000;
  FAPPCOMMAND_KEY   = 0;
  FAPPCOMMAND_OEM   = $1000;
  FAPPCOMMAND_MASK  = $F000;
 
  // Mouse buttons;  remaining ones are declared in Windows.pas
  MK_XBUTTON1 = $20;
  MK_XBUTTON2 = $40;
 
function GET_APPCOMMAND_LPARAM(lParam: LPARAM): Short;
function GET_DEVICE_LPARAM(lParam: LPARAM): Word;
function GET_KEYSTATE_LPARAM(lParam: LPARAM): Word;
 
(******************************************************************************
 * Das ursprüngliche Formular                                                 *
 ******************************************************************************)

type
  TForm1 = class(TForm)
    ApplicationProperties1: TApplicationProperties;
    procedure FormCreate(Sender: TObject);
    procedure AsyncMsg(Data: PtrInt);
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
function GET_APPCOMMAND_LPARAM(lParam: LPARAM): Short;
begin
  Result := HiWord(lParam) and not FAPPCOMMAND_MASK;
end;
 
function GET_DEVICE_LPARAM(lParam: LPARAM): Word;
begin
  Result := HiWord(lParam) and FAPPCOMMAND_MASK;
end;
 
function GET_KEYSTATE_LPARAM(lParam: LPARAM): Word;
begin
  Result := LoWord(lParam);
end;
 
var
  // Ursprünglicher (LCL) Message-Handler
  PrevWndProc: WNDPROC;
 
function WndCallback(Ahwnd: HWND; uMsg: UINT; wParam: WParam; lParam: LParam):LRESULT; stdcall;
var
  p: SHORT;
begin
  if uMsg=WM_APPCOMMAND then
  begin
    // AppCommand ermitteln
    p := GET_APPCOMMAND_LPARAM(LParam);
    // Zur asynchronen Verarbeitung an eine Methode des Formulars Form1
    // weiterleiten. Wenn die weiteren Parameter ebenfalls verwendet werden
    // sollen, müssen diese anderweitig übergeben werden
    Application.QueueAsyncCall(@form1.AsyncMsg, p);
  end;
  // Ursprünglichen (LCL) Message-Handler aufrufen
  result:=CallWindowProc(PrevWndProc,Ahwnd, uMsg, WParam, LParam);
end;
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  // Eigenen Windows-Message-Handler setzen
  // Siehe http://wiki.lazarus.freepascal.org/Win3 ... our_window
  PrevWndProc:=Windows.WNDPROC(SetWindowLongPtr(Self.Handle,GWL_WNDPROC,PtrInt(@WndCallback)));
end;
 
procedure TForm1.AsyncMsg(Data: PtrInt);
begin
  // Als Demo nur die Ausgabe des Zahlencodes
  ShowMessage('appcommand: '+ inttostr(data));
end;
 
end.


Die Funktion WndCallback wird im Beispiel jedoch nur aufgerufen, wenn Form1 beim Drücken der Multimedia-Taste den Fokus hat. Ist es minimiert oder ist ein modales Fenster geöffnet ist (dazu gehören auch Dialoge wie ShowMessage oder MessageDlg wie im Beispiel!), wird sie nicht aufgerufen. Hier kenne ich jedoch nicht den Grund, gehe aber davon aus, dass man dies irgendwie umgehen kann (zumindest bei minimiertem Fenster).

Dies ist die Situation unter Windows. Unter Linux, Mac OS X und deren Widget-Sets sieht die Situation anders aus. Einen plattformunabhängigen Weg habe ich nicht gefunden (aber auch nicht gesucht).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 993
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Linux Mint 20 , FPC 3.3.1 , Lazarus 2.1.0 -Win10 & XE7Pro
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Maus-Tasten abfragen

Beitrag von kralle »

Hallo Socke,

vielleicht bin ich im Moment zu müde, aber

Code: Alles auswählen

ShowMessage
wird nie ausgeführt.
Egal welche Maus-Taste oder Multimedia-Taste ich drücke.

Gruß
Heiko
OS: Manjaro Linux, Debian und Windows 10
FPC-Version: 3.2.2 , Lazarus 3.0
+ Delphi XE7SP1

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Maus-Tasten abfragen

Beitrag von Socke »

kralle hat geschrieben:vielleicht bin ich im Moment zu müde, aber

Code: Alles auswählen

ShowMessage
wird nie ausgeführt.
Egal welche Maus-Taste oder Multimedia-Taste ich drücke.

Bei den "normalen" Maustasten sollte dies auch nicht der Fall sein.
Wird denn die Funktion WndCallback() überaupt aufgerufen? Wie kommt dort ein Tastendruck auf eine Multimediataste an?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
kralle
Lazarusforum e. V.
Beiträge: 993
Registriert: Mi 17. Mär 2010, 14:50
OS, Lazarus, FPC: Linux Mint 20 , FPC 3.3.1 , Lazarus 2.1.0 -Win10 & XE7Pro
CPU-Target: 64Bit
Wohnort: Bremerhaven
Kontaktdaten:

Re: Maus-Tasten abfragen

Beitrag von kralle »

Hallo Socke,

Asche auf mein Haupt!
Ich hatte vergessen, das "OnFormCreate"-Ereignis einzutragen. :oops:

Jetzt funktioniert das Programm, nur leider werden zwei Maus-Tasten nicht erkannt.
Aber, das was ich a) wissen wollt und b) ausprobieren wollte, habe ich erfahren/probiert.

Danke.

Gruß Heiko
OS: Manjaro Linux, Debian und Windows 10
FPC-Version: 3.2.2 , Lazarus 3.0
+ Delphi XE7SP1

Antworten