Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Tastendruck -> Mausklicks (https://www.delphipraxis.net/105080-tastendruck-mausklicks.html)

Saturos 15. Dez 2007 12:01


Tastendruck -> Mausklicks
 
Hallo Delphipraktiker :hi: , ich habe folgendes vor:
Ich möchte ein Programm schreiben, welches bei Gedrückthalten einer Taste an der aktuellen Cursorposition im aktiven Fenster Mausklicks ausführt. Das soll später in einem Spiel Anwendung finden.

Hier der bisherige Code:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, ExtCtrls, StdCtrls, MMSystem, WinTypes, WinProcs;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    Beenden1: TMenuItem;
    Beenden2: TMenuItem;
    Hilfe1: TMenuItem;
    Controls1: TMenuItem;
    Panel1: TPanel;
    Button1: TButton;
    Image1: TImage;
    Timer1: TTimer;
    procedure Beenden2Click(Sender: TObject);
    procedure Controls1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  anaus:boolean;
  x,y,m:integer;
  curs:tpoint;


implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 timer1.Enabled:=false;
 anaus:=false;
 image1.Picture.LoadFromFile('pics/rot.bmp');
end;

procedure TForm1.Beenden2Click(Sender: TObject);
begin
 Application.Terminate;
end;

procedure TForm1.Controls1Click(Sender: TObject);
var Msg:string;
begin
 Msg:='Durch Drücken des Enable/Disable-Buttons, wird das Programm aktiviert.'+#10#13+'Ist es aktiv, so werden durch Gedrückthalten'+#10#13+'der Taste "Ö" pro Sekunde 100 Mausklicks an der'+#10#13+'gegenwärtigen Zeigerposition ausgeführt. Ob das Programm'+#10#13+'aktiv ist, erkennt man an der gegenwärtigen Farbe der'+#10#13+'Signallampe neben dem Enable/Disable-Button- Rot=Inaktiv, Grün=Aktiv.';
 showmessage(msg);
end;

procedure TForm1.Button1Click(Sender: TObject); //Über diesen Button wird gesteuert, ob bei Tastendruck geklickt wird                                                oder nicht
begin
 if anaus=false then begin
  anaus:=true;
  image1.Canvas.Refresh;
  image1.Picture.LoadFromFile('pics/grün.bmp')
 end
 else if anaus=true then begin
  anaus:=false;
  image1.Canvas.Refresh;
  image1.Picture.LoadFromFile('pics/rot.bmp')
 end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var i:integer;
begin
 for i:=1 to 10 do begin
  mouse_event(MOUSEEVENTF_LEFTDOWN, mouse.CursorPos.x, mouse.CursorPos.y, 0, 0);
  mouse_event(MOUSEEVENTF_LEFTUP, mouse.CursorPos.x, mouse.CursorPos.y, 0, 0)
 end;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
 if (Key = Ord('ö')) then begin
  m:=GetActiveWindow;
  GetCursorPos(curs);
  x:=Curs.x;
  y:=Curs.y;
   if anaus=true then
    timer1.Enabled:=true;
  end;
end;

end.
Ich habe schon mit Fensterhandles experimentiert, aber es scheitert, wie so oft schon daran, dass der Tastendruck (im Beispiel ö; auch andere getestet) von Delphi "wahrgenommen" wird :wall: .
Ich habe das Forum wirklich lange durchsucht, aber keine Lösung gefunden. :oops:

patti 15. Dez 2007 12:21

Re: Tastendruck -> Mausklicks
 
Zitat:

Zitat von Saturos
Ich habe schon mit Fensterhandles experimentiert, aber es scheitert, wie so oft schon daran, dass der Tastendruck (im Beispiel ö; auch andere getestet) von Delphi "wahrgenommen" wird :wall: .

Was genau meinst du mit "wahrgenommen" wird? Hast du KeyPreview von deiner Form an (im Objektinspektor einstellbar)?

Saturos 15. Dez 2007 15:41

Re: Tastendruck -> Mausklicks
 
Ja, wobei es auch manchmal ohne dessen Aktivierung ging. Wahrgenommen bedeutet hier, dass selbst dann, wenn ich das Prog aktiv habe und zum Beispiel ein anderes Bild auf Tastendruck einfügen lasse (testweise, anstelle der Klicks), Delphi nicht auf das Drücken der Taste reagiert.

patti 15. Dez 2007 15:48

Re: Tastendruck -> Mausklicks
 
Du könntest alternativ auch einen globalen Hier im Forum suchenHotkey definieren, bei dem du deinen Tastendruck simulierst. Der gilt dann systemweit und sollte immer funktionieren!

Die Muhkuh 15. Dez 2007 15:51

Re: Tastendruck -> Mausklicks
 
Hi,

wenn Dein Programm die Eingaben abfangen soll, dann bleiben Dir nur [dp]Hotkey[dp]s und Hier im Forum suchenHooks übrig.

Im OnKeyPress / OnKeyDown / OnKeyUp kommen die Buchstaben nur an, wenn Dein Programm den Fokus besitzt.

Saturos 15. Dez 2007 16:01

Re: Tastendruck -> Mausklicks
 
Gut, das hilft mir dann später weiter, aber momentan ist es noch so, dass nichteinmal dann, wenn mein Prog den "Fokus" hat die Buchstaben durchkommen.

Falls das hilft, habe ich Hier mal das Prog hochgeladen.

Saturos 15. Dez 2007 16:16

Re: Tastendruck -> Mausklicks
 
Danke :thumb: Dass es auf ö reagiert, hab ich zwar nicht hinbekommen, aber mit "o" geht es.

Saturos 15. Dez 2007 18:48

Re: Tastendruck -> Mausklicks
 
Zitat:

Zitat von patti
Du könntest alternativ auch einen globalen Hier im Forum suchenHotkey definieren, bei dem du deinen Tastendruck simulierst. Der gilt dann systemweit und sollte immer funktionieren!

Ich habe nun dazu entschlossen es mit den Hotkeys zu versuchen und gemerkt, dass ich die Keydownprocedur gar nich brauche :?
Hot-Keys systemweit setzen und verwenden <- Dort wurde im Beispiel Strg+F1 als Hotkey verwendet, aber für meine Zwecke ist ö nunmal ganz gut. Meine Frage ist nun, was ich in der Zeile:
Delphi-Quellcode:
...RegisterHotKey(Self.Handle, HotKeyID, MOD_SHIFT, VK_F1); ...
für VK_F1 einsetzen muss, um das ö als hotkey zu bekommen. In der Delphi-Hilfe stand unter Tastencodes etwas von Key_Odiaeresis für ö, aber das geht nicht. :gruebel:

Die Muhkuh 15. Dez 2007 18:49

Re: Tastendruck -> Mausklicks
 
Hi,

bin mir nicht ganz sicher, aber es dürfte das hier sein:

Delphi-Quellcode:
RegisterHotKey(Self.Handle, HotKeyID, MOD_SHIFT, Ord('ö'));
Hab den Aufruf jetzt nicht ganz im Kopf, falls es nicht klappt, müsstest mal in der Delphi-Hilfe bzw. im MSDN schauen, wenn es ein direkter API-Aufruf ist.

DeddyH 15. Dez 2007 18:49

Re: Tastendruck -> Mausklicks
 
Versuch es mal mit Ord('Ö')

[edit] Manuel *grmpf* :? [/edit]

Die Muhkuh 15. Dez 2007 18:50

Re: Tastendruck -> Mausklicks
 
Na Detlef :zwinker:

Mal wieder zu langsam für die Kuh? :mrgreen:

DeddyH 15. Dez 2007 18:51

Re: Tastendruck -> Mausklicks
 
[OT] Das können aber nur Sekunden gewesen sein :mrgreen: [/OT]

Die Muhkuh 15. Dez 2007 18:51

Re: Tastendruck -> Mausklicks
 
Zitat:

Zitat von DeddyH
[OT] Das können aber nur Sekunden gewesen sein :mrgreen: [/OT]

Aber es hat gereicht. :mrgreen:

DeddyH 15. Dez 2007 18:52

Re: Tastendruck -> Mausklicks
 
:P

Saturos 15. Dez 2007 22:13

Re: Tastendruck -> Mausklicks
 
Hmmm...aber leider nicht zur lösenden Antwort, denn Ord('ö/Ö') habe ich schon dutzende Male versucht. :freak:

patti 15. Dez 2007 22:16

Re: Tastendruck -> Mausklicks
 
Du hast aber schon beachtet, dass in deinem Code-Schnipsel die Shift-Taste (MOD_SHIFT) mit abgefragt wird, oder?

Patti

Saturos 16. Dez 2007 10:39

Re: Tastendruck -> Mausklicks
 
Ja, eigentlich schon. Wobei ich da nur ö genommen hätte, also mit 0 anstelle von MOD_SHIFT etc. .

patti 16. Dez 2007 11:33

Re: Tastendruck -> Mausklicks
 
Du könntest mal z.B. Alt + Ö oder eine Kombination mit einem anderen Buchstaben versuchen und überprüfen, ob das funktioniert. Eigentlich sollte es, solange der HotKey noch nicht anderweitig gesetzt ist, dann klappen. Ich weiß nicht, ob man einen einzelnen Buchstaben ohne MOD_... als Hotkey definieren kann, oder ob Windows das verbietet.

Patti

Saturos 16. Dez 2007 12:10

Re: Tastendruck -> Mausklicks
 
Also in der CodeLibrary stand, dass man auch eine einzelne Taste definieren kann. Diese letzte vereinbarte Taste muss laut Delphi vom Typ cardinal sein. Das dürften aber doch dann nur "Sondertasten", wie Pfeil auf oder - ab sein oder irre ich mich da?
Beim Testen habe ich herausgefunden, dass das Klicken außerhalb des Forms auch funktioniert, mein Problem ist nur den Timer wieder zu disabeln. Bis jetzt sieht das folgendermaßen aus:
Delphi-Quellcode:
var
  ...
  curs:tpoint;
  klick:boolean;

procedure TForm1.Timer1Timer(Sender: TObject);
var i:integer;
begin
 for i:=1 to 2 do begin
  mouse_event(MOUSEEVENTF_LEFTDOWN, Curs.x, Curs.y, 0, 0);
  mouse_event(MOUSEEVENTF_LEFTUP, Curs.x, Curs.y, 0, 0)
 end;
end;

procedure TForm1.WMHotKey(var Message:TMessage);
begin
   If Message.wParam=HotKeyID then begin
    if not klick then begin
     klick:= true;
     GetCursorPos(curs);
     if anaus=true then
      timer1.Enabled:=true
    else if klick then
     timer1.Enabled:=false;
    end;
   end;
end;
Die Variable klick ist am Anfang false und wird bei Aktivierung des Timers auf true gesetzt. Das würde also bedeuten, dass beim nächsten Mal, wenn der Hotkey gedrückt wird die zweite Bedingung erfüllt ist und der timer wieder gestoppt wird. Problem: beim erneuten Drücken des Hotkeys, wird der Timer trotzdem nicht gestoppt :wiejetzt: .

DeddyH 16. Dez 2007 12:13

Re: Tastendruck -> Mausklicks
 
Zitat:

Zitat von Saturos
Delphi-Quellcode:
    if not klick then begin
     klick:= true;
     GetCursorPos(curs);
     if anaus=true then
      timer1.Enabled:=true
    else if klick then
     timer1.Enabled:=false;
    end;

Wenn klick true ist, kommst Du gar nicht in den Block.

patti 16. Dez 2007 12:17

Re: Tastendruck -> Mausklicks
 
Außerdem veränderst du (soweit ich das jetzt richtig gesehen habe) die Variable "anaus" gar nicht. Diese bleibt bei dir immer true, der zweite "Block" wird allein deswegen nie ausgeführt!

Saturos 16. Dez 2007 12:29

Re: Tastendruck -> Mausklicks
 
Hmmm, das liegt daran, dass die Unterteilung net hinhaut. Das, wo anaus überprüft wird, ist noch der erste Block.
Delphi-Quellcode:
procedure TForm1.WMHotKey(var Message:TMessage);
begin
   If Message.wParam=HotKeyID then begin
    if not klick then begin//1.Block
     klick:= true;
     GetCursorPos(curs);
     if anaus=true then
      timer1.Enabled:=true
    else if klick then   //2.Block
     timer1.Enabled:=false;
    end;
   end;
end;

DeddyH 16. Dez 2007 12:31

Re: Tastendruck -> Mausklicks
 
Delphi-Quellcode:
procedure TForm1.WMHotKey(var Message:TMessage);
begin
   If Message.wParam=HotKeyID then begin
    if not klick then begin//1.Block
     klick:= true;
     GetCursorPos(curs);
    end;
    if anaus then //2.Block
      timer1.Enabled:=true
    else if klick then  
      timer1.Enabled:=false;  
   end;
end;
Versuch es mal so.

Saturos 16. Dez 2007 12:34

Re: Tastendruck -> Mausklicks
 
Nein es funktioniert auch so nicht. der Timer läuft und läuft ....

DeddyH 16. Dez 2007 12:36

Re: Tastendruck -> Mausklicks
 
Dann schalt den Timer doch mal im Timer-Event selbst aus. Ich versteh eh nicht, wozu Du soviele Variablen brauchst.

patti 16. Dez 2007 12:39

Re: Tastendruck -> Mausklicks
 
In deinem Code-Schnipsel bleibt immer noch anaus ständig true und wenn du schreibst:

Delphi-Quellcode:
if anaus=true then
      timer1.Enabled:=true
    else if klick then
     timer1.Enabled:=false;
    end;
Dann bleibt der Timer enabled. Schaltest du anaus irgendwann auch auf false?

Saturos 16. Dez 2007 12:41

Re: Tastendruck -> Mausklicks
 
:)
anaus: da gibt es einen Button, der das steuert. Also auch, ob bei Drücken des Hotkeys was läuft oder net.
klick: soll dazu dienen, dass in den Bedingungen erkannt wird, ob der timer läuft oder nicht (:wall: verdammt das geht auch direkt)
curs: speichert nur die Zeigerposition

DeddyH 16. Dez 2007 12:45

Re: Tastendruck -> Mausklicks
 
Also dient anaus dazu, zu ermitteln, ob Du auf den Hotkey reagieren willst?

Saturos 16. Dez 2007 12:46

Re: Tastendruck -> Mausklicks
 
Genau das.

DeddyH 16. Dez 2007 12:47

Re: Tastendruck -> Mausklicks
 
Delphi-Quellcode:
procedure TForm1.WMHotKey(var Message:TMessage);
begin
   If (Message.wParam=HotKeyID) and anaus then begin...
Erscheint mir erstmal logischer.

Saturos 16. Dez 2007 12:52

Re: Tastendruck -> Mausklicks
 
Ich habs jetzt:
Delphi-Quellcode:
procedure TForm1.WMHotKey(var Message:TMessage);
begin
 If Message.wParam=HotKeyID then begin
    if (not klick) and (anaus) then begin
     klick:= true;
     GetCursorPos(curs);
     timer1.Enabled:=true
     end
    else if klick then  
      timer1.Enabled:=false;  
   end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:59 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz