Entwickler-Ecke

Windows API - Notepad ausfüllen lassen vom Projekt


F.Art - Mo 13.07.09 02:42
Titel: Notepad ausfüllen lassen vom Projekt

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
unit main;

interface

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

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

var
  Hauptform: THauptform;

implementation

{$R *.dfm}

procedure PostKey(key: Byte);
begin
  keybd_event(key, Mapvirtualkey(key, 0), 00 );
end;

Procedure Senden(variable:string);
var
wnd:HWND;
i:integer;
begin
wnd := FindWindowEx(00nil'Unbenannt - Editor');
if wnd <> 0 then begin
   if length(variable) <> 0 then begin
      SetForegroundWindow(wnd);
      ShowWindow(wnd, 1);
      Sleep(500);
      for i := 0 to length(variable) do SendMessage(wnd, WM_CHAR, Ord(variable[i]), 0);
      PostKey(VK_RETURN);
      end;
   end;
end;

procedure THauptform.Button1Click(Sender: TObject);
var
   Windows:HWND;
begin
ShellExecute(Hauptform.Handle,'open',PChar('C:\Windows\system32\notepad.exe'),nilnil,SW_SHOWNORMAL);
sleep(500);
Senden(Edit.Text);
end;

end.


ich möchte im notepad den text im edit feld eintragen lassen.
irgend etwas mache ich falsch.
wie müsste es richtig sein?


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Mo 13.07.2009 um 18:11


jaenicke - Mo 13.07.09 04:51

Wie kommst du auf die Idee das Editorfenster könnte ein Kindfenster des Desktops sein (FindWindowEx(0, ...))? :shock:

Da das wohl auch bei dir kaum der Fall sein dürfte, versuch einmal das:

Delphi-Quelltext
1:
wnd := FindWindow(nil'Unbenannt - Editor');                    


F.Art - Mo 13.07.09 11:25

das funktioniert leider auch nicht, die taste RETURN wird übergeben, nur nicht das aus dem editfeld


Sprint - Mo 13.07.09 12:53

http://www.softgames.de/forum/viewtopic.php?t=109513#609304


ffgorcky - Mo 13.07.09 15:48

