Registriert seit: 3. Sep 2004
4.629 Beiträge
Delphi 10.2 Tokyo Starter
|
AW: FindWindow per Handle
25. Aug 2013, 22:55
Kein Problem, dafür ist das Forum ja da. Folgende Variante sollte ab Windows 2000 funktionieren (auch ohne psapi.dll und mit Unterstützung von 64 bit Prozessen):
Delphi-Quellcode:
{$Z4}
type
_PROCESSINFOCLASS = (
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers,
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
MaxProcessInfoClass);
PROCESSINFOCLASS = _PROCESSINFOCLASS;
PROCESS_INFORMATION_CLASS = PROCESSINFOCLASS;
TProcessInfoClass = PROCESSINFOCLASS;
{$Z1}
function NtQueryInformationProcess(ProcessHandle: THandle;
ProcessInformationClass: PROCESSINFOCLASS; ProcessInformation: Pointer;
ProcessInformationLength: ULONG; ReturnLength: PULONG): LongInt; stdcall; external 'ntdll.dll';
type
PUNICODE_STRING = ^UNICODE_STRING;
{$EXTERNALSYM PUNICODE_STRING}
_UNICODE_STRING = record
Length: USHORT;
MaximumLength: USHORT;
Buffer: PWideChar;
end;
{$EXTERNALSYM _UNICODE_STRING}
UNICODE_STRING = _UNICODE_STRING;
{$EXTERNALSYM UNICODE_STRING}
PCUNICODE_STRING = ^UNICODE_STRING;
{$EXTERNALSYM PCUNICODE_STRING}
TUnicodeString = UNICODE_STRING;
PUnicodeString = PUNICODE_STRING;
procedure TForm3.Button1Click(Sender: TObject);
var
ThreadId,
ProcessId: DWord;
hProcess: THandle;
Data: Pointer;
Size: ULONG;
begin
ThreadId := GetWindowThreadProcessId(WindowHandle, ProcessId);
if (ThreadId <> 0) then
begin
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, ProcessId);
if (hProcess <> 0) and (hProcess <> INVALID_HANDLE_VALUE) then
try
NtQueryInformationProcess(hProcess, ProcessImageFileName, nil, 0, @Size);
GetMem(Data, Size);
try
if (NtQueryInformationProcess(hProcess, ProcessImageFileName, Data, Size, @Size) = 0) then
begin
Caption := ExtractFileName(PUNICODE_STRING(Data).Buffer);
end;
finally
FreeMem(Data);
end;
finally
CloseHandle(hProcess);
end;
end;
end;
Die Funktion ermittelt allerdings nur den Dateinamen und nicht den kompletten Pfad. Wenn du den ganzen Pfad haben willst, wird es für Systeme < Vista etwas komplizierter.
Alternativ vielleicht noch etwas sauberer über die TlHelp32 API:
Delphi-Quellcode:
procedure TForm3.Button1Click(Sender: TObject);
var
ThreadId,
ProcessId: DWord;
hSnapshot: THandle;
Process: TProcessEntry32;
begin
ThreadId := GetWindowThreadProcessId(WindowHandle, ProcessId);
if (ThreadId <> 0) then
begin
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, ProcessId);
if (hSnapshot <> 0) and (hSnapshot <> INVALID_HANDLE_VALUE) then
try
FillChar(Process, SizeOf(Process), #0);
Process.dwSize := SizeOf(Process);
if Process32First(hSnapshot, Process) then
repeat
if (Process.th32ProcessID = ProcessId) then
begin
Caption := StrPas(PChar(@Process.szExeFile[0]));
Break;
end;
until not Process32Next(hSnapshot, Process);
finally
CloseHandle(hSnapshot);
end;
end;
end;
Geändert von Zacherl (25. Aug 2013 um 22:59 Uhr)
|