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 sendkey methode umbauen (https://www.delphipraxis.net/121161-sendkey-methode-umbauen.html)

benny1452 23. Sep 2008 11:02


sendkey methode umbauen
 
Guten Morgen,

Es geht um einen Text den ich automatisch abtippen lassen möchte.
Jedoch hab ich die sendkey methode in vba schon ausprobier, klappt auch super, nun wollte ich mal fragen ob mir jemand was zu der sendkeymethode hier in delpihi erklären kann...gegoogelt hab ich selber schon...bekomm auch zum beispiel diesen code hier:

Delphi-Quellcode:
procedure SendKeyString(KStr: String);
var
  Scan: SHORT;
  key: Byte;
  i: Integer;
begin
  for i := 0 to length(KStr) do begin
    key := Byte(Kstr[i]);
    Scan := MapVirtualKey(key, 0);
    keybd_event(key, Scan, 0, 0);
    keybd_event(key, Scan, KEYEVENTF_KEYUP, 0);
  end;
end;
Das ist jetzt irgendein Beispiel...kann mir einer den code so umbauen das an ein aktives fenster z.B: www.delphi.de geschickt wird ?
Noch besser wäre es natülich wenn mir einer das auch ein wenig erklärt :)

wenn ich auf: Datei->Neu->Neue VCL Anwendung gehe, dann ein Button erstelle, auf den dann ein doppelklick mache und dort den code einfüge kommen 3 Fehler (so führt man doch den code aus oder geht das auch anders?) :

[Pascal Fehler] Unit1.pas(40): E2029 Deklaration erwartet, aber Dateiende gefunden
[Pascal Fehler] Unit1.pas(12): E2065 Ungenügende Forward- oder External-Deklaration: 'TForm1.Button1Click'
[Pascal Fataler Fehler] Project2.dpr(5): F2063 Verwendete Unit 'Unit1.pas' kann nicht compiliert werden

danke schonmal

gruß benny

Kalfany 23. Sep 2008 11:08

Re: sendkey methode umbauen
 
Bitte dazu schreiben das ein Crosspost existiert :wink:

alleinherrscher 23. Sep 2008 11:11

Re: sendkey methode umbauen
 
Huhu und Willkommen im Forum :zwinker:

Öhm, sieht so aus als wäre da was an der Prozedurdeklaration falsch. Kannst mal explizit deinen Sourcecode hier rein schreiben?

benny1452 23. Sep 2008 11:13

Re: sendkey methode umbauen
 
hehe woher weißt du das denn ? :oops:

jetzt wissen das ja gleich alle :oops:

Öhh welchen Sourcecode meinst du ? ich denk das war der schon ? brauch man nochwas um das prigramm ausführen zu können ?
ouh man bei Visual Basic war das alles so einfach :?

EDIT: Ich finds übrigens super, dass ich gleich so viele schnelle antworten bekomme

alleinherrscher 23. Sep 2008 11:16

Re: sendkey methode umbauen
 
Viele Forumsmitglieder sind sowohl im delphi-Praxis als auch im delphi-Forum. Schick uns doch einfach mal den kompletten Quelltext, der in dem Formular steht, wenn du auf den Button doppelklickst.

benny1452 23. Sep 2008 11:22

Re: sendkey methode umbauen
 
ah okay :)
hier hab ich mal den kompletten code....wobei ich überhaupt nicht weiß was und wofür der erste teil gut ist.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure SendKeyString(KStr: String);
var
  Scan: SHORT;
  key: Byte;
  i: Integer;
begin
  for i := 0 to length(KStr) do begin
    key := Byte(Kstr[i]);
    Scan := MapVirtualKey(key, 0);
    keybd_event(key, Scan, 0, 0);
    keybd_event(key, Scan, KEYEVENTF_KEYUP, 0);
  end;
end;

alleinherrscher 23. Sep 2008 11:29

Re: sendkey methode umbauen
 
Okay, da haben wir doch schon das Problem. Wenn du auf einen Button klickst, erstellt dir die Entwicklungsumgebung automatisch eine Prozedur, welche beim einem Event (nämlich dem Klick auf den Button) ausgeführt wird. Diese Prozedur muss zunächst deklariert werden, also wird dem Compiler gesagt "Hallo, dieses Forumlar besitzt eine Methode, die so und so heißt, und folgende Parameter besitzt". Dies ist im oberen Teil der Fall:

