Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Probleme beim Auslesen von Festertext (https://www.delphipraxis.net/183363-probleme-beim-auslesen-von-festertext.html)

Helmi 5. Jan 2015 17:27


Probleme beim Auslesen von Festertext
 
Hallo,

mit folgender Procedure starte ich ein Programm und lass mir dessen Handle zurückgeben:

Delphi-Quellcode:
function start_process(const FileName: String): THandle;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;

begin
  //Rückgabewert vordefinieren
  Result := 0;

  If not FileExists(FileName) then
    exit;

  //Variable mit nullen auffüllen und Größe setzen
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  StartupInfo.cb := SizeOf(TStartupInfo);

  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_HIDE;

  If CreateProcess(nil, PChar(FileName + #0), nil, nil, false, 0, nil, nil,
                    StartupInfo, ProcessInfo) then
    begin
      If WaitForInputIdle(ProcessInfo.hProcess, INFINITE) = 0 then
        Result := ProcessInfo.hProcess;
    end;
end;
Den Fenstertext lasse ich mir mit einer von den 2 nachfolgenden Proceduren ausgeben:

#1:
Delphi-Quellcode:
function WindowText(const WHandle: THandle): String;
var
  length: LongInt;
  Title : String;

begin
  Result := '';

  If WHandle <= 0 then
    exit;

  length := GetWindowTextLength(WHandle) + 1;
  SetLength(Title, length);

  GetWindowText(WHandle, PChar(Title), length);
  Result := TrimRight(Title);
end;
#2:
Delphi-Quellcode:
function WindowText(Wnd: HWND): String;

  function EnumWindowsProc(wHandle: HWND; StringList: TStringList): Bool; stdcall;
  var
     Title: array[0..255] of Char;
  begin
    Result := true;

    GetWindowText(wHandle, Title, length(Title));

    If IsWindowVisible(wHandle) then
      StringList.AddObject(String(Title), TObject(wHandle));
  end;

var
  i        : Integer;
  Window_HND: HWND;
  StringList: TStringList;

begin
  Result := '';

  If Wnd = 0 then
    exit;

  StringList := TStringList.Create;

  try
    EnumWindows(@EnumWindowsProc, Integer(StringList));

    for i := 0 to Pred(StringList.Count) do
      begin
        Window_HND := HWND(StringList.Objects[i]);

        If Window_HND = Wnd then
          begin
            Result := StringList.Strings[i];

            break;
          end;
      end;
  finally
    FreeAndNil(StringList);
  end;
end;
Ich lade insgesamt 2 Programme, speichere mir jeweils die Handles und lasse mir dann den Fenstertext ausgeben.

Bei dem 1. Programm, das nur die Haupt-Form besitzt (beide Programme sind von mir), wird von beiden Proceduren der richtige Text ausgegeben.
Beim 2. Programm, dass neben der Haupt-Form noch eine 2. Form besitzt, bekomm ich bei der 1. Procedure den Fenstertext der 2. Form (nicht den der Hauptform) und bei der 2. Procedure nur den leeren Rückgabewert der Procedure selbst (also nichts).

Wie kann ich sauber den (richtigen) Fenstertext auslesen?

[edit]
warum bei der 2. Procedure nichts rückgemeldet wird, hab ich jetzt rausgefunden:

blende ich diese If-Abfrage aus:
Delphi-Quellcode:
//    If IsWindowVisible(wHandle) then
      StringList.AddObject(String(Title), TObject(wHandle));
so erhalte ich das gleiche, wie bei der 1. Procedure - nämlich den Text der 2. Form

himitsu 5. Jan 2015 17:42

AW: Probleme beim Auslesen von Festertext
 
Wie jetzt, du lässt dir die Prozess-ID als THandle gecastet liefern und benutzt dann das THandle (HANDLE) als Fenster-Handle (HWND) und willst darüber einen Text auslesen?
Na das muß ja schief gehn.

Du hast das Prozess-Handle die Prozess-ID.
Nun kannst du via EnumWindows alle Top-Level-Fenster durchlaufen und merkst dir die Fenster, deren "Prozess-ID" (nicht das Fenster-Handle) der Prozess-ID des Programmstarts entspricht.

DeddyH 5. Jan 2015 17:45

AW: Probleme beim Auslesen von Festertext
 
Der Sinn der 2. Prozedur ist mir nicht klar, wieso erst über alle Fenster iterieren und dann mit dem gespeicherten Handle vergleichen? Wenn schon, dann würde ich doch eher EnumThreadWindows nutzen, die ThreadId sollte ja in der befüllten ProcessInformation enthalten sein. Zum eigentlichen Problem: bist Du sicher, dass Du Dir auch die richtigen Fensterhandles merkst?

Helmi 5. Jan 2015 17:50

AW: Probleme beim Auslesen von Festertext
 
ich weiss leider nicht mehr, woher ich die 2. Procedure her habe.
die 1. Procedure hab ich hieraus gebastelt.

ganz sicher bin ich nicht, ob ich das richtige Handle hab.

Wie müsste das richtigerweise aussehen?

[edit]

Uups - ich hab was übersehen:
das Handle, dass ich mir speichere wandel ich erst noch um:
Delphi-Quellcode:
function PHandle_to_WHandle(const PHandle: Cardinal): HWND;

  function EnumWindowsProc(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
   begin
     TList(lParam).Add(Pointer(hWnd));
     Result := True;
   end;

var
   i       : Integer;
   List    : TList;
   ProcessId: DWORD;

begin
  Result := 0;

  If PHandle <= 0 then
    exit;

  List := TList.Create;

  try
    If EnumWindows(@EnumWindowsProc, Integer(List)) then
      for i := 0 to Pred(List.Count) do
        begin
          If GetWindowThreadProcessId(Integer(List.Items[i]), ProcessId) > 0 then
            If GetProcessId(PHandle) = ProcessId then
              begin
                Result := HWND(List.Items[i]);

                break;
              end;
        end;
  finally
    FreeAndNil(List);
  end;
end;
Und erst mit dem Handle geh ich auf die anderen 2 Proceduren

DeddyH 5. Jan 2015 18:17

AW: Probleme beim Auslesen von Festertext
 
Ob das so nun 100%-ig richtig ist, weiß ich nicht, aber versuch es doch mal so:
Delphi-Quellcode:
function start_process(const FileName: String): DWORD;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;

begin
  //Rückgabewert vordefinieren
  Result := 0;

  If not FileExists(FileName) then
    exit;

  //Variable mit nullen auffüllen und Größe setzen
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  StartupInfo.cb := SizeOf(TStartupInfo);

  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_SHOW;

  If CreateProcess(nil, PChar(FileName + #0), nil, nil, false, 0, nil, nil,
                    StartupInfo, ProcessInfo) then
    try
      If WaitForInputIdle(ProcessInfo.hProcess, INFINITE) = 0 then
        Result := ProcessInfo.dwThreadId;
    finally
      CloseHandle(ProcessInfo.hProcess);
      CloseHandle(ProcessInfo.hThread);
    end;
end;

function EnumThreadWndProc(Wnd: HWnd; Param: lParam): BOOL; stdcall;
var
  Len: integer;
  Title: string;
begin
  Result := true;
  if IsWindowVisible(Wnd) then
    begin
      Len := GetWindowTextLength(Wnd) + 1;
      SetLength(Title, Len);
      GetWindowText(Wnd, PChar(Title), Len);
      SetLength(Title, StrLen(PChar(Title)));
      TStringList(Param).Add(Title);
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ThreadId: DWORD;
  List: TStringlist;
  i: integer;
begin
  ThreadId := start_process('C:\Windows\notepad.exe');
  if ThreadId <> 0 then
    begin
      List := TStringList.Create;
      try
        EnumThreadWindows(ThreadId, @EnumThreadWndProc, lParam(List));
        for i := 0 to List.Count - 1 do
          ShowMessage(List[i]);
      finally
        List.Free;
      end;
    end;
end;

Helmi 5. Jan 2015 18:40

AW: Probleme beim Auslesen von Festertext
 
Danke Papa, äh DeddyH :-)

schaut schon sehr vielversprechend aus

Ich hab das mal in einer Testanwendung mit meinen zwei Programmen ausprobiert
und ich hab jeweils die richtigen Texte zurückbekommen

Luckie 5. Jan 2015 19:01

AW: Probleme beim Auslesen von Festertext
 
Zitat:

Zitat von Helmi (Beitrag 1285437)
beide Programme sind von mir

Und warum baust du dann nicht eine gescheite Kommunikation zwischen deinen Programmen ein und wurschtelst stattdessen mit Fensterhandels und Text auslesen rum? Siehst ja selbst, dass das nicht richtig funktioniert.

Helmi 5. Jan 2015 19:02

AW: Probleme beim Auslesen von Festertext
 
es sind nur Testprogramme, können aber auch Nicht-von-mir-Programme sein


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