私はプロセスのIDを持っています。このプロセスは、メインウィンドウを持つアプリケーションです。 メインウィンドウにWM_CLOSEを送信して、このアプリケーションを終了しようとしています。 EnumWindows
を使用してメインウィンドウを検索しています。プロセスのIDだけを持っている場合、メインアプリケーションウィンドウを閉じる際の問題
私が閉じようとしているこのアプリケーションは、常に閉じないという問題があります。 マルチスレッドアプリケーションです。メモ帳とCalcは、以下に示す同じ方法を使用すると、常に閉じられます。しかし、Calc.exeの場合でも、同じウィンドウに多くのハンドルを返すので、正しく動作しているかどうかはわかりません。
スレッドがウィンドウへのハンドルを取っていて、このハンドルが何らかの形で破損している可能性はありますか?または、私はGetWindowThreadProcessId(hHwnd,pPid)
を使用してはならないかもしれませんが、コールバックには他の機能がありますか?
私は考えが尽きていて、助けてくれてありがとうと思います。ありがとう。
コードスニペット:
unit Unit22;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm22 = class(TForm)
edtprocID: TEdit;
lblEnterProcessID: TLabel;
btnCloseProcessWindow: TButton;
lblStatus: TLabel;
procedure btnCloseProcessWindowClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
THandleAndHWND = record
ProcID: THandle;
WindowHandle: HWND;
end;
var
Form22: TForm22;
var
HandleAndHWNDArray: array of THandleAndHWND;
HandeIndex, lp: Integer;
implementation
{$R *.dfm}
function EnumProcess(hHwnd: HWND; lParam : integer): boolean; stdcall;
var
pPid : DWORD;
begin
//if the returned value in null the
//callback has failed, so set to false and exit.
if (hHwnd=0) then
begin
result := false;
end else
begin
GetWindowThreadProcessId(hHwnd,pPid);
Inc(HandeIndex);
HandleAndHWNDArray[HandeIndex].ProcID := pPid;
HandleAndHWNDArray[HandeIndex].WindowHandle := hHwnd;
Result := true;
end;
end;
procedure TForm22.btnCloseProcessWindowClick(Sender: TObject);
var
ProcID: Cardinal;
i, LastError: Integer;
begin
HandeIndex := -1;
ProcID := StrToInt(edtprocID.Text);
SetLength(HandleAndHWNDArray, 3000);
EnumWindows(@EnumProcess,lp);
for i := 0 to HandeIndex do //After EnumWindows HandleIndex is above 500 despite the fact that I have like 10 openned windows max
begin //That means that EnumWindows was called 500 times?
if HandleAndHWNDArray[i].ProcID = ProcID then //search for process equal to procces ID given by the user
begin
//if we have a processID then we have a handle to its main window
if PostMessage(HandleAndHWNDArray[i].WindowHandle, WM_CLOSE, 0, 0) then
begin
lblStatus.Caption := 'message posted!';
end else
begin
LastError := GetLastError;
lblStatus.Caption := Format('Error: [%d] ' + SysErrorMessage(LastError), [LastError]);
end;
Exit;
end;
end;
end;
end.
あなたは 'TerminateProcess()'を呼び出して、それを使って終了できます! –
できません。要件は、穏やかにWM_CLOSEで閉じることです。 – Wodzu
これは動作しないようです!それが失敗すると、アプリはUIを表示しますか? –