Delphi-Quellcode:
procedure Button1Click(Sender: TObject);
Später kommt dann die Implementierung der Prozedur, also die eigentliche Umsetzung, der Quelltext, der ausgeführt werden soll.
Dafür erstellt dir die Entwicklungsumgebung eine leere Prozedur, (die genauso heißen muss, wie vorher in der Deklaration)

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin




end;
Diese hast du aber gelöscht. Der Compiler sieht also die Deklaration im oberen Teil deiner Unit, aber findet die Umsetzung, also die Implementierung nicht. Deswegen gibt es einen fehler.

//edit:

Du könntest das ganze z.B. so lösen:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure SendKeyString(KStr: String);
var
  Scan: SHORT;
  key: Byte;
  i: Integer;
begin
  for i := 0 to length(KStr) do begin
    key := Byte(Kstr[i]);
    Scan := MapVirtualKey(key, 0);
    keybd_event(key, Scan, 0, 0);
    keybd_event(key, Scan, KEYEVENTF_KEYUP, 0);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin

  SendKeyString('test');

end;

end.
In diesem Beispielcode würde beim Klick auf den Button die Prozedur SendKeyString aufgerufen und der String 'test' übergeben.

benny1452 23. Sep 2008 11:45

Re: sendkey methode umbauen
 
oaky nun hab ich beide Proceduren so benannt:

Delphi-Quellcode:
procedure Button1Click(Sender: TObject);
Bekomme aber immernoch n haufen von fehlermeldungen:

[Pascal Fehler] Unit1.pas(32): E2003 Undefinierter Bezeichner: 'KStr'
[Pascal Fehler] Unit1.pas(40): E2029 Deklaration erwartet, aber Dateiende gefunden
[Pascal Fehler] Unit1.pas(12): E2065 Ungenügende Forward- oder External-Deklaration: 'TForm1.Button1Click'
[Pascal Fataler Fehler] Project1.dpr(5): F2063 Verwendete Unit '..\..\Desktop\Unit1.pas' kann nicht compiliert werden

Ich denk ma das ich jetzt statt: "KStr" -> "TObject" deklarieren müsste. Aber wie mach ich das ?

// NACH DEINEM EDIT:

also okay...nun bekomm ich nurnoch diese Fehlermeldung:

[Pascal Fehler] Unit1.pas(50): E2029 Deklaration erwartet, aber Dateiende gefunden
[Pascal Fataler Fehler] Project1.dpr(5): F2063 Verwendete Unit '..\..\Desktop\Unit1.pas' kann nicht compiliert werden

PS. übrigens ist die melung, dass es inzwischen ein neuen Beitrag gibt, ziemlich genial :)

alleinherrscher 23. Sep 2008 11:46

Re: sendkey methode umbauen
 
Ich glaube ich habe am Schluss das "end." vergessen ;) Habe es in meinem letzten Beitrag mal korrigiert.

benny1452 23. Sep 2008 11:53

Re: sendkey methode umbauen
 
okay prima....darauf hätt ich auch selbst kommen können ...^^

also nun klappt das shconmal ohne fehlermeldung, aber wo steht denn jetzt der text: `test`
ich muss doch lediglich z.B. wordpad öffnen und das dan als aktives fenster machen oder ?
Und wie lange hab ich dann vom ausführen unseres kleinen progs zeit das wordpad aktive zu setzten ?

danke

alleinherrscher 23. Sep 2008 12:21

Re: sendkey methode umbauen
 
Die Frage müsstest du dir teilweise selbst beantworten können: Wann wird der Code ausgeführt? -> Wenn du auf den Button klickst. Allerdings siehst du den 'test' - Text nirgendwo, weil du praktisch auf dein eigenes Formular tippst. Du musst also irgendwie das Fenster, wie z.B. Wordpad in den vordergrund holen, bevor du tippst.

Such also mal nach SetForegroundWindow

benny1452 23. Sep 2008 12:28

Re: sendkey methode umbauen
 
okay werd ich mal machen....aber könnte man nicht eine Pause von ungefähr 5 sekunden einbauen bevor er: TEST schreibt ?
Dann hätte ich also 5 Sekunden Zeit WordPad zu öffnen.

