Uzyskać uchwyt do okna głownego na podstawie PID'u, poniższym kodem.
Kopiuj
unit get_hwnd_from_pid;
interface
uses
Windows;
function PidToHandle(SourcePid : DWORD) : HWND;
implementation
type
TEnumClass = class
private
TempH : HWND;
DestPid : DWORD;
function SearchForHandle(SourcePid : DWORD) : HWND;
end;
function EnumWindowsProc(AHandle : HWND; ALParam : LParam) : LongBool; stdcall;
var
Pid : DWORD;
EC : TEnumClass;
begin
Result := True;
EC := TEnumClass(ALParam);
GetWindowThreadProcessId(AHandle, Pid);
if Pid = EC.DestPid then
begin
if (GetWindowLong(AHandle, GWL_HWNDPARENT) = 0) and (IsWindowVisible(AHandle) or IsIconic(AHandle)) then
begin
EC.TempH := AHandle;
Result := False;
end;
end;
end;
function TEnumClass.SearchForHandle(SourcePid : DWORD) : HWND;
begin
DestPid := SourcePid;
EnumWindows(@EnumWindowsProc, LParam(Self));
Result := TempH;
end;
function PidToHandle(SourcePid : DWORD) : HWND;
var
EC : TEnumClass;
begin
Result := 0;
if SourcePid > 0 then
begin
EC := TEnumClass.Create;
EC.DestPid := SourcePid;
Result := EC.SearchForHandle(SourcePid);
EC.Free;
end;
end;
end.
A PID masz z pola rekordu dwProcessId
struktury ostatniego parametru przekazanego do funkcji CreateProcess
. Jeżeli jednak potrzebujesz PID koniecznie ze ShellExecute to jest troche cięzej. Powyższy kod działa z Delphi 7, jak również poniższy. Chociaż są pewnie inne metody. Zawsze można po uruchomieniu sprawdzać enumerując uchwyty jak poniżej i na podstawie PIDu sprawdzanego jak powyżej, otrzymać też nazwę procesu.
Kopiuj
unit mini_shellapi;
interface
uses
WIndows;
type
HDROP = Longint;
const
{$IFDEF MSWINDOWS}
shell32 = 'shell32.dll';
{$ENDIF}
{$IFDEF LINUX}
shell32 = 'libshell32.borland.so';
{$ENDIF}
type
PSHFileInfoA = ^TSHFileInfoA;
PSHFileInfoW = ^TSHFileInfoW;
PSHFileInfo = PSHFileInfoA;
_SHFILEINFOA = record
hIcon : HICON;
iIcon : Integer;
dwAttributes : DWORD;
szDisplayName : array[0..MAX_PATH - 1] of AnsiChar;
szTypeName : array[0..79] of AnsiChar;
end;
_SHFILEINFOW = record
hIcon : HICON;
iIcon : Integer;
dwAttributes : DWORD;
szDisplayName : array[0..MAX_PATH - 1] of WideChar;
szTypeName : array[0..79] of WideChar;
end;
_SHFILEINFO = _SHFILEINFOA;
TSHFileInfoA = _SHFILEINFOA;
TSHFileInfoW = _SHFILEINFOW;
TSHFileInfo = TSHFileInfoA;
SHFILEINFOA = _SHFILEINFOA;
SHFILEINFOW = _SHFILEINFOW;
SHFILEINFO = SHFILEINFOA;
PNotifyIconDataA = ^TNotifyIconDataA;
PNotifyIconDataW = ^TNotifyIconDataW;
PNotifyIconData = PNotifyIconDataA;
_NOTIFYICONDATAA = record
cbSize : DWORD;
Wnd : HWND;
uID : UINT;
uFlags : UINT;
uCallbackMessage : UINT;
hIcon : HICON;
szTip : array[0..63] of AnsiChar;
end;
_NOTIFYICONDATAW = record
cbSize : DWORD;
Wnd : HWND;
uID : UINT;
uFlags : UINT;
uCallbackMessage : UINT;
hIcon : HICON;
szTip : array[0..63] of WideChar;
end;
_NOTIFYICONDATA = _NOTIFYICONDATAA;
TNotifyIconDataA = _NOTIFYICONDATAA;
TNotifyIconDataW = _NOTIFYICONDATAW;
TNotifyIconData = TNotifyIconDataA;
NOTIFYICONDATAA = _NOTIFYICONDATAA;
NOTIFYICONDATAW = _NOTIFYICONDATAW;
NOTIFYICONDATA = NOTIFYICONDATAA;
PShellExecuteInfoA = ^TShellExecuteInfoA;
PShellExecuteInfoW = ^TShellExecuteInfoW;
PShellExecuteInfo = PShellExecuteInfoA;
_SHELLEXECUTEINFOA = record
cbSize : DWORD;
fMask : ULONG;
Wnd : HWND;
lpVerb : PAnsiChar;
lpFile : PAnsiChar;
lpParameters : PAnsiChar;
lpDirectory : PAnsiChar;
nShow : Integer;
hInstApp : HINST;
lpIDList : Pointer;
lpClass : PAnsiChar;
hkeyClass : HKEY;
dwHotKey : DWORD;
hIcon : THandle;
hProcess : THandle;
end;
_SHELLEXECUTEINFOW = record
cbSize : DWORD;
fMask : ULONG;
Wnd : HWND;
lpVerb : PWideChar;
lpFile : PWideChar;
lpParameters : PWideChar;
lpDirectory : PWideChar;
nShow : Integer;
hInstApp : HINST;
lpIDList : Pointer;
lpClass : PWideChar;
hkeyClass : HKEY;
dwHotKey : DWORD;
hIcon : THandle;
hProcess : THandle;
end;
_SHELLEXECUTEINFO = _SHELLEXECUTEINFOA;
TShellExecuteInfoA = _SHELLEXECUTEINFOA;
TShellExecuteInfoW = _SHELLEXECUTEINFOW;
TShellExecuteInfo = TShellExecuteInfoA;
SHELLEXECUTEINFOA = _SHELLEXECUTEINFOA;
SHELLEXECUTEINFOW = _SHELLEXECUTEINFOW;
SHELLEXECUTEINFO = SHELLEXECUTEINFOA;
type
PROCESS_BASIC_INFORMATION = packed record
Reserved1 : Pointer;
PebBaseAddress : Pointer;
Reserved2 : array[0..1] of Pointer;
UniqueProcessId : DWORD;
Reserved3 : Pointer;
end;
const
SEE_MASK_FLAG_NO_UI = $400;
SEE_MASK_NOCLOSEPROCESS = $00000040;
const
NIM_ADD = $00000000;
NIM_MODIFY = $00000001;
NIM_DELETE = $00000002;
NIF_MESSAGE = $00000001;
NIF_ICON = $00000002;
NIF_TIP = $00000004;
SHGFI_ICON = $000000100;
SHGFI_DISPLAYNAME = $000000200;
SHGFI_TYPENAME = $000000400;
SHGFI_ATTRIBUTES = $000000800;
SHGFI_ICONLOCATION = $000001000;
SHGFI_EXETYPE = $000002000;
SHGFI_SYSICONINDEX = $000004000;
SHGFI_LINKOVERLAY = $000008000;
SHGFI_SELECTED = $000010000;
SHGFI_LARGEICON = $000000000;
SHGFI_SMALLICON = $000000001;
SHGFI_OPENICON = $000000002;
SHGFI_SHELLICONSIZE = $000000004;
SHGFI_PIDL = $000000008;
SHGFI_USEFILEATTRIBUTES = $000000010;
function ShellExecAndGetPid(CommandToExec, Params : string; CmdShow : LongWord) : Cardinal;
procedure DragFinish(Drop : HDROP); stdcall;
procedure DragAcceptFiles(Wnd : HWND; Accept : BOOL); stdcall;
function DragQueryPoint(Drop : HDROP; var Point : TPoint) : BOOL; stdcall;
function DragQueryFile(Drop : HDROP; FileIndex : UINT; FileName : PChar; cb : UINT) : UINT; stdcall;
function ShellExecute(hWnd : HWND; Operation, FileName, Parameters, Directory : PChar; ShowCmd : Integer) : HINST; stdcall;
function ShellExecuteEx(lpExecInfo : PShellExecuteInfo) : BOOL; stdcall;
function Shell_NotifyIcon(dwMessage : DWORD; lpData : PNotifyIconData) : BOOL; stdcall;
function Shell_NotifyIconA(dwMessage : DWORD; lpData : PNotifyIconDataA) : BOOL; stdcall;
function Shell_NotifyIconW(dwMessage : DWORD; lpData : PNotifyIconDataW) : BOOL; stdcall;
function SHGetFileInfo(pszPath : PAnsiChar; dwFileAttributes : DWORD;
var psfi : TSHFileInfo; cbFileInfo, uFlags : UINT) : DWORD; stdcall;
function SHGetFileInfoA(pszPath : PAnsiChar; dwFileAttributes : DWORD;
var psfi : TSHFileInfoA; cbFileInfo, uFlags : UINT) : DWORD; stdcall;
function SHGetFileInfoW(pszPath : PAnsiChar; dwFileAttributes : DWORD;
var psfi : TSHFileInfoW; cbFileInfo, uFlags : UINT) : DWORD; stdcall;
procedure DragFinish; external shell32 name 'DragFinish';
function ShellExecute; external shell32 name 'ShellExecuteA';
function DragQueryFile; external shell32 name 'DragQueryFileA';
function DragQueryPoint; external shell32 name 'DragQueryPoint';
procedure DragAcceptFiles; external shell32 name 'DragAcceptFiles';
function ShellExecuteEx; external shell32 name 'ShellExecuteExA';
function Shell_NotifyIcon; external shell32 name 'Shell_NotifyIconA';
function Shell_NotifyIconA; external shell32 name 'Shell_NotifyIconA';
function Shell_NotifyIconW; external shell32 name 'Shell_NotifyIconW';
function SHGetFileInfo; external shell32 name 'SHGetFileInfoA';
function SHGetFileInfoA; external shell32 name 'SHGetFileInfoA';
function SHGetFileInfoW; external shell32 name 'SHGetFileInfoW';
function GetProcessId(Process : THandle) : DWORD; stdcall; external kernel32 name 'GetProcessId';
implementation
function NtQueryInformationProcess(hProcess : DWORD; InfoClass : Integer; ProcessInfo : Pointer; ProcessInfoLen : Integer; ReturnLen : Pointer) : Integer; stdcall; external 'ntdll.dll';
function ShellExecAndGetPid(CommandToExec, Params : string; CmdShow : LongWord) : Cardinal;
var
SHI : TShellExecuteInfo;
PBI : PROCESS_BASIC_INFORMATION;
begin
FillChar(SHI, SizeOf(SHI), 0);
SHI.cbSize := SizeOf(SHI);
SHI.fMask := SEE_MASK_FLAG_NO_UI or SEE_MASK_NOCLOSEPROCESS;
SHI.lpVerb := 'open';
SHI.lpFile := PChar(CommandToExec);
SHI.lpParameters := PChar(Params);
SHI.nShow := CmdShow;
ShellExecuteEx(@SHI);
if GetLastError = ERROR_FILE_NOT_FOUND then
begin
Result := 0;
end
else
begin
NtQueryInformationProcess(SHI.hProcess, 0, @PBI, SizeOf(PBI), nil);
Result := PBI.UniqueProcessId;
end;
end;
end.
Pełne ściezki na podstawie PIDu można ustalić na przykład tak:
Kopiuj
function ProcessFullPath(PID : DWORD) : string;
var
AHandle : THandle;
begin
Result := '';
AHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
if AHandle <> 0 then
try
SetLength(Result, MAX_PATH);
if GetModuleFileNameEx(AHandle, 0, PChar(Result), MAX_PATH) > 0 then
SetLength(Result, StrLen(PChar(Result)))
else
Result := '';
finally
CloseHandle(AHandle);
end;
end;
function ProcessFullPath64Bit(PID : DWORD) : string;
const
PROCESS_QUERY_LIMITED_INFORMATION = $1000;
var
Len : DWord;
AHandle, DllHandle : THandle;
QueryFullProcessImageNameA : function(HProcess : THandle; dwFlags : DWord; lpExeName : PAnsiChar; lpdwSize : PDWord) : Bool; stdcall;
begin
Result := '';
DllHandle := LoadLibrary('kernel32.dll');
if DllHandle > 0 then
begin
QueryFullProcessImageNameA := GetProcAddress(DllHandle, 'QueryFullProcessImageNameA');
if Assigned(QueryFullProcessImageNameA) then
begin
AHandle := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, PID);
if AHandle <> 0 then
begin
Len := MAX_PATH;
SetLength(Result, Len - 1);
QueryFullProcessImageNameA(AHandle, 0, PAnsiChar(Result), @len);
SetLength(Result, Len);
CloseHandle(AHandle);
end;
end;
FreeLibrary(DllHandle);
end;
end;
Ktoś może jeszcze Tobie tutaj lepiej doradzi. Sorry za rozpisanie się, ale chciałem jakoś podpowiedzieć rozwiązania jakie znam.