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 Inhalt von Textfeldern in externer Anwendung ändern (https://www.delphipraxis.net/106100-inhalt-von-textfeldern-externer-anwendung-aendern.html)

little_budda 5. Jan 2008 14:30


Inhalt von Textfeldern in externer Anwendung ändern
 
Hallo,

ich möchte gerne Textfelder (Edits) in einer externen Applikation ändern.
Das Handle der Applikation habe ich und den Text in dem gewünschten Edit bekomme ich auch markiert.
Aber ändern kann ich ihn nicht.

In meinem vorherigen Thread hab ich normale Einzeltasten verschickt. Also der Zugriff klappt.
Nur mit den Textfeldern da hapert es.

Für eine Idee wär ich schon dankbar.

Gruß Holger.

:gruebel:

Luckie 5. Jan 2008 14:32

Re: Inhalt von Textfeldern in externer Anwendung ändern
 
Wi wäre es mit MSDN-Library durchsuchenWM_SETTEXT?

little_budda 5. Jan 2008 14:34

Re: Inhalt von Textfeldern in externer Anwendung ändern
 
Hallo,

schon klar ich versuche es mit
Delphi-Quellcode:
procedure Tfrm_main.btn_setTextClick(Sender: TObject);
var sEditValue : string;
begin
  sEditValue := ed_text.text;

  PostMessage(extWindowsHandle, WM_SetFocus, 86, 0);
  PostMessage(extWindowsHandle, WM_SETTEXT, 0, Integer(Pchar(sEditValue))); // Text des Objektes schreiben

end;
Aber es will nicht.

Wotan89 5. Jan 2008 15:28

Re: Inhalt von Textfeldern in externer Anwendung ändern
 
Bei der Message WM_SETTEXT musst du Sendmessage verwenden! Warum weiß ich noch nicht, aber ich stand mal vor dem selben Problem. Steht auch in der MSDN-Library so drin. Dann müsste es klappen, wenn du das Handle des Edit-Fensters hast. Jedenfalls ich konnte das Edit-Fenster des Explorers ändern. Allerdings benötigst du für WM_SETTEXT keinen Fokus.

little_budda 5. Jan 2008 15:36

Re: Inhalt von Textfeldern in externer Anwendung ändern
 
Hallo,

also ich habe jetzt eine Form mit zwei Buttons.
Der eine schickt eine Taste ("b", Key 66). Das klappt. (Damit wähle ich mein Edit aus)
Der zweite schickt "willi". Das klappt nicht.

Hier der Code:
Delphi-Quellcode:
procedure Tfrm_main.btn_sendKeyClick(Sender: TObject);
begin
  iSendKeyCode := 66; // Klein B
  PostMessage (extWindowsHandle, // Handle des externen Programmes
               WM_CHAR,          // Übergabe = Keycode
               iSendKeyCode,     // KeyCode
               0                  // Vierter Parameter (frei)
              );
end;


procedure Tfrm_main.btn_setTextClick(Sender: TObject);
var sEditValue : string;
begin
  sEditValue := "willi";
  SendMessage(extWindowsHandle,          // Text des Objektes schreiben
              WM_SETTEXT,                // Übergabe = Text
              0,                         // Dritter Parameter (frei)
              Integer(Pchar(sEditValue)) // Adresse der Variablen ("willi")
              );
end;
Ich hab so keine Idee mehr ...

:gruebel:

Wotan89 5. Jan 2008 16:08

Re: Inhalt von Textfeldern in externer Anwendung ändern
 
Schreib mal bitte deinen ganzen Quelltext auf, z.B. wie du das Handle des editfeldes kriegst. Denn bei mir klappt alles einwandfrei.

little_budda 5. Jan 2008 19:40

Re: Inhalt von Textfeldern in externer Anwendung ändern
 
OK.
Hier der Code.
Delphi-Quellcode:
...

const sWinFx4Exe : string = 'WINFx4.exe';

var frm_main: Tfrm_main;
    extProcessHandle: THandle;
    extWindowsHandle: THandle;

...

function GetWindowThreadProcessId(hWnd: HWND; var dwProcessId: DWORD): DWORD; stdcall; external 'user32.dll' name 'GetWindowThreadProcessId';

function MyEnumWindowProc(AHandle: THandle; LParam: LongWord): boolean; stdcall;
var ProcessID: THandle;
begin
  ProcessID := 0;
  GetWindowThreadProcessID(AHandle, ProcessID);
  Result := not (ProcessID = LParam);
  if not Result then extWindowsHandle := AHandle;
end;

function GetWindowHandleByExeName(const AExeName: string): THandle;
var SnapShot: THandle;
    p: TProcessEntry32;
    ProcessHandle: THandle;
begin
//  Result := 0;
  extWindowsHandle := 0;
  ProcessHandle := 0;
  p.dwSize := SizeOf(p);
  SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
  try
    if Process32First(SnapShot, p) then
      repeat
      if AnsiLowerCase(AExeName) = AnsiLowerCase(p.szExeFile) then
        ProcessHandle := p.th32ProcessID;
      until (ProcessHandle <> 0) or not Process32Next(SnapShot, p);
    EnumWindows(@MyEnumWindowProc, ProcessHandle);
    Result := extWindowsHandle;
  finally
    CloseHandle(SnapShot);
  end;
end;

function GetProcessID(Exename: string): DWORD;
var
  hProcSnap: THandle;
  pe32: TProcessEntry32;
begin
  result := 0;
  hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  if hProcSnap <> INVALID_HANDLE_VALUE then
  begin
    pe32.dwSize := SizeOf(ProcessEntry32);
    if Process32First(hProcSnap, pe32) = true then
    begin
      while Process32Next(hProcSnap, pe32) = true do
      begin
        if pos(Exename, pe32.szExeFile) <> 0 then
          result := pe32.th32ProcessID;
      end;
    end;
    CloseHandle(hProcSnap);
  end;
end;


function GetProcessHandleFromID(ID: DWORD): THandle;
begin
  result := OpenProcess(SYNCHRONIZE, False, ID);
  CloseHandle(result);
end;


procedure Tfrm_main.Beenden1Click(Sender: TObject);
begin
  close;
end;

procedure Tfrm_main.btn_getHandleClick(Sender: TObject);
begin
  extProcessHandle := GetProcessHandleFromID(GetProcessID(sWinFx4Exe));
  extWindowsHandle := GetWindowHandleByExeName(sWinFx4Exe);

  if ((extProcessHandle = 0) or (extWindowsHandle = 0)) then
    begin
      Label1.Caption := 'Fx4 läuft nicht';
      btn_sendKey.enabled := false;
    end
  else
    begin
      Label1.Caption := 'Fx4 läuft';
      btn_sendKey.enabled := true;
    end;
  Application.HandleMessage;
end;


procedure Tfrm_main.btn_sendKeyClick(Sender: TObject);
begin
  iSendKeyCode := strtoint(ed_keyCode.text);

  PostMessage (extWindowsHandle, // Handle des externen Programmes
               WM_CHAR,          // Übergabe = Keycode
               iSendKeyCode,     // KeyCode
               0                  // Dritter Parameter
              );
end;


procedure Tfrm_main.btn_setTextClick(Sender: TObject);
var sEditValue : string;
    Buffer    : array of Char;
begin
  sEditValue := ed_text.text;

  SendMessage(extWindowsHandle, WM_SETTEXT, 0, Integer(Pchar(sEditValue))); // Text des Objektes schreiben
end;
Wie zu sehen gibt es drei Buttons
1. btn_getHandle : Hier hole ich das Handle der Anwendung
2. btn_getHandle : Hier schicke ich Tastaturcodes
Mit 80 (p), 84 (t), 52(4) und 66(b) wird mein Edit gewählt und der Text ist dann automatisch markiert.
3. btn_sendKey : Hier versuche ich den Text zu ändern

Hoffe das hilft weiter.

:?

Gruß Holger.

Wotan89 5. Jan 2008 20:07

Re: Inhalt von Textfeldern in externer Anwendung ändern
 
Dein Problem ist, dass du zwar das Handle des Hauptfensters hast, aber nicht das Handle des Editfeldes. Du kannst von Glück reden, dass deine Tastatureingabe an die richtige Stelle kommt. Das Edit-Feld ist ein Child-Window der externen Anwendung, dadurch musst du mit FindWindowEx() an das Handle heran:
Delphi-Quellcode:
Edithandle:=FindWindowEx(extWindowsHandle,0,'Edit',nil)
Allerdings funktioniert das nur, wenn das Edit-Feld das "Hauptfenster" als Parent hat. Mit EnumChildWindows kannst du alle Child-Windows auflisten, welche dein Hauptfenster als Parent haben. Berichtigt mich, wenn ich was falsches sage, da ich mich auch erst seit geestern damit auseinandergesetzt habe. Die Messages schickst du dann an das Edit-Feld. Wenn das Edit-Feld nicht den Klassennamen "Edit" hat, kannst du mit der Funktion GetClassName den Klassennamen des Chilswindows herauskriegen. Außerdem wozu brauchst du das Handle des externen Prozesses?


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