Здравствуйте господа программеры.
Назрела проблема, над которой бьюсь последние три дни.
Похожий вопрос я уже задавал, но ответа или совета я так и не получил.
Проблема вот в чем.
Пытаюсь создать список указателей всех существующих окон на данный момент в системе.
Затем на основе указателя определяю пид процесса к которому он принадлежит.
function EnumProc (Wd: HWnd; Param: LongInt): Boolean; stdcall;
Var
mProcessID,mThreadID : Dword;
Nm:Array[0..255] of Char;
Cs: Array[0..255] of Char;
Begin
GetWindowText(Wd,Nm,255);
GetClassName(Wd,Cs,255);
mThreadID:= GetWindowThreadProcessId(Wd, @mProcessID);
EnumProc := TRUE;
end;
procedure GetAllWindow;
Var
Wd : HWnd;
mProcessID,mThreadID : Dword;
begin
form1.L5.Items.Clear;
EnumWindows (@EnumProc, 0);
Wd:=FindWindow( 0, 0 );
While ( Wd <> 0 ) do
Wd:=GetNextWindow(Wd,GW_HWNDNEXT);
end;
Затем создаю список процессов в памяти ОС и определяю имя процесса и его пид. После выполнения обоих подпрограмм имеется два списка процессов. Но дело в том, что окна имеющие принадлежность например к опере имеют пид отличный от процесса оперы.
Перелопатил кучу документации включая статьи Мечты вуайериста и доку в интернете по текущей теме.
Программеры обращаюсь к тем кто работал с подобными вещами проясните что я все таки не так делаю
procedure TForm1.Button2Click(Sender: TObject);
var
ContinueLoop : BOOL;
FSnapshotHandle : THandle;
FProcessEntry32 : TProcessEntry32;
HProgramm_ID : Cardinal;
begin
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
while integer(ContinueLoop) <> 0 do
begin
HProgramm_ID := FProcessEntry32.th32ProcessID;
form1.L.Items.Add( ExtractFileName( FProcessEntry32.szExeFile ) );
form1.L1.Items.Add( inttostr( HProgramm_ID ) );
ContinueLoop := Process32Next( FSnapshotHandle, FProcessEntry32 );
end;
end;
»вопрос КС №34800« - тоже Ваш вопрос? Так я на него ответил. Вы мне письмо прислали в личную почту? Вообще-то это не слишком вежливо, у меня своих дел хватает, но ладно. Я прислал тебе программу. У меня все рааботает. Правда, термин "PID окна" я толкую как "PID процесса, которому принадлежит окно", может как-то не так трактовать надо? Если не так - то пишите по-русски, а не по-не_знаю_каковски! Если надо, повторю еще раз текст:
unit Fdialog;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, ExtCtrls, ComCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Memo2: TMemo;
Button2: TButton;
Button3: TButton;
Memo3: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
Uses mmSystem,TlHelp32,JCLMultimedia;
procedure TForm1.Button1Click(Sender: TObject);
var H,PID:cardinal;
Found:boolean;
ProcessSearch:integer;
ProcessEntry:TProcessEntry32;
begin
H:=FindWindow('TAppBuilder',nil);
Memo1.Lines.Clear;
GetWindowThreadProcessID(H,PID);
Memo1.Lines.Add(Format('Delphi''s PID method 1=%d',[PID]));
ProcessSearch:=CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS,0);
if ProcessSearch>0 then begin
ProcessEntry.dwSize:=sizeof(TProcessEntry32);
Found:=Process32First(ProcessSearch,ProcessEntry);
while Found do begin
if CompareText(ProcessEntry.szExeFile,'delphi32.exe')=0 then
Memo1.Lines.Add(Format('Delphi''s PID method 2=%d',[ProcessEntry.th32ProcessID]));
Found:=Process32Next(ProcessSearch,ProcessEntry);
end;
CloseHandle(ProcessSearch);
end;
end;
Function GetProcessFileName(PID:integer):string;
var ModuleSearch:integer;
ModuleEntry:TModuleEntry32;
begin
ModuleSearch:=CreateToolHelp32Snapshot(TH32CS_SNAPMODULE,PID);
if ModuleSearch>0 then begin
ModuleEntry.dwSize:=sizeof(TModuleEntry32);
if Module32First(ModuleSearch,ModuleEntry) then Result:=ModuleEntry.szExePath
else Result:='';
CloseHandle(ModuleSearch);
end;
end;
function EnumProc (Wd: HWnd; Param: LongInt): Boolean; stdcall;
Var
mProcessID,mThreadID : Dword;
Nm:Array[0..255] of Char;
Cs: Array[0..255] of Char;
Begin
GetWindowText(Wd,Nm,255);
GetClassName(Wd,Cs,255);
mThreadID:= GetWindowThreadProcessId(Wd,@mProcessID);
if(lstrlen(Nm)>0)and(lstrlen(Cs)>0)then Form1.Memo2.Lines.Add(Format('%s [%s] PID=%d',[StrPas(Nm),StrPas(Cs),mProcessID]));
EnumProc := TRUE;
end;
procedure GetAllWindow;
Var
Wd : HWnd;
mProcessID,mThreadID : Dword;
begin
form1.Memo2.Lines.Clear;
EnumWindows (@EnumProc, 0);
Wd:=FindWindow( 0, 0 );
While ( Wd <> 0 ) do
Wd:=GetNextWindow(Wd,GW_HWNDNEXT);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
GetAllWindow;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
ContinueLoop : BOOL;
FSnapshotHandle : THandle;
FProcessEntry32 : TProcessEntry32;
HProgramm_ID : Cardinal;
begin
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
while ContinueLoop do
begin
form1.Memo3.Lines.Add(Format('%s PID=%d',[ExtractFileName( FProcessEntry32.szExeFile ),
FProcessEntry32.th32ProcessID]));
ContinueLoop := Process32Next( FSnapshotHandle, FProcessEntry32 );
end;
end;
end.
В программе три кнопки, заполняющих три Memo списками окон, процессов и их пидами. Все работало! Что не нравится? Почему не взять мой готовый вариант???
|
|