ankhmorpork
Goto Top

Mausposition auslesen

Hallo Experts,

vielleicht kann mich ein Pascal-Kundiger in die richtige Richtung schupsen. Habe wie ein Besengter gegoogelt, aber bewege mich da ständig im Kreis.

Ich benutze den FreePascal-Compiler 2.6.4 mit einer Lazarus-IDE.

Ich brauche die aktuelle Mausposition, und zwar die Bildschirmkoordinaten, nicht die Formularkoordinaten. Ich habe das mit
Mouse.CursorPos.X / Mouse.CursorPos.Y
im Mousemove-Handler probiert, aber dat lüppt nich. Ich bekomme zwar die Koordinaten, aber nur solange sich die Maus innerhalb des Formularfensters bewegt - ist auch klar, da ja der Mousemove-Handler des Formulars genötigt wird.

Frage also: Wie komme ich an die aktuelle Mausposition (in Bildschirm-Koordinaten), auch wenn das Anwendungsfenster minimiert ist? Hat jemand da draußen an den Bildschirmen einen Tipp für mich?
Vor vielen Jahren konnte man den Interrupt-Handler abfragen (Interrupt 33, wenn ich mich recht entsinne). Geht das mit modernen Betriebssystemen auch noch? Und ggf. wie?
Boah man, ist das lange her ...

Gruß

ankh

Content-ID: 249991

Url: https://administrator.de/contentid/249991

Ausgedruckt am: 22.11.2024 um 12:11 Uhr

narthan
narthan 24.09.2014 um 08:34:21 Uhr
Goto Top
Moin,

vlt. hilft dir folgendes:
Als ich das vor einiger Zeit brauchte, habe ich das HIER gefunden.
Einfach das Script mit dem Editor von AutoIT speichern und dann mit RunScript von AutoIT ausführen. Koordinaten werden dann in der linken Ecke oben angezeigt und können mit STRG+S zusätzlich in eine txt-Datei gespeichert werden.

 MsgBox(0, "Tastaturkürzel", "Mit STRG+S werden die Koordinaten in der Textdatei gespeichert." & @CRLF & "Mit STRG+D wird der Inhalt der Textdatei gelöscht"&@crlf&"Mit STRG+F werden Koordinaten und Pixelfarbe in HEX gespeichert")  

While 1 ;eigentliche schleife die die Koordinaten abliest und anzeigt
    HotKeySet("{esc}", "ende")  
    HotKeySet("^s", "save")  
    HotKeySet("^f", "savewithcoords")  
    HotKeySet("^d", "delete")  
    $file = FileOpen("coords.txt", 1)  
    $pos = MouseGetPos()
    $px = PixelGetColor($pos ,$pos[1])
    ToolTip($pos&", "&$pos[1]&@CRLF&"Pixelfarbe: "&Hex($px, 6), 0, 0)  
    Sleep(20)
WEnd

Func save() ;speichert die Koordinaten
    If $file = -1 Then Exit MsgBox(0, 'Maus-Koordinaten', 'Datei konnte nicht geöffnet werden!') ;überprüft ob die Datei schon vorhanden ist  
    FileWrite($file, $pos & ", " & $pos[1] & @CRLF)  
    FileClose($file)
EndFunc   ;==>save

Func savewithcoords() ;speichert die Koordinaten
    $file = FileOpen("coords.txt", 1)  
    If $file = -1 Then Exit MsgBox(0, 'Maus-Koordinaten', 'Datei konnte nicht geöffnet werden!') ;überprüft ob die Datei schon vorhanden ist  
    FileWrite($file, $pos & ", " & $pos[1] &" "& Hex($px, 6) & @CRLF)  
    FileClose($file)
EndFunc   ;==>save

Func delete() ;löscht den Inhalt der Textdatei
    $file = FileOpen("coords.txt", 2)  
    FileClose($file)
EndFunc   ;==>delete

Func ende() ; logischerweise: Ende xD
    Exit
EndFunc   ;==>ende

Grüße, narthan
AnkhMorpork
AnkhMorpork 24.09.2014 um 08:48:28 Uhr
Goto Top
Hallo narthan,

vielen Dank für deinen Beitrag. Aber ich glaube, wir haben uns mißverstanden. Ich benötige eine Pascal-Routine, die das erledigt, da ich es in ein bestehendes Programm integrieren möchte. Und ich möchte keine EXE in einer EXE verwursten.

Gruß

ankh
narthan
narthan 24.09.2014 um 09:05:04 Uhr
Goto Top
Oh alles klar, dann hab ich das tatsächlich falsch verstanden. Pardon face-plain
colinardo
colinardo 24.09.2014 um 12:35:44 Uhr
Goto Top
Moin Ankh,
kenne Pascal überhaupt nicht, aber laut Doku sollte sich die Mausposition in Screenkoordinaten mit GetMouseX / GetMouseY abfragen lassen.

