Autor Beitrag
Knodelpa
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Mi 15.12.04 16:11 
Hallo,
wie kann ich ermitteln welches Programm im Vordergrund ist, demnach den Focus hat :?:

Vielen Dank
Gruß Paul


Moderiert von user profile iconKlabautermann: Topic aus CLX / Delphi Language (Object-Pascal) verschoben am Do 16.12.2004 um 12:52
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Mi 15.12.04 23:43 

_________________
Ciao, Sprint.
Knodelpa Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Do 16.12.04 11:26 
Danke Sprint,
sobald ich dazu komme probiere ich es aus. Ich habe noch eine Frage:
Wie bekomme ich Infos wie das Fenster, bzw. das Programm heisst. Hast
du vielleicht ein Beispiel ? Wäre toll :-)

Viele Grüße
Paul
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Do 16.12.04 13:03 
Knodelpa hat folgendes geschrieben:
Wie bekomme ich Infos wie das Fenster, bzw. das Programm heisst. Hast
du vielleicht ein Beispiel?

Du holst dir mit GetForegroundWindow das Fensterhandle, das gerade aktiv ist. Mit GetWindowThreadProcessId ermittelst du den Prozess, der das Fenster erstellt hat.
Jetzt hast du schon mal die ProcessId. Du kannst nun mit OpenProcess und GetModuleFileNameEx auf Win2k & XP Rechnern den vollständigen Namen ermitteln.

ausblenden volle Höhe 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:
const
  S_MSG = 'Fenster: %d' + #13#10 + 'Titel: %s' + #13#10 + 'Dateiname: %s';
var
  AppHWnd: HWND;
  Title: String;
  ProcessId: DWORD;
  ProcessHandle: THandle;
  FileName: String;
begin

  // Fenster ermitteln das im Vordergrund liegt
  AppHWnd := GetForegroundWindow;

  if IsWindow(AppHWnd) then
  begin
    // Fenstertext auslesen
    SetLength(Title, GetWindowTextLength(AppHWnd) + 1);
    SetLength(Title, GetWindowText(AppHWnd, PChar(Title), Length(Title)));

    // Prozess ermitteln, der das Vordergrundfenster erstellt hat
    if GetWindowThreadProcessId(AppHWnd, ProcessId) <> 0 then
      if ProcessId <> 0 then
      begin
        ProcessHandle := OpenProcess(PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, False, ProcessId);
        if ProcessHandle <> 0 then
        begin
          SetLength(FileName, MAX_PATH + 1);
          SetLength(FileName, GetModuleFileNameEx(ProcessHandle, 0, PChar(FileName), Length(FileName)));
          CloseHandle(ProcessHandle);
        end;
      end;
  end;

  ShowMessage(Format(S_MSG, [AppHWnd, Title, FileName]));


Das Problem ist nur, das du genügend Rechte haben muss, um ein ProcessHandle zu bekommen. Das bedeutet, dass das kein 100%ig sicherer Weg ist. Sollte auch nur ein Beispiel sein.
Auf Win9x Rechnern würde ich CreateToolhelp32Snapshot, Process32First & Process32Next nutzen.

ausblenden volle Höhe 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:
const
  S_MSG = 'Fenster: %d' + #13#10 + 'Titel: %s' + #13#10 + 'Dateiname: %s';
var
  AppHWnd: HWND;
  Title: String;
  ProcessId: DWORD;
  ProcessSnap: THandle;
  ProcessEntry: TProcessEntry32;
  FileName: String;
