Entwickler-Ecke

Windows API - Text übergeben


Schakal - Mo 01.12.03 20:46
Titel: Text übergeben
ich weiss zwar nicht ob das jetzt in das Thema Dateizugriff passt, aber ich versuchs ma :D
Also ich hab ein programm, da kann ich einen Text reinschreiben. und wenn ich jetzt auf OK klicke, soll der dsa dem Notepad übergeben, also beim NotePad reinschreiben. Wie geht das genau? Ich vermute mal mit hooks, aber ich raff das noch ned so ganz.

Moderiert von user profile iconTino: Topic verschoben.


Delete - Mo 01.12.03 20:51

Ndein, ohne Hooks. Mit Suche in: Delphi-Forum, Delphi-Library FINDEWINDOW das Notepad Fenster suchen. Mit Suche in: Delphi-Forum, Delphi-Library FINDWINDOWEX das Edit suchen und dann mit der Nachricht Suche in: Delphi-Forum, Delphi-Library WM_SETTEXT reinschreiben.


Schakal - Di 02.12.03 14:00

so ich habs ma geschafft. ich kann ohne probleme reinschreiben. aber wenn ich jetzt z.B. im Notepad unter schriftart gehe und dort im ersten editfeld was ändern will, gehts nicht. hier mal de quellcode, wo liegt hier der fehler?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button1Click(Sender: TObject);
var s : string;
wnd : Hwnd;
i : integer;
begin
  wnd := FindWindow('Notepad', nil);
  if wnd <> 0 then
  begin
    wnd := FindWindowEx(Form1.Handle, 0, '#32770', nil);
    wnd := FindWindowEx(Form1.Handle, 0, 'Edit', '1');
    s := 'Hello';
    for i := 1 to Length(s) do
    SendMessage(wnd, WM_CHAR, Word(s[i]), 0);
  end;
end;


Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt.


ErnestoChe - Di 02.12.03 15:01

Hi,

2 Dinge, die mir auffallen:

Wieso übergibst du FindWindowEx das Handle deiner Form? Du solltest hier das Handle von Notepad übergeben, welches du mit FindWindow ermittelst. Und wieso WM_CHAR? Benutz doch WM_SETTEXT, wie Luckie schon sagte. Dann brauchst du auch keine Schleife.

MFG

- Ernesto -


Schakal - Do 04.12.03 17:34

ich schaffs einfach nicht auf ein programm zu zugreifen. notepad ist kein problem, aber ein anderes schaffe ich nicht.
ich will mal das programm zeigen auf das ich zugreifen will.

user defined image
user defined image
user defined image
user defined image

das sind die einzelnen fenster
bei bild1 mach ich dclick auf die gelbe fläche
dann öffnet sich bild2
dort klick ich auf die scriptbox rechts und dan kommt bild3
und dann öffnet sich bild3, wo ich auf message klicke
dann öffnet sich bild4, dort, in dieses memofeld will ich den text übergeben.

wie mach ich das? muss ich alle fenster hier handeln? wie geht das?


Delete - Do 04.12.03 19:19

Sieht aus, als wenn das Memo kein direktes Kind vom Fenster wäre. Das scheint noch auf irgendetwas draufzuliegen. da musst du wohl mit EnumChildWindows rekursiv alle Kindfenster durchgehen bis du das Memo gefunden hast.


matze - Do 04.12.03 19:45

du kannst dir ja mal mit solchen proggis wie X-Spy anscheuen wie das memo heisst!


Schakal - Do 04.12.03 21:13

jo aber was ich ned raff ist, welche fenster muss ich hier handeln?
muss ich mit findwindow nur das erste? und dann den rest mit findwindowex oder wie geht das?
kann mir wer ned helfen, mit bissl quellcode. kenn enumchildwindows ned


Tino - Fr 05.12.03 10:23

Schakal hat folgendes geschrieben:
kenn enumchildwindows ned

-> Suche in: Delphi-Forum, Delphi-Library ENUMCHILDWINDOWS Da gibt es auch einige Beispiele!

Gruß
Tino


Schakal - Sa 06.12.03 18:43

:evil: :evil:
ich raff das enumchildwindows immer noch ned :D
also kann mir mal etwas nen bissl genauer helfen?

was muss ich den nun genau tun?
zuerst handle zum ersten fenster udn nachher einfach enumchildwindows oder was, wie ???


toms - Sa 06.12.03 18:50

Zitat:
bei bild1 mach ich dclick auf die gelbe fläche
dann öffnet sich bild2
dort klick ich auf die scriptbox rechts und dan kommt bild3
und dann öffnet sich bild3, wo ich auf message klicke


Klickst du oder muss dein Programm die Klicks simulieren?

Zitat:
was muss ich den nun genau tun?
zuerst handle zum ersten fenster udn nachher einfach enumchildwindows oder was, wie ???


Ist das "Message" Fenster ein einzelnes Fenster oder Teil einer MDI
Anwendung?
Sieht zwar so aus, als ob es ein einzelnes Fenster wäre.
Dann ermittelst du das Handle vom Fenster "Message" und
mit FindWindowEx das Handle des Memos.


Schakal - Sa 06.12.03 18:53

Zitat:
Klickst du oder muss dein Programm die Klicks simulieren?

ich erkläre bei den bildern wie ich zu den einzelnen fenster komme, ich klicke also selber.

Zitat:
Ist das "Message" Fenster ein einzelnes Fenster oder Teil einer MDI
Anwendung?

das ist teil der anwendung oder? sonst würd man in der taskleiste sehen oder?


toms - Sa 06.12.03 18:58

Zitat:
das ist teil der anwendung oder? sonst würd man in der taskleiste sehen oder?


Nicht zwingend.


Führe mal diesen Code aus.
Wenn die Zahl grösser als 0 ist, dann hast du das Handle
zum 'Message' Fenster erhalten.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  hwndFensterMsg: HWND;
begin
  hwndFensterMsg := FindWindow(nil, 'Message');
  ShowMessage(IntToStr(hwndFensterMsg));
end;


Schakal - Sa 06.12.03 19:06

ok die zahl ist grösser als 0
das heisst also ich hab das handle
das programm ist nur, wenn man jetzt die sprache von dem programm wechselt, dann steht da statt "Message" "Mitteilung" kann man das nicht irgendwie machen das er es trotzdem handlet.

kann ich jetzt mit findwindowex auf das memo handlen? das memo sitzt eben auf nem tabcontrol oder so.

edit:
habs gelöst mit klassennamen, tnx


toms - Sa 06.12.03 19:28

Zitat:
edit:
habs gelöst mit klassennamen, tnx


...auch das FindWindowEx Problem?


Schakal - Sa 06.12.03 21:39

joa hab einfach zuerst mit findwindowex die tabcontrol und dan mit findwindowex das memo, und das ging :D


Schakal - Sa 06.12.03 22:27

hmm, neues problem :D
wenn ich mehrere TabControl habe, und FindWindowEx 'TTabControl' mache, wie sag ich ihm dann welche genau er nehmen soll? sind schliesslich 3 stück da :D und ich brauch die 2te :D


toms - So 07.12.03 01:00

Hi!

Habe dafür eine Funktion FindControlByNumber geschrieben.
Ihr kannst du das ParentFenster übergeben und den Klassennamen
des zu suchenden Controls.
Falls mehrere Controls der gleichen Klasse vorhanden sind,
kann man noch den Parameter ControlNr angeben.



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:
function FindControlByNumber(hApp: HWND; ControlClassName: string; ControlNr: Word = 1): HWND;
var
  i: Word;
  hControl: HWND;
begin
  Result := 0;
  if IsWindow(hApp) then
  begin
    Dec(ControlNr);
    hControl := 0;
    for i := 0 to ControlNr do
    begin
      hControl := FindWindowEx(hApp, hControl, PChar(ControlClassName), nil);
      if hControl = 0 then
        Exit;
    end;
  end;
  Result := hControl;
end;


// Beispiel: in einem Fenster nach dem 2. TTabControl suchen
// und verstecken.

procedure TForm1.Button1Click(Sender: TObject);
var
  hApp, hControl: HWND;
begin
  hApp := FindWindow('Klassenname_eines_Fensters','Evtl_Titel_eines_Fensters_oder_NIL');
  hApp := Handle;
  hControl := FindControlByNumber(hApp, 'TTabControl', 2);
  ShowWindow(hControl, SW_HIDE);
end;


Schakal - So 07.12.03 01:35

hey das funzt sogar :D
nur kommt da schon das nächste problem :D


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure TForm1.BitBtn1Click(Sender: TObject);
var Fenster: HWND;
    result : integer;
begin
  Fenster := FindWindow('TFormEDEvent', nil);
  ShowMessage(IntToStr(Fenster));

  if Fenster <> 0 then
  begin
    Fenster := FindWindowEx(Fenster, 0, 'TTabControl', nil);
    ShowMessage(IntToStr(Fenster));
    Fenster := FindWindowEx(Fenster, 0, 'TTabControl', nil);
    ShowMessage(IntToStr(Fenster));
    Fenster := FindControlByNumber(Fenster, 'TFakeGroupBox', 2);
    ShowMessage(IntToStr(Fenster));
    Fenster := FindWindowEx(Fenster, 0, 'TScriptListBox', nil); // <-----
    Fenster := Handle;
    Result := SendMessage(Fenster, LB_GETCOUNT, 0, 0);
    ShowMessage(IntToStr(Fenster));
    ShowMessage(IntToStr(result));
  end;

das is ja der code
bis dort wo ich den pfeil hingezeichnet habe funzt alles, also zahl ist immer über 0, was mich annehmen lässt das ich das handle habe. aber das mit dem zählen der einträge in der listbox geht ned, gibt miri mmer 0 an.


toms - So 07.12.03 02:18

Zitat:
das mit dem zählen der einträge in der listbox geht ned, gibt miri mmer 0 an.


Vielleicht ist es ja gar keine ListBox, sondern eine TListView oder
ein anderes Control!?!
(Auch wenn der Name 'TScriptListBox' lautet)


Schakal - So 07.12.03 21:14

auf Bild2 (weiter oben) sieht man die box die ich meine auf der rechten seite.
wie kann ich den herausfindne ob es vielelicht ne listview ist?
kann ich die dann auch extrahieren wie ne listbox?


Schakal - Di 09.12.03 09:43

*push*
öhm.. hilfe :D


Schakal - Do 11.12.03 13:27

also ich hab mal im quellcode des programmes etwas herumgestöbert und hab herausgefunden das die TScriptListBox doch eine ListBox ist, dennoch kann ich ncihts daraus extrahieren mit dem code weiter oben.
fehlt da etwas oder ist die listbox vielleicht geschützt?