ShellExecuteEx如何得到Handle 來下WM_CLOSE |
尚未結案
|
VICSYS
初階會員 發表:21 回覆:64 積分:32 註冊:2002-10-10 發送簡訊給我 |
procedure TForm1.OpenClick(Sender: TObject);
var
ExecInfo: SHELLEXECUTEINFO;
APath: array [0..MAX_PATH] of Char;
begin
FillMemory(@ExecInfo,sizeof(SHELLEXECUTEINFO),0);
ExecInfo.cbSize := sizeof(SHELLEXECUTEINFO);
ExecInfo.fMask:=SEE_MASK_NOCLOSEPROCESS;
ExecInfo.Wnd:= 0;
ExecInfo.lpFile := 'Notepad.exe';
ExecInfo.nShow := SW_SHOWNORMAL;
ShellExecuteEx(@ExecInfo);
fLastProcess:= ExecInfo.hProcess;
GetModuleFileNameEx(FLastProcess, 0, @APath[0], SizeOf(APath));
fFilename:= StrPas(APath);
end; procedure TForm1.CloseClick(Sender: TObject);
var
ExitCode:DWORD;
begin
if fLastProcess <> 0 then
begin
GetExitCodeProcess(FLastProcess,ExitCode);
if ExitCode =STILL_ACTIVE then
begin
TerminateProcess(FLastProcess,0);
FLastProcess:= 0;
end;
end;
end; 由於 ShellExecuteEx 得到的結果 fLastProcess
這時下 TerminateProcess 沒有問題, 但是不想用 TerminateProcess! 這個是強制關掉吧!
我想用 PostMessage(wnd, WM_CLOSE, 0, 0), 那麼如何由 ExecInfo.hProcess 得到 wnd ??
這個例子 也許可是用 fFilename 來得到 Notepad.exe 的執行檔名, 然後關閉 Notepad.exe 所有程序 procedure TForm1.CloseFielNameClick(Sender: TObject);
var
handle, AHandle:THandle;
lppe:TProcessEntry32;
lpExitCode: DWORD;
t: Boolean; procedure Check;
function EnumFunc(Wnd:HWND; lp:LPARAM):Boolean; stdcall;
var
dwID:DWORD;
begin
GetWindowThreadProcessId(WND, dwID);
if dwID = lp then
begin
SetForegroundWindow(Wnd);
PostMessage(wnd, WM_CLOSE, 0, 0);
end;
Result:= TRUE ;
end;
begin
if AnsiSameStr(lppe.szExeFile , 'Notepad.exe') then
begin
AHandle:= OpenProcess(PROCESS_TERMINATE or PROCESS_QUERY_INFORMATION,FALSE, lppe.th32ProcessID);
if (AHandle <> 0) and GetExitCodeProcess(AHandle, lpExitCode) then
EnumWindows(@EnumFunc,lppe.th32ProcessID);
end;
end;
begin
handle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
try
if handle > 0 then
begin
lppe.dwSize := sizeOf(ProcessEntry32);
if process32first(handle,lppe) then
begin
check;
while process32next(handle,lppe) do
check;
end;
finally
closeHandle(handle);
end;
end; 可是這又不是我要的, 若是 notepad.exe 而使用者可能同時執行多個 notepad.exe...上述的方法會
關閉所有 notepad.exe ?? 我只要關掉由 ShellExecuteEx 關啟的那一個 Notepad. 但是不可強制關閉,
至少要詢問使用者是否存檔! 發表人 - VICSYS 於 2004/06/25 23:54:17 發表人 - VICSYS 於 2004/06/25 23:59:08
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
chris_shieh
高階會員 發表:46 回覆:308 積分:240 註冊:2004-04-26 發送簡訊給我 |
可改用CreateProcess 執行程式 取得 hProcess 之後利用EnumWindows 取得 視窗HWND , 則 SendMessage(hwnd, WM_CLOSE, 0, 0) 就可以使用 function TfmMain.PlayFlashExe(Exe: string): integer;
type
PEnumInfo = ^TEnumInfo;
TEnumInfo = record
ProcessID: DWORD;
HWND: THandle;
end; function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
var
PID: DWORD;
begin
GetWindowThreadProcessID(Wnd, @PID);
Result := (PID <> EI.ProcessID) or
(not IsWindowVisible(WND)) or
(not IsWindowEnabled(WND)); if not result then EI.HWND := WND;
end; function FindMainWindow(PID: DWORD): DWORD;
var
EI: TEnumInfo;
begin
EI.ProcessID := PID;
EI.HWND := 0;
EnumWindows(@EnumWindowsProc, Integer(@EI));
Result := EI.HWND;
end;
var
SI: TStartupInfo;
PI: TProcessInformation;
twnd:integer;
begin
ZeroMemory(@SI, SizeOf(SI));
ZeroMemory(@PI, SizeOf(PI));
SI.cb := SizeOf(SI);
if CreateProcess(nil, PChar(Exe), nil, nil, FALSE, 0 ,nil,nil, SI, PI) then
begin
WaitForInputIdle(PI.hProcess, INFINITE);
repeat
twnd:=FindMainWindow(PI.dwProcessID);
until twnd>0;
Result := twnd;
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
end;
end;
|
VICSYS
初階會員 發表:21 回覆:64 積分:32 註冊:2002-10-10 發送簡訊給我 |
|
yl_jun
一般會員 發表:0 回覆:1 積分:0 註冊:2004-07-06 發送簡訊給我 |
|
chris_shieh
高階會員 發表:46 回覆:308 積分:240 註冊:2004-04-26 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |