Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi AutoIT Befehl "ControlSend" in Delphi (https://www.delphipraxis.net/110482-autoit-befehl-controlsend-delphi.html)

Circle 18. Mär 2008 19:58


AutoIT Befehl "ControlSend" in Delphi
 
Hallo Leute

einige von euch kennen bestimmt auch AutoIT. Da gibts nen Befel, der heisst ControlSend und sendet Tasten wie F1 etc... an einen Handle. Ich suche jetzt den selben Befehl eigentlich für Delphi, hab aber noch nichts gefunden.
Habs mit der Sendkey funktion versucht, keybd_event und anderen Befehlen.
Das Problem ist, dass die Applikation, also ein DirectX Spiel diese Befehle blockiert, aber die ControlSend Funktion von AutoIT wird nicht blockiert. Was ich nicht verstehe und deshalb hoffe, dass mir wer hier helfen kann.

toms 19. Mär 2008 18:37

Re: AutoIT Befehl "ControlSend" in Delphi
 
Hallo,

Du kannst mal folgende Prozedur probieren:

Delphi-Quellcode:
procedure PostKeyExHWND(hWindow: HWnd; key: Word; const shift: TShiftState;
  specialkey: Boolean);
{************************************************************
 * Procedure PostKeyEx
 *
 * Parameters:
 *  hWindow: target window to be send the keystroke
 *  key   : virtual keycode of the key to send. For printable
 *           keys this is simply the ANSI code (Ord(character)).
 *  shift : state of the modifier keys. This is a set, so you
 *           can set several of these keys (shift, control, alt,
 *           mouse buttons) in tandem. The TShiftState type is
 *           declared in the Classes Unit.
 *  specialkey: normally this should be False. Set it to True to
 *           specify a key on the numeric keypad, for example.
 *           If this parameter is true, bit 24 of the lparam for
 *           the posted WM_KEY* messages will be set.
 * Description:
 *  This procedure sets up Windows key state array to correctly
 *  reflect the requested pattern of modifier keys and then posts
 *  a WM_KEYDOWN/WM_KEYUP message pair to the target window. Then
 *  Application.ProcessMessages is called to process the messages
 *  before the keyboard state is restored.
 * Error Conditions:
 *  May fail due to lack of memory for the two key state buffers.
 *  Will raise an exception in this case.
 * NOTE:
 *  Setting the keyboard state will not work across applications
 *  running in different memory spaces on Win32 unless AttachThreadInput
 *  is used to connect to the target thread first.
 *Created: 02/21/96 16:39:00 by P. Below
 ************************************************************}
type
  TBuffers = array [0..1] of TKeyboardState;
var
  pKeyBuffers: ^TBuffers;
  lParam: LongInt;
begin
  (* check if the target window exists *)
  if IsWindow(hWindow) then
  begin
    (* set local variables to default values *)
    pKeyBuffers := nil;
    lParam := MakeLong(0, MapVirtualKey(key, 0));

    (* modify lparam if special key requested *)
    if specialkey then
      lParam := lParam or $1000000;

    (* allocate space for the key state buffers *)
    New(pKeyBuffers);
    try
      (* Fill buffer 1 with current state so we can later restore it.
         Null out buffer 0 to get a "no key pressed" state. *)
      GetKeyboardState(pKeyBuffers^[1]);
      FillChar(pKeyBuffers^[0], SizeOf(TKeyboardState), 0);

      (* set the requested modifier keys to "down" state in the buffer*)
      if ssShift in shift then
        pKeyBuffers^[0][VK_SHIFT] := $80;
      if ssAlt in shift then
      begin
        (* Alt needs special treatment since a bit in lparam needs also be set *)
        pKeyBuffers^[0][VK_MENU] := $80;
        lParam := lParam or $20000000;
      end;
      if ssCtrl in shift then
        pKeyBuffers^[0][VK_CONTROL] := $80;
      if ssLeft in shift then
        pKeyBuffers^[0][VK_LBUTTON] := $80;
      if ssRight in shift then
        pKeyBuffers^[0][VK_RBUTTON] := $80;
      if ssMiddle in shift then
        pKeyBuffers^[0][VK_MBUTTON] := $80;

      (* make out new key state array the active key state map *)
      SetKeyboardState(pKeyBuffers^[0]);
      (* post the key messages *)
      if ssAlt in Shift then
      begin
        PostMessage(hWindow, WM_SYSKEYDOWN, key, lParam);
        PostMessage(hWindow, WM_SYSKEYUP, key, lParam or $C0000000);
      end
      else
      begin
        PostMessage(hWindow, WM_KEYDOWN, key, lParam);
        PostMessage(hWindow, WM_KEYUP, key, lParam or $C0000000);
      end;
      (* process the messages *)
      Application.ProcessMessages;

      (* restore the old key state map *)
      SetKeyboardState(pKeyBuffers^[1]);
    finally
      (* free the memory for the key state buffers *)
      if pKeyBuffers <> nil then
        Dispose(pKeyBuffers);
    end; { If }
  end;
end; { PostKeyEx }

// Beispiel:

procedure TForm1.Button1Click(Sender: TObject);
var
  targetWnd: HWND;
begin
  targetWnd := FindWindow('notepad', nil)
    if targetWnd <> 0 then
    begin
      PostKeyExHWND(targetWnd, Ord('I'), [ssAlt], False);
  end;
end;

Circle 20. Mär 2008 15:49

Re: AutoIT Befehl "ControlSend" in Delphi
 
Wie kann ich denn damit einstellen, dass er die Taste zusammen mit CTRL drückt. Also z.B. Ctrl + F1


PostKeyExHWND(targetWnd, Ord('I'), [ssAlt], False);
Das hier funktioniert soweit, aber wenn ich z.B. F1 drücken will, muss ich das dann auch mit ORD machen, oder wie geht das?
Wofür steht das [ssAlt], steht zwar in der Beschreibung, habs aber ned ganz verstanden.

Dani 20. Mär 2008 15:58

Re: AutoIT Befehl "ControlSend" in Delphi
 
Zitat:

Zitat von Circle
ein DirectX Spiel

Welches denn? :gruebel:

halinchen 20. Mär 2008 16:07

Re: AutoIT Befehl "ControlSend" in Delphi
 
Zitat:

Zitat von Circle
PostKeyExHWND(targetWnd, Ord('I'), [ssAlt], False);
Das hier funktioniert soweit, aber wenn ich z.B. F1 drücken will, muss ich das dann auch mit ORD machen, oder wie geht das

F1 wäre VK_F1.

Siehe hier: http://msdn2.microsoft.com/en-us/library/ms927178.aspx

[ssAlt] steht dafür, das Alt auch gedrückt ist. [ssShift] wäre Shift und [] wäre keine Sondertaste.

Circle 22. Mär 2008 16:29

Re: AutoIT Befehl "ControlSend" in Delphi
 
Soweit funktioniert das alles gut, hab aber noch eine Frage zu dieser Funktion.

Also ich muss die rechte Maustaste gedrückt halten und gleichzeitig die Maus dabei nach links um sagen wir mal 100pixel bewegen.
Das gedrückt halten sollte ja so gehen.

Delphi-Quellcode:
PostKeyExHWND(fenster, VK_RBUTTON, [ssRight], False);
Wie mach ich das jetzt, das er gleichzeitig die Maus dabei bewegt. Weil wenn ich die Bewegung ja nach dem Tastendruck sende, wird das nacheinander gemacht und ned zusammen.

Dani 22. Mär 2008 17:13

Re: AutoIT Befehl "ControlSend" in Delphi
 
[/thread]

Erklärung: in der Regel wird dir hier keiner mehr antworten, sobald es offensichtlich ist, dass du Schadsoftware oder MP-Cheats programmierst. Guten Tag.

bundy 22. Mär 2008 18:35

Re: AutoIT Befehl "ControlSend" in Delphi
 
Zitat:

Zitat von Dani
[/thread]

Erklärung: in der Regel wird dir hier keiner mehr antworten, sobald es offensichtlich ist, dass du Schadsoftware oder MP-Cheats programmierst. Guten Tag.

Seit wann sind den Cheats verboten bei Offline Games ?
Das musst du mir mal erklären.
lg
bundy

Dani 23. Mär 2008 12:29

Re: AutoIT Befehl "ControlSend" in Delphi
 
Verboten ist, soviel ich weiß, nichts in der Richtung. Aber gerade was MP-Cheats (also Multi-Player) angeht, reagieren die meisten DP-Mitglieder eher ablehnend.

toms 23. Mär 2008 21:00

Re: AutoIT Befehl "ControlSend" in Delphi
 
[quote="Circle"]
Also ich muss die rechte Maustaste gedrückt halten und gleichzeitig die Maus dabei nach links um sagen wir mal 100pixel bewegen.
Das gedrückt halten sollte ja so gehen. [quote]

MOUSEEVENTF_LEFTDOWN dann MOUSEEVENTF_MOVE dann MOUSEEVENTF_LEFTUP mit SendInput simulieren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:19 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