begin

  // Fenster ermitteln das im Vordergrund liegt
  AppHWnd := GetForegroundWindow;

  if IsWindow(AppHWnd) then
  begin
    // Fenstertext auslesen
    SetLength(Title, GetWindowTextLength(AppHWnd) + 1);
    SetLength(Title, GetWindowText(AppHWnd, PChar(Title), Length(Title)));

    // Prozess ermitteln, der das Vordergrundfenster erstellt hat
    if GetWindowThreadProcessId(AppHWnd, ProcessId) <> 0 then
      if ProcessId <> 0 then
      begin
        ProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if ProcessSnap <> INVALID_HANDLE_VALUE then
        begin
          ProcessEntry.dwSize := SizeOf(TProcessEntry32);
          if Process32First(ProcessSnap, ProcessEntry) then
          begin
            repeat
              if ProcessId = ProcessEntry.th32ProcessID then
              begin
                FileName := ProcessEntry.szExeFile;
                Break;
              end;
            until (not Process32Next(ProcessSnap, ProcessEntry));
          end;
          CloseHandle(ProcessSnap);
        end;
      end;
  end;

  ShowMessage(Format(S_MSG, [AppHWnd, Title, FileName]));


Das Beispiel kannst du zwar auch unter Win2k & WinXP benutzen, aber szExeFile beinhaltet nur den Namen der Datei. Unter Win9x steht dort der vollständige Pfad mit Dateinamen drin.

_________________
Ciao, Sprint.
Knodelpa Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Fr 17.12.04 17:56 
Hallo Sprint,

das Programm lässt sich bei mir (Delphi5) nicht compilieren !!??

GetWindowThreadProcessId(AppHWnd, ProcessId)

führt zu Fehler

[Fehler] Unit1.pas(51): Inkompatible Typen: 'Cardinal' und 'Pointer' :?: :?:

Kannst du mir noch mal helfen oder das komplette Programm schicken ??

Gruß Paul
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Fr 17.12.04 18:02 
Knodelpa hat folgendes geschrieben:
[Fehler] Unit1.pas(51): Inkompatible Typen: 'Cardinal' und 'Pointer'


Dann musst du...
ausblenden Delphi-Quelltext
1:
GetWindowThreadProcessId(AppHWnd, ProcessId)					


zu...
ausblenden Delphi-Quelltext
1:
GetWindowThreadProcessId(AppHWnd, @ProcessId)					


...umschreiben.

_________________
Ciao, Sprint.
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Fr 17.12.04 18:12 
@Sprint: GetWindowText/GetWindowTextLength sollte man nicht verwenden, sondern lieber direkt die WM_GETTEXT/WM_GETTEXTLENGTH-Messages schicken:
PSDK hat folgendes geschrieben:
To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead of calling GetWindowText.

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Fr 17.12.04 18:24 
Motzi hat folgendes geschrieben:
GetWindowText/GetWindowTextLength sollte man nicht verwenden, sondern lieber direkt die WM_GETTEXT/WM_GETTEXTLENGTH-Messages schicken

Hatte irgendwo schon mal den Hinweis gelesen. GetWindowText hat bei Form noch nie versagt bzw. ist mir bis jetzt noch nie aufgefallen. GetWindowText versagt bei Password-Edit's ab Windows 2000 total. Das muss man schon WM_GETTEXT nehmen.

Wenn du jetzt ein Beispiel für Formen hast, wo GetWindowText nicht funktioniert, dann wäre ich dafür dankbar. :)

_________________
Ciao, Sprint.
Knodelpa Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Fr 17.12.04 18:50 
Hallo Sprint,

vielen Dank. Genau dies habe ich gesucht. Jetzt steht meinem Tatendrang nichts
mehr im Weg. :D :D :wink:
Knodelpa Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Sa 25.12.04 20:40 
Hallo Sprint,
ich brauche nochmal deine Hilfe. Da ich nicht möchte, dass mein Programm beendet werden kann habe ich das ganze in eine Serviceanwendung verpackt. Leider funktioniert dein Beispiel als Serviceanwendung nicht :-( Solange ich mich noch in der Delphi Enwicklung befinde funktioniert es noch. Als Dienst ist AppHWnd immer 0.

Ich bitte dich nochmals um Hilfe.

Gruß Paul
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Sa 25.12.04 21:21 
Knodelpa hat folgendes geschrieben:
Leider funktioniert dein Beispiel als Serviceanwendung nicht

Schau mal in die Hilfe unter TService, Interactive.

_________________
Ciao, Sprint.
Knodelpa Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: Sa 25.12.04 21:38 
Hallo Sprint,

Volltreffer. Sieht gut aus :D :D :D