alleinherrscher 23. Sep 2008 12:44

Re: sendkey methode umbauen
 
Zitat:

Zitat von benny1452
okay werd ich mal machen....aber könnte man nicht eine Pause von ungefähr 5 sekunden einbauen bevor er: TEST schreibt ?
Dann hätte ich also 5 Sekunden Zeit WordPad zu öffnen.

Du kannst auch Wordpad direkt durch dein Programm öffnen lassen(Stichwort hierfür ist ShellExecute)

Natürlich kannst du auch ne 5 Sekunden Pause einbauen (mit sleep(5000) ) aber das halte ich nicht für sehr sinnvoll. Mir ist eh noch nicht so ganz klar, was du mit dem Programm machen willst...

benny1452 23. Sep 2008 13:07

Re: sendkey methode umbauen
 
Ich hab mir mal die sleep funktion angeschaut und herausgekommen ist folgendes:

Diese Funktion hab ich versucht einzubauen:

Delphi-Quellcode:
time:=GetTickCount;
while (GetTickCount-time < 5000 ) do
 application.ProcessMessages; //sonst friert das Programm ein
und hier nochmal der ganze code nachher hab ich das noch an der falschen stelle eingefügt oder sowas ^^

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure SendKeyString(KStr: String);
var
  Scan: SHORT;
  key: Byte;
  i: Integer;
  time: Longint;
begin
  for i := 0 to length(KStr) do begin
    key := Byte(Kstr[i]);
    Scan := MapVirtualKey(key, 0);
    keybd_event(key, Scan, 0, 0);
    keybd_event(key, Scan, KEYEVENTF_KEYUP, 0);
  end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
time:= GetTickCount;
while (GetTickCount-time < 5000) do
 application.ProcessMessages; //sonst friert das Programm ein



SendKeyString('test');


end;
end.
Ich bekomme aber noch diese fehler hier:
[Pascal Hinweis] Unit1.pas(32): H2164 Variable 'time' wurde deklariert, aber in 'SendKeyString' nicht verwendet
[Pascal Fehler] Unit1.pas(43): E2064 Der linken Seite kann nichts zugewiesen werden
[Pascal Fataler Fehler] Project1.dpr(5): F2063 Verwendete Unit '..\..\Desktop\Unit1.pas' kann nicht compiliert werden

danke nochmal für deine geduld =)

DeddyH 23. Sep 2008 13:28

Re: sendkey methode umbauen
 
time ist eine lokale Variable von SendKeyString, Du willst aber im ButtonClick darauf zugreifen.

[edit] Außerdem ist "time" ein unglücklich gewählter Name, da es auch eine Funktion dieses Namens gibt. [/edit]

benny1452 23. Sep 2008 13:40

Re: sendkey methode umbauen
 
ups..ja stimmt natürich...das problem hab ich jetzt gelöst....da smit den 5 sekunden pause klappt auch wunderbar.

Aber warum bekomm ich jetzt diese ausgabe: 14:33 23.09.2008514:33 23.09.2008 ?

Das ist doch zum mäuse melken, würde meine omi jetzt sagen :roll:

Nach deinem EDIT:

hhm ich hab jz alles was: "time" hieß unbenannt in "pause"
ich bekomm aber immernoch die zeit+datum ausgegeben anstatt mein bespieltext: TEST

