線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4868
推到 Plurk!
推到 Facebook!

ShellExecuteEx如何得到Handle 來下WM_CLOSE

尚未結案
VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-06-25 23:45:41 IP:219.68.xxx.xxx 未訂閱
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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-06-27 18:26:29 IP:218.190.xxx.xxx 未訂閱
wrong reply  發表人 -
william
版主


發表:66
回覆:2535
積分:3048
註冊:2002-07-11

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-06-27 18:35:24 IP:218.190.xxx.xxx 未訂閱
Was wrong reply  >>
chris_shieh
高階會員


發表:46
回覆:308
積分:240
註冊:2004-04-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-06-28 11:05:12 IP:218.167.xxx.xxx 未訂閱
可改用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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-06-30 06:19:30 IP:219.68.xxx.xxx 未訂閱
引言: 可改用CreateProcess 執行程式 取得 hProcess 之後利用EnumWindows 取得 視窗HWND , 則 SendMessage(hwnd, WM_CLOSE, 0, 0) 就可以使用
謝謝您的熱心,但是 CreateProcess 必須指定程式的完整路徑! 也就是這個原因,讓我很難放棄 ShellExecuteEx 的方便性。
yl_jun
一般會員


發表:0
回覆:1
積分:0
註冊:2004-07-06

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-07-06 17:21:18 IP:61.143.xxx.xxx 未訂閱
原来如此! 学习ing!
------
delphi的兴趣很大
chris_shieh
高階會員


發表:46
回覆:308
積分:240
註冊:2004-04-26

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-12-16 11:03:00 IP:219.68.xxx.xxx 未訂閱
其實ShellExecuteEx 的ExecInfo.hProcess 它跟 CreateProcess的 PI.hProcess 是相同意義的 小弟試過也是用來可以代入PID 找 Window Handle function FindMainWindow(PID: DWORD): DWORD; 所以也是可以用來找的
系統時間:2024-09-17 10:55:47
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!