Popełniłem błąd przy przekazywaniu uchwytu okna do PostMessage. WM_Quit jednak zadziałało.
Poniżej mój kod, który jest trochę rozbudowany jak na tak prostą operację, ale chodziło mi o zabezpieczenie się przed omyłkowym zamknięciem jakiejś innej aplikacji, która miałaby Class Name i Title takie same jak ChomikBox.
uses
...Variants, StdCtrls, ToolWin, ComCtrls, PsAPI...
// Pobranie scieżki pliku po PID
// http://stackoverflow.com/questions/4178443/get-the-full-path-from-a-pid-using-delphi
function ProcessGetPathFromPID(const PID: cardinal): string;
var
hProcess: THandle;
path: array[0..MAX_PATH - 1] of char;
begin
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PID);
if hProcess <> 0 then
try
if GetModuleFileNameEx(hProcess, 0, path, MAX_PATH) = 0 then
RaiseLastOSError;
result := path;
finally
CloseHandle(hProcess)
end
else
RaiseLastOSError;
end;
// Funkcja szuka procesu ChomikBoxa i zamyka go
// http://delphi.about.com/od/windowsshellapi/l/aa080304a.htm
function ProcessEnum(hHwnd: HWND; lParam : integer): boolean; stdcall;
var
pPid, pPid2 : DWORD;
title, className : string;
begin
if(hHwnd=NULL) then
begin
result := false;
end
else
begin
GetWindowThreadProcessId(hHwnd,pPid);
SetLength(className, 255);
SetLength(className, GetClassName(hHwnd, PChar(className), Length(className)));
SetLength(title, 255);
SetLength(title, GetWindowText(hHwnd, PChar(title), Length(title)));
// Warunek zamykający program ChomikBox. Zamykanie po title='chomikbox' czasami
// powoduje pojawienie się komunikatu o nieoczekiwanym zamknięciu aplikacji ChomikBox
If (className = 'QWidget') AND (title = 'Dodawanie plików') Then
begin
// Dla pewności sprawdzamy po scieżce pliku, czy to rzeczywiście jest ChomikBox.
If (ProcessGetPathFromPID(pPid) = 'C:\Program Files (x86)\ChomikBox\chomikbox.exe')
OR (ProcessGetPathFromPID(pPid) = 'C:\Program Files\ChomikBox\chomikbox.exe') Then
begin
//showmessage('Class Name = ' + className + '; Title = ' + title + '; HWND = ' + IntToStr(hHwnd) + '; Pid = ' + IntToStr(pPid));
If NOT PostMessage(hHwnd, WM_Quit, 0, 0) Then
MessageBox(0, PChar('Wystąpił problem przy zamykaniu ChomikBoxa. Zamknij program ręcznie i naciśnij OK.'),
PChar(naglowek), MB_ICONWARNING + MB_OK);
end;
end;
result := true;
end;
end;
procedure ProcessGet;
var
lp : integer;
begin
lp := 0;
if EnumWindows(@ProcessEnum, lp) = false then ShowMessage('Błąd: Nie można uzyskać uchwytu okna.');
end;
Jeżeli macie jakieś uwagi lub lepszy pomysł na kod, to pisać śmiało.