:(

DeddyH 23. Sep 2008 13:55

Re: sendkey methode umbauen
 
Ich habe ein bisschen suchen müssen, aber versuch es mal mit dieser Funktion: Klick

benny1452 23. Sep 2008 14:05

Re: sendkey methode umbauen
 
okay...das klingt ja nach ungefähr dem gleichen...

Wo kann man denn da seinen Text bzw. die einzelnen Buchstaben eingeben ?
ich denke mal in so einer zeile hier:

Delphi-Quellcode:
if lWithShift then
      keybd_event(VK_SHIFT, 0, 0, 0);
VK_SHIFT bedeutet, dass die shifttaste gedrückt werden soll...das ist mir soweit klar aber wozu sind die drei Nullen dahinter ?

könntest du mal so eine beispielzeile posten ?

danke

DeddyH 23. Sep 2008 14:08

Re: sendkey methode umbauen
 
http://msdn.microsoft.com/de-de/ms64...us,VS.85).aspx

alleinherrscher 23. Sep 2008 14:37

Re: sendkey methode umbauen
 
So könnte es gehen, aber wie gesagt, sehr sinnvoll ist das nicht:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure SendKeyString(KStr: String);
var
  Scan: SHORT;
  key: Byte;
  i: Integer;
  time: Longint;
begin
  for i := 0 to length(KStr) do begin
    key := Byte(Kstr[i]);
    Scan := MapVirtualKey(key, 0);
    keybd_event(key, Scan, 0, 0);
    keybd_event(key, Scan, KEYEVENTF_KEYUP, 0);
  end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var tick,tack:integer; //lokale Variablendeklaration, gilt nur in dieser Procedure
begin

tick:= GetTickCount;
tack:= GetTickCount;

while (tack-tick < 5000) do
 begin
   application.ProcessMessages; //sonst friert das Programm ein
   sleep(20);                  //sonst ist die CPU Auslastung sehr hoch
   tack:=GetTickCount;
 end;


SendKeyString('test');


end;
end.

und nochwas wichtiges: Benutz doch bitte mal die Suchfunktion. Wir haben hier sehr viele Themen schonmal besprochen und du findest in der Regel immer eine passende Antwort mit der Suchfunktion. Wenn man richtig programmieren will, muss man sich manchmal auch selbst durchbeißen...

benny1452 23. Sep 2008 15:01

Re: sendkey methode umbauen
 
ich bekomme immernoch nur die Uhrzeit+Datum angezeigt :(
Ich bin ja schon die gane zeit am versuchen das auch mal selbst zu lösen...allerdings nur bei google bis eben.
Nunja und jetzt hab ich das Problem, dass ich ja immernoch diese Zeile als Ergebnis bekomme:

15:44 23.09.2008515:42 23.09.2008

nach der funktion GetTickCount hab ich gesucht...diese scheint nicht die blöde ausgabe zu verursachen.
alles was: time heißt hab ich rausgenommen oder umbenant und nun weiß ich beim besten wille nicht was zu dem Ergebniss führt.
Mir fallen auch leider keine anhaltspunkte mehr ein nach denen ich suchen könnte...

Naja und ausserdem beshcäftige ich mich mit delphi ja erst seit heute morgen :oops:

DeddyH 23. Sep 2008 15:16

Re: sendkey methode umbauen
 
Könntest Du das hier mal testen?
Delphi-Quellcode:
uses ShellAPI;

procedure EnterText(AText: String);
var lCount    : Integer;
    lScanCode : Smallint;
    lWithAlt,
    lWithCtrl,
    lWithShift : Boolean;
begin
  for lCount := 1 To Length(AText) Do
  begin
    lScanCode := VkKeyScan(AText[lCount]);
    //Ermitteln ob Shift gedrückt wurde
    lWithShift := lScanCode and (1 shl 8) <> 0;
    //Ermitteln ob Strg gedrückt wurde
    lWithCtrl := lScanCode and (1 shl 9) <> 0;
    //Ermitteln ob Alt gedrückt wurde
    lWithAlt  := lScanCode and (1 shl 10) <> 0;

    if lWithShift then
      keybd_event(VK_SHIFT, 0, 0, 0);
    if lWithCtrl then
      keybd_event(VK_CONTROL, 0, 0, 0);
    if lWithAlt then
      keybd_event(VK_MENU, 0, 0, 0);

    keybd_event(lScanCode, 0, 0, 0);
    keybd_event(lScanCode, 0, KEYEVENTF_KEYUP, 0);

    if lWithAlt then
      keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
    if lWithCtrl then
      keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
    if lWithShift then
      keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var jetzt: Cardinal;
begin
  if ShellExecute(0,'open','notepad.exe',nil,nil,SW_SHOWNORMAL) > 32 then
    begin
      jetzt := GetTickCount;
      while (GetTickCount - jetzt) < 3000 do
        begin
          Application.ProcessMessages;
          sleep(0);
        end;
      EnterText('Hallo Welt');
    end;
end;

benny1452 23. Sep 2008 15:24

Re: sendkey methode umbauen
 
uiiuui das klappt !
Prima....sogar mit erstellter .TXT Datei :)

dankeee


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