Grüße Uwe
AnkhMorpork
AnkhMorpork 24.09.2014 um 12:39:40 Uhr
Goto Top
Zitat von @colinardo:

Moin Ankh,
kenne Pascal überhaupt nicht, aber laut Doku sollte sich die Mausposition in Screenkoordinaten mit
GetMouseX / GetMouseY abfragen lassen.

Grüße Uwe

Hallo Uwe,

ja, das funktioniert aber nur in der Konsole. Ich kasper mit eine GUI-Umgebung rum.
Sorry, hatte ich vergessen zu erwähnen.

Trotzdem danke!


Gruß

ankh
colinardo
Lösung colinardo 24.09.2014, aktualisiert am 25.09.2014 um 12:31:36 Uhr
Goto Top
Und was ist wenn du einfach die Windows API Funktion GetCursorPos über die user32.dll einbindest und aufrufst ?
ungefähr so einzubinden:
function GetCursorPos(var lpPoint: TPoint):Boolean;stdcall;external 'user32.dll';
AnkhMorpork
AnkhMorpork 24.09.2014 aktualisiert um 15:42:43 Uhr
Goto Top
Zitat von @colinardo:

Und was ist wenn du einfach die Windows API Funktion
GetCursorPos über die user32.dll
einbindest und aufrufst ?

DAS mus ich mal genauer beschnuppern. Da fehlt zwar noch einiges an Erfahrung, aber dat krije mer schonn.
Ist mir garnicht in den Sinn gekommen - blind ...

Danke für den Tipp!


EDIT:
Tja, das führt leider in dieselbe Sackgasse. Das Mousemove-Ereignis wird nur solange erkannt, wie sich der Zeiger innerhalb des Anwendungsfensters befindet. Das soll aber letztendlich minimiert werden.
Ich werde wohl eine komplett andere Strategie verfolgen müssen ...
colinardo
colinardo 25.09.2014 aktualisiert um 10:31:27 Uhr
Goto Top
Zitat von @AnkhMorpork:
EDIT:
Tja, das führt leider in dieselbe Sackgasse. Das Mousemove-Ereignis wird nur solange erkannt, wie sich der Zeiger innerhalb
des Anwendungsfensters befindet.
Das ist ja auch klar, da es nur die Anwendung erfasst.
Das soll aber letztendlich minimiert werden.
Mach die Abfrage über das API und einer While Schleife, feddich...
AnkhMorpork
AnkhMorpork 25.09.2014, aktualisiert am 26.09.2014 um 07:53:06 Uhr
Goto Top
Jepp - so geidas ... war doch ganz einfach. face-smile
Jetzt habe ich eine Arbeitsgrundlage, mit der ich weiterbasteln kann.

Wenn du mir mal im realen Leben über den Weg laufen solltest, gebe ich einen aus.

Gruß

ankh


Kleiner Nachtrag:

Die Definition der Funktion in fpc sieht konkret so aus:
function GetCursorPos(var lpPoint: TPoint):Boolean;

Ich habe das in einer kleinen Testumgebung probiert, und es lief optimal. Formular mit TLabel (zur Positionsanzeige), Umschalter und Timer.
Die Timer-Lösung ist zwar nicht optimal, aber zum Testen erträglich.

Hier mal der Quelltext:

unit MousePosScreen_unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Windows, LCLIntf, ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    PROCEDURE ShowMousePosition;
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  pos: TPoint;
  WantShowPos: BOOLEAN;

implementation

{$R *.lfm}

{ TForm1 }

PROCEDURE TForm1.ShowMousePosition;
BEGIN
  IF WantShowPos THEN
  BEGIN
       GetCursorPos(pos);
       Label1.Caption := IntToStr(pos.x) + ' | ' + IntToStr(pos.y);  
  END;
END;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
     Application.Processmessages;
     ShowMousePosition
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
     WantShowPos := FALSE;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
     WantShowPos := NOT WantShowPos;
end;



end.
Friemler
Friemler 15.07.2017 um 22:01:13 Uhr
Goto Top
Hallo Ankh,

ist zwar uralt, der Thread, aber der Vollständigkeit halber: Besser macht man sowas mit einem Mouse Hook. Dann kriegt man wirklich alle Mausbewegungen mit und flutet auch die Message Queue nicht mit Timer Events.

Grüße
Friemler
AnkhMorpork
AnkhMorpork 17.07.2017 um 07:49:19 Uhr
Goto Top
Ay Friemler,

Sachen gibbet ...
Ich werde das mal aus der Versenkung holen, abstauben und ein wenig damit spielen.

Vielen Dank für den Nachtrag.


Grüße zurück

Ankh