Such doch z.B. erst mal hier im Delphi-Forum:
Da findest Du dann bei den Suchbegriffen "text senden anwendung" (ohne die Hochkommas) z.B. diesen Thread:
[URL=http://www.delphi-forum.de/viewtopic.php?t=89525&highlight=text+senden+anwendung]Text in ein Feld einer externen Anwendung einfügen
[/URL]

Hilft Dir das nicht schon weiter?


Delete - Di 14.07.09 13:16

Setze den Text mit WM_SETTEXT in das Editorfenster.


F.Art - Di 14.07.09 13:51

Irgendwie blicke ich nicht so wirklich da durch.



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure PostKey(key: Byte);
begin
keybd_event(key, Mapvirtualkey(key, 0), 00 ); // was bedeuten und bewirken die 0 in dieser zeile?
end;

Procedure Senden(variable:string);
var
   Windows : HWND; // was bedeutet HWND?
         i : integer;
begin
Windows := FindWindowEx(00nil'Unbenannt - Editor');
if Windows <> 0 then begin
   if length(variable) <> 0 then begin
      SetForegroundWindow(Windows);
      ShowWindow(Windows, 1); 
      Sleep(500);
      for i := 0 to length(variable) do SendMessage(Windows, WM_CHAR, Ord(variable[i]), 0); // was bewirkt WM_CHAR und die 0 in dieser zeile?
      PostKey(VK_RETURN);
      end;
   end;
end;


ffgorcky - Di 14.07.09 16:30

Einfach nur, um noch mal an die Ausgangsfrage anzuknüpfen:
Möchtest Du denn diesen Text nur als *.txt-Datei speichern?

Dieses wäre doch auch eine Möglichkeit:
Dann könntest Du das doch einfach nur, indem Du z.B. ein Memo nimmst
[evtl. vorher die alte Datei mit MemoText.LoadFromFile('hierDeineDatei.txt') lädst]
und dort den Text reinkopierst und dann einfach nur dieses Memo wieder mit MemoText.SaveToFile('hierDeineDatei.txt') abspeicherst.

Dass die Dateiangabe mit Pfad voran passieren muss, falls sie nicht im aktuellen Arbeitsverzeichnis ist, versteht sich ja von selbst...


F.Art - Di 14.07.09 18:05

ne es soll nicht als txt gespeichert werden.
ich möchte mich mit dem bedienen von anderen tools beschäftigen und möchte lernen mit den ganze befhelne um zu gehen.


ffgorcky - Di 14.07.09 18:36

Das sieht mir doch so ziemlich nach dem gleichen Problem wie in diesem Thema [http://www.delphi-forum.de/viewtopic.php?t=56959&highlight=pastefromclipboard+fenster] aus.
- Oder findest Du da einen unterschied - außer, dass Du da die beiden Befehle "umdrehen" musst? - Also hillft Dir das nicht?


F.Art - Di 14.07.09 19:04

am besten mal schritt für schritt alles durchgehen.


Delphi-Quelltext
1:
Windows := FindWindowEx(00nil'Unbenannt - Editor');                    


mit diesem befehhl FindWindowsEx lasse ich das fenster suchen.
n8un stehen noch ein paar 0en und so in der klammer. dazu könnte ich noch erklärungen gebrauchen was der genauere sinn ist. und wie kann ich es machen, wenn er das gesuchte fenster nicth finden dann eine nachricht ausgibt?


jaenicke - Di 14.07.09 19:52

Also erstens ist es schlecht eine Variable oder so Windows zu nennen. So heißt nämlich auch eine Unit von Delphi.

Und dann ist FindWindowEx wie gesagt der falsche Befehl. Warum habe ich ja geschrieben und steht in der Dokumentation [http://msdn.microsoft.com/en-us/library/ms633500.aspx]...
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Wie kommst du auf die Idee das Editorfenster könnte ein Kindfenster des Desktops sein (FindWindowEx(0, ...))? :shock:

Da das wohl auch bei dir kaum der Fall sein dürfte, versuch einmal das:

Delphi-Quelltext
1:
wnd := FindWindow(nil'Unbenannt - Editor');                    


F.Art - Di 14.07.09 22:02


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
Procedure Senden(variable:string);
var
   Win : HWND;
     i : integer;
begin
Win := FindWindow(nil'Unbenannt - Editor');
if Win <> 0 then begin
   if length(variable) <> 0 then begin
      SetForegroundWindow(Win);
      Sleep(500);
      for i := 0 to length(variable) do SendMessage(Win, WM_GETTEXT, Ord(variable[i]), 0);
      end;
   end;
end;


hab es etwas abgeändert.
was bvedeutet das NIL bei findwindows?
und so überträt das projekt leider auch noch kein text aus dem edit in den notepad.


jaenicke - Mi 15.07.09 04:21

Nun ja, damit findest du jetzt ein Fenster mit der genannten Caption und einer beliebigen (nil) Klasse. Jetzt hast du das Fenster des Editors. Und jetzt musst du darin das Eingabefeld suchen.

Du kannst dir mit WinSpy den Code automatisch generieren lassen:
http://www.delphi-forum.de/viewtopic.php?p=124897
http://www.delphipraxis.net/post124648.html (etwas neuere Version)

user profile iconF.Art hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
SendMessage(Win, WM_GETTEXT, Ord(variable[i]), 0);                    
[...]
und so überträt das projekt leider auch noch kein text aus dem edit in den notepad.
Naja, Get Text macht wohl was? Text anfordern, genau... was du wohl meinst ist Set Text...

Und dazu solltest du dir die Dokumentation einmal anschauen, denn so benutzt du das falsch. Du musst da keine Buchstaben als Asciicodes senden...
http://msdn.microsoft.com/en-us/library/ms632644.aspx


F.Art - Do 16.07.09 23:59


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm1.Button3Click(Sender: TObject);
var
   Win   : HWND;
   i     : integer;
begin
ShellExecute(Form1.Handle,'open',PChar('C:\Windows\system32\notepad.exe'),nilnil,SW_SHOWNORMAL);
Sleep(500);
Win := FindWindow(NIL'Unbenannt - Editor');
if Win <> 0 then begin
   SetForegroundWindow(Win);
   for i := 1 to length(Edit1.Text) do
       if VkKeyScan(Edit1.Text[i])>255 then begin
          keybd_event(VK_SHIFT, 000);
          keybd_event(VkKeyScan(Edit1.Text[i]), 000);
          keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
          end else keybd_event(VkKeyScan(Edit1.Text[i]), 00, KEYEVENTF_KEYUP);
   end;
keybd_event(VkKeyScan(chr(vk_return)),0,0,keyeventf_keyup);
end;


habs nun so gemacht


jaenicke - Fr 17.07.09 05:04

Wozu das Sleep? Was, wenn es mal länger dauert, ...?
Wie wäre es richtig:
http://www.delphi-library.de/viewtopic.php?p=571423

Ja, du kannst es dir natürlich auch etwas schwerer machen und es so machen, klar. Für die Zukunft solltest du dir WinSpy vielleicht trotzdem einmal anschauen und den davon generierten Code um zu verstehen wie das eigentlich funktioniert.


ffgorcky - Fr 17.07.09 10:00

user profile iconF.Art hat folgendes geschrieben Zum zitierten Posting springen:
was bvedeutet das NIL bei findwindows?

Dazu erst mal eine (hoffentlich richtige) generelle Antwort:
Soweit ich das weiß, heißt das in C# z.B. nur Null und ist also eine Angabe, dass dieser Variable noch kein bestimmter Werk zugewiesen wurde/werden konnte - also dass sie noch nicht initialisiert wurde.

- Oder? Bin ich da jetzt gerade "auf dem Holzweg"?


jaenicke - Fr 17.07.09 17:02

Sagte ich ja:
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Nun ja, damit findest du jetzt ein Fenster mit der genannten Caption und einer beliebigen (nil) Klasse.
Um genau zu sein ist das ein Pointer. Und ein Pointer auf die Stelle 0 im Arbeitsspeicher ist eben "nix".


F.Art - So 19.07.09 13:50

das mit der funktion gefällt mir, habe es auch schon mit übernommen.
allerdings könnte ich sowas nun in richtung fensterhandle gebrauchen.

ich habe für mich zum automatisch ausfüllen der passwörter für vnc ein projekt gecodet.
sobald man denn vnc startet und die ip/host einträgt wird nach der connection ein weiteres fenster aufgebaut und genau dieses würde ich gerne auch drauf warten bis es da ist.
hat jemand da ne schöne lösung?


jaenicke - So 19.07.09 14:09

user profile iconF.Art hat folgendes geschrieben Zum zitierten Posting springen:
ich habe für mich zum automatisch ausfüllen der passwörter für vnc ein projekt gecodet.
Was ist da automatisch auszufüllen, wie wäre es ganz normal mit Kommandozeilenparametern [http://www.uvnc.com/install/cmdline.html#vncviewer] (10 Sek. Google^^)? :shock:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  HostName, Password: String;
begin
  HostName := '192.168.0.1';
  Password := 'Supergeheim :D';
  ShellExecute(Handle, 'open''c:\...\vncviewer.exe', PChar(HostName + ' -password ' + Password + ' -nostatus'), '', SW_SHOWNORMAL);


F.Art - So 19.07.09 14:14

ja LOL
hätte ich mir auch einfacher machen können.
na werde es mir jetzt auch einfacher machen mit den komandos.

aber das mit den fensterhandle würde mich trotzdem noch interessieren.


jaenicke - So 19.07.09 14:18

Eigentlich hätte ich gedacht, dass das dann direkt mit der vorher verlinkten Funktion klappt. Schließlich kommt dann vorher gar kein Fenster mehr. :gruebel: