![]() |
Text in Eingabefeld beliebiger Anwendungen ersetzen?
Wie stelle ich es am besten an in aktiven Eingabefeldern beliebiger Anwendungen nach einem bestimmten Text zu suchen und diesen automatisch zu ersetzen?
Im Prinzip soll das ganze in jedem Mailprogramm, in Word, im Notepad im IE u.s.w. funktionieren... Beispiel: Der User öffner sein Mail, wo automatisch die Signatur "###Hierhin###" eingefügt wird. Nun ersetzt mein Programm "###Hierhin###" durch einen anderen Text. |
Re: Text in Eingabefeld beliebiger Anwendungen ersetzen?
|
Re: Text in Eingabefeld beliebiger Anwendungen ersetzen?
Dieses kleine Beispiel ermittelt mit Hilfe von EnumWindows alle TopLevel Fenster. Sollte das Fenster den Klassennamen "Notepad" haben, wird das Kindfenster "Edit" gesucht. Wurde es gefunden, wird es in die TList "List" eingetragen. Mit WM_GETTEXT wird dann der Inhalt von Notepad ausgelesen. StringReplace tauscht dann "###Hierhin###" durch "Neuer Text" aus. Und WM_SETTEXT sorgt dafür, das der bearbeitete Text wieder ins Notepad Fenster gelangt. Ich denke mal, als kleiner Einstieg reicht das und wird dir bestimmt weiterhelfen.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
function EnumWindowsProc(Wnd: HWND; lParam: LPARAM): BOOL; stdcall; var ClassName: String; EditHWnd: HWND; begin SetLength(ClassName, 512); SetLength(ClassName, GetClassName(Wnd, PChar(ClassName), Length(ClassName))); if ClassName = 'Notepad' then begin EditHWnd := FindWindowEx(Wnd, 0, 'Edit', nil); if IsWindow(EditHWnd) then TList(lParam).Add(Pointer(EditHWnd)); end; Result := True; end; var List: TList; I: Integer; S: String; begin List := TList.Create; try EnumWindows(@EnumWindowsProc, LPARAM(List)); for I := 0 to List.Count - 1 do begin SetLength(S, SendMessage(HWND(List.Items[I]), WM_GETTEXTLENGTH, 0, 0) + 1); if Length(S) > 1 then begin SetLength(S, SendMessage(HWND(List.Items[I]), WM_GETTEXT, Length(S), LPARAM(PChar(S)))); S := StringReplace(S, '###Hierhin###', 'Neuer Text', [rfReplaceAll]); SendMessage(HWND(List.Items[I]), WM_SETTEXT, Length(S), LPARAM(PChar(S))); end; end; finally List.Free; end; end; |
Re: Text in Eingabefeld beliebiger Anwendungen ersetzen?
Danke, das ist natürlich ein Anfang ;) ...
Aber wäre es nicht möglich einfach im gerade aktivem Control (egal welche Anwendung!) nach einem Text zu suchen? WM_SETTEXT hat auch den unangenehmen Nebeneffekt, dass sich die Cursorposition ändert... |
Re: Text in Eingabefeld beliebiger Anwendungen ersetzen?
Zitat:
Zitat:
|
Re: Text in Eingabefeld beliebiger Anwendungen ersetzen?
Eine interessante Idee. Aber du wirst einige Hürden zu überwinden haben. Handelt es sich um ein standard Windows Edit-Controll ist es kein großes Problem, wie der Code von Sprint gezeigt hat. Word und andere Anwendungen benutzen aber selbst gebastelte Controlls. So ist das, wo du bei Word deinen Text eingibst bestimmt kein Edit-Controll. Du hast es also im Prinzip mit unendlich vielen Fensterklassen zu tun. OpenOffice wird wieder eine andere eigenen Fensterklasse benutzen usw.
@Sprint. Wenn du mit WM_GETTWEXT den Fenstertext ausliest und ihn in eine Variable deines Programmes schreibst, dann befindet sich der Text doch in einer Varaibel, die in deinem Prozess liegt. Das zeigt doch dein Quellcode? Deswegen verstehe ich deine aussage nicht so ganz. |
Re: Text in Eingabefeld beliebiger Anwendungen ersetzen?
Zitat:
|
Re: Text in Eingabefeld beliebiger Anwendungen ersetzen?
Wäre es nicht irgendwie möglich geziehlt das Control zu bekommen, welches gerade den Focus hat?
|
Re: Text in Eingabefeld beliebiger Anwendungen ersetzen?
Zitat:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var AppHWnd: HWND; ThreadId: DWORD; FocusHWnd: HWND; begin FocusHWnd := GetFocus; if not IsWindow(FocusHWnd) then begin AppHWnd := GetForegroundWindow; if AppHWnd <> Self.Handle then begin ThreadId := GetWindowThreadProcessId(AppHWnd, nil); if ThreadId <> 0 then if AttachThreadInput(GetCurrentThreadId, ThreadId, True) then begin FocusHWnd := GetFocus; AttachThreadInput(GetCurrentThreadId, ThreadId, False); end; end; end; ListBox1.ItemIndex := ListBox1.Items.Add('Das Fensterhandle $' + IntToHex(FocusHWnd, 8) + ' hat den Fokus'); end; |
Re: Text in Eingabefeld beliebiger Anwendungen ersetzen?
Also, jetzt klappt es eigentlich schon ganz gut, wenn es ein Edit oder ein Button ist... bei einigen Controls bekomme ich jedoch noch nicht einmal den Klassennamen :?
Ich hab mir jetzt erst einmal eine Funktion gebastelt, die mir onTimer1 den gerade aktiven Klassennamen und den dazu gehörenden Text in eine ListView schreibt:
Delphi-Quellcode:
Klassen wo es nicht funzt:
procedure TForm1.Timer1Timer(Sender: TObject);
var AppHWnd: HWND; ThreadId: DWORD; FocusHWnd: HWND; ClassName: string; S0, S1: string; begin Timer1.Enabled := False; FocusHWnd := GetFocus; if not IsWindow(FocusHWnd) then begin AppHWnd := GetForegroundWindow; if AppHWnd <> Self.Handle then begin ThreadId := GetWindowThreadProcessId(AppHWnd, nil); if ThreadId <> 0 then if AttachThreadInput(GetCurrentThreadId, ThreadId, True) then begin FocusHWnd := GetFocus; AttachThreadInput(GetCurrentThreadId, ThreadId, False); SetLength(ClassName, 512); SetLength(ClassName, GetClassName(FocusHWnd, PChar(ClassName), Length(ClassName))); SetLength(S0, SendMessage(FocusHWnd, WM_GETTEXTLENGTH, 0, 0) + 1); if Length(S0) > 1 then begin Application.ProcessMessages; SetLength(S0, SendMessage(FocusHWnd, WM_GETTEXT, Length(S0), LPARAM(PChar(S0)))); S1 := StringReplace(S0, '###Hierhin###', 'Neuer Text', [rfReplaceAll]); if S0 <> S1 then SendMessage(FocusHWnd, WM_SETTEXT, Length(S1), LPARAM(PChar(S1))); end; end; end; end; if (ListView1.Items.Count = 0) or (ListView1.Items[ListView1.Items.Count - 1].Caption <> IntToStr(FocusHWnd) + '[' + ClassName + ']="' + Trim(S0) + '"') then begin ListView1.Items.BeginUpdate; ListView1.Items.Add; ListView1.Items[ListView1.Items.Count - 1].Caption := IntToStr(FocusHWnd) + '[' + ClassName + ']="' + Trim(S0) + '"'; ListView1.Items[ListView1.Items.Count - 1].MakeVisible(False); ListView1.Items.EndUpdate; end; Timer1.Enabled := True; end; "_WwG" (Word XP) "TEditControl" (Delphi2005, Code) "Internet Exploerer_Server" (IE) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:30 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz