Czasami widziałem na forum pytania, jak pobrać PID albo HWND aplikacji na podstawie nazwy plku wykonywalnego.
Poniżej prezentuje moduł, który to robi. Wystarczy poniższy kod zapisać do pliku get_hwnd_from_exename. pas i
dodać go do sekcji uses i wywołać funkcję ExeProcessToHWnd jako parametr podając .exe programu, na przykład:
var
  Opera_H : HWND;
begin
  Opera_H := ExeProcessToHWnd('opera.exe');
  ShowMessage(IntToStr(Opera_H));
// ...
end;

Poniższy kod napisałem na podstawie kodów znalezionych w google. Bardzo ważne jest aby zmienne PidNum oraz
AHandle były globalnymi czyli poza kodem samej funkcji zwracającej HWND. Inaczej funkcja zwróci błędne wartości.

Oto pełen kod modułu, który można również pobrać w postaci skompresowanej: get_hwnd_from_exename.zip (800 b)
unit get_hwnd_from_exename;
 
interface
 
uses
  Windows, SysUtils, TlHelp32;
 
function ExeProcessToHWnd(ProcessName : string) : HWND;
 
implementation
 
var
  PidNum : DWORD;
  AHandle : HWND;
 
function ExeProcessToHWnd(ProcessName : string) : HWND;
  function EnumProcess(hHwnd : HWND; lParam : integer) : boolean; stdcall;
  var
    pPid : DWORD;
  begin
    Result := (hHwnd <> 0);
    if Result = True then
    begin
      GetWindowThreadProcessId(hHwnd, pPid);
      if pPid = PidNum then
      begin
        if (GetWindowLong(hHWND, GWL_HWNDPARENT) = 0)
          and (IsWindowVisible(hHWND) or IsIconic(hHWND)) then
        begin
          AHandle := hHWND;
        end;
      end;
    end;
    Result := True;
  end;
 
  function ProcessIDFromAppname32(AppName : string) : DWORD;
  var
    SnapShot : THandle;
    processEntry : TProcessEntry32;
  begin
    Result := 0;
    AppName := AnsiUpperCase(AppName);
    SnapShot := CreateToolhelp32SnapShot(TH32CS_SNAPPROCESS, 0);
    if SnapShot <> 0 then
    try
      ProcessEntry.dwSize := SizeOf(ProcessEntry);
      if Process32First(SnapShot, ProcessEntry) then
        repeat
          if Pos(AppName, AnsiUpperCase(ExtractFilename
            (StrPas(processEntry.szExeFile)))) > 0 then
          begin
            Result := ProcessEntry.th32ProcessID;
            Break;
          end;
        until not Process32Next(SnapShot, ProcessEntry);
    finally
      CloseHandle(SnapShot);
    end;
  end;
 
begin
  PidNum := ProcessIDFromAppname32(ProcessName);
  EnumWindows(@EnumProcess, 0);
  Result := AHandle;
end;
 
end.

Kategoria: Delphi » Gotowce
4programmers.net