如何关闭用SHELLEXECUTE打开的外部程序?

g58521547 2004-12-14 12:33:31
我在用SHELLEXECUTE打开一个外部程序(程序是别人写的),并且把句柄保存在全局变量里了,我想在我自己的主程序关闭时候,关闭外部程序,使用了SENDMESSAGE(AHANDLE,WM_CLOSE,0,0);
(外部程序不止一个,并且无法预先知道程序的标题,)
在线等待................一旦解决,马上给分!!!分不够再加!
...全文
608 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
g58521547 2004-12-15
  • 打赏
  • 举报
回复
谢谢,各位的关注,现在接帖!
g58521547 2004-12-14
  • 打赏
  • 举报
回复
我现在头都大了,郁闷啊。搞不顶
g961681 2004-12-14
  • 打赏
  • 举报
回复
学习中!
sunjunfeng4 2004-12-14
  • 打赏
  • 举报
回复
关键是怎么获得句柄 那个FINDWINDOW函数查找得很不精确 第有,不知道别人的标题,用类名,得到句丙就不一定是自己想要的
g58521547 2004-12-14
  • 打赏
  • 举报
回复
Kevin_Lmx(繁华阅尽):
我用的是这样的SendMessage(strtoint(exeList.Strings[i]),WM_Close,0,0);
其中EXELIST是TSTRINGLIST,里面保存了我打开外部程序是获得 的句柄.
因为外部可执行文件不是我写的,所以我没有办法知道标题,我想我这种情况只能用句柄了.
再问一下,EXE文件的窗体类名如何确定?
Kevin_Lmx 2004-12-14
  • 打赏
  • 举报
回复
首先你要用FindWindow找到该窗体的句柄
findWindow(ClassName,Title):Handle;
ClassName是那个窗口的类名,参数可以用Spy++得到,而Title是那个窗口的标题。两个只要找到一个就可以,另一个置nil。
得到了Handle后就调用SendMessage关闭它。
写法:
SENDMESSAGE(findWindow(PChar(窗体类名),PChar(窗体标题)),WM_CLOSE,0,0);
g58521547 2004-12-14
  • 打赏
  • 举报
回复
补充一下,调用SENDMESSAGE()之后,自己的主窗口关闭了,但是外部程序没有反应啊。
Kevin_Lmx 2004-12-14
  • 打赏
  • 举报
回复
CreateProcess可以返回ProcessID,通过它去找主进程。
g58521547 2004-12-14
  • 打赏
  • 举报
回复
就是说用SHELLEXECUTE()没有办法得到程序的句柄的了?
如果用CREATEPROCESS()?有没有比较详细的参数中文解释以及简明例子啊?
ghchen 2004-12-14
  • 打赏
  • 举报
回复
同意楼上的
Kevin_Lmx 2004-12-14
  • 打赏
  • 举报
回复
ShellExecute返回的不是句柄那。你需要用CreateProcess来打开外部程序,然后得到这个Process的Handle,再去找它的主Form的Handle。
我这有段代码,你试试理解一下。
========================================================
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;


procedure TForm1.Button1Click(Sender: TObject);
var
SI : TStartupInfo;
PI : TProcessInformation;
H : THandle;
S : String;
begin
ZeroMemory(@SI, SizeOf(SI));
ZeroMemory(@PI, SizeOf(PI));
SI.cb := SizeOf(SI);
if CreateProcess(nil,'CALC.EXE', nil, nil, FALSE, 0 ,nil,nil, SI, PI) then
begin
//注意!
WaitForInputIdle(PI.hProcess, INFINITE);
H := FindMainWindow(PI.dwProcessID);
if H > 0 then
begin
SetLength(S, 255);
GetWindowText(H, PChar(S), 255);
SetLength(S, StrLen(PChar(S)));
ShowMessage(S);
end;

CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
end;
end;

end.
g58521547 2004-12-14
  • 打赏
  • 举报
回复
对啊,如果我得到句柄,我想SENDMESSAGE()就可以用了.
SHELLEXECUTE()返回的值是什么?不是句柄吗?
如果用SHELLEXECUTEEX()函数如何?有例子吗?
liqing7165 2004-12-14
  • 打赏
  • 举报
回复
请问我怎么关闭 Regsvr32.exe 程序
Kevin_Lmx 2004-12-14
  • 打赏
  • 举报
回复
GetWindowText()可以得到窗口的标题,但是要先知道窗口的句柄。而就你现在的情况来看,只有得到句柄才能解决
Kevin_Lmx 2004-12-14
  • 打赏
  • 举报
回复
我问一下,你得到句柄是用哪个API?有没有用GetLastActivePopup?或者你是怎么写的?

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