给程序发送WM_CLOSE消息后,就收消息的程序不退出!

Storm2008 2009-05-06 12:42:51
var
h1553 : THandle;

h1553 := FindWindow(nil, 'BusTest');
if h1553<>NULL then
ShowMessage(IntToStr(SendMessage(h1553, WM_CLOSE, 0, 0)));



A、B两个程序,当双击运行程序B的,用程序A给B发消息(前面是A程序代码)发送后程序正常退出。



当我用下面这个函数运行B程序时,用同样的代码给B程序发送消息,SendMessage返回值是0,说明消息已经被处理了,但接受消息的窗体并没有退出。
发送消息的过程是在A程序closequey过程中发送的,由于接受消息的程序没退出,造城A程序也无法正常退出。


下面函数组要作用是运行B程序,并将其父窗体设置成A程序中的一个tabsheet,并将B显示到A的tabsheet中,A程序中通过循环等待B程序的退出,如果B程序不退出,就会造成A也无法退出。
现在要解决的是通过A怎么发消息才能让B正常退出,熟悉的朋友给说下,谢谢。
procedure TfrmMain.CreateProcessForm(Sender: TObject);
var
hHandle : THandle;
StartUpInfo:TStartupInfo;
ProcessInfo:TProcessInformation;
seProcess, seThread: TSecurityAttributes;
sPath:String;
exCode:DWORD;
begin
sPath := ExtractFilePath(Application.ExeName)+'BusTest.exe';
if not FileExists(sPath) then begin
MessageBox(Application.Handle, #10#13+'找不到总线测试程序,无法进行总线测试! '+#10#13+#10#13, '提示',
MB_OK+MB_ICONWARNING+MB_APPLMODAL);
Exit;
end;

FillChar(StartUpInfo, SizeOf(StartUpInfo), 0);
FillChar(seProcess, SizeOf(seProcess),0);
FillChar(seThread, SizeOf(seThread),0);
StartUpInfo.dwFlags:=STARTF_USESHOWWINDOW ;
seProcess.nLength := sizeof(seProcess);
seProcess.lpSecurityDescriptor := nil;
seProcess.bInheritHandle := true;
seThread.nLength := sizeof(seThread);
seThread.lpSecurityDescriptor := nil;
seThread.bInheritHandle := true;
if not CreateProcess(nil, PChar(sPath), @seProcess, @seThread, False, 0 ,
nil, nil, StartUpInfo, ProcessInfo) then begin
raise Exception.Create('创建总线测试进程失败');
end;

hHandle := 0;
while (hHandle=0) do
begin
sleep(30);
hHandle:=FindWindow(nil,'BusTest');
end;

Windows.SetParent(hHandle, frmMain.tbs1553b.Handle);
Windows.MoveWindow(hHandle, -4, -29, 1000 , 800 , true);

GetExitCodeProcess(ProcessInfo.hProcess,exCode);

while(exCode=STILL_ACTIVE) do
begin
Sleep(100);
Application.ProcessMessages;
GetExitCodeProcess(ProcessInfo.hProcess,exCode);
end;

end;


...全文
550 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
sy_100000 2009-05-08
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 Storm2008 的回复:]
B程序是MFC环境下的一个模态窗体。
[/Quote]

模态窗体,SendMessage(Handle, WM_SYSCOMMAND, SC_CLOSE, 0)即可!!

若用以上语句,B程序不能退出,说明B程序处理了WM_SYSCOMMAND消息,这时就必须用
TerminateProcess(hBProcess, 0)来关闭它!
Storm2008 2009-05-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 unsigned 的回复:]
PostThreadMessage(ProcessInfo.hThread,WM_QUIT,0,0);
[/Quote]


我试了,发送消息后,B程序还是没反应。


不知道是不是这句话的问题h1553 := FindWindow(nil, 'BusTest'); if h1553<>NULL then

上午又写了个例子,这句话这么写好像不对,B程序的父窗体已经不是桌面了。
Storm2008 2009-05-07
  • 打赏
  • 举报
回复
B程序是MFC环境下的一个模态窗体。
Storm2008 2009-05-07
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 unsigned 的回复:]
引用 16 楼 Storm2008 的回复:
引用 15 楼 unsigned 的回复:
Delphi当中最好不要使用NULL,这是一个函数,返回是一个VarNull的Variant值.正确的写法是Nil.


用Nil好像提示错误,记不清了,我明天再去试试。

是的,Nil不能当0来使用,而handle被定义为数值类型,所以使用0.
[/Quote]


指针、Variant类似的类型用nil,数值类型的用数值比较,一般是这样吧?基础概念不是太清。



帮我看下这个问题吧,我找不到头绪。
B程序的parent是A程序中的一个tabsheet控件,B是VC写的,当A退出了,B也自动退出了,但没触发OnOK和OnCancel过程,造成有几个释放资源的过程没执行到,老提示错误。但单独运行B程序时,无论是点击确定、取消还是叉掉都不会提示错误。
我想问下,A退出时,B也会自动退出,B程序中我应该处理那个消息,才能运行窗体退出时的过程,或者说我把释放资源的过程放到哪里,才能正确的被执行到。
写的有点乱,您多费心了。
僵哥 2009-05-07
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 Storm2008 的回复:]
引用 15 楼 unsigned 的回复:
Delphi当中最好不要使用NULL,这是一个函数,返回是一个VarNull的Variant值.正确的写法是Nil.


用Nil好像提示错误,记不清了,我明天再去试试。
[/Quote]
是的,Nil不能当0来使用,而handle被定义为数值类型,所以使用0.
Storm2008 2009-05-07
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 unsigned 的回复:]
Delphi当中最好不要使用NULL,这是一个函数,返回是一个VarNull的Variant值.正确的写法是Nil.
[/Quote]

用Nil好像提示错误,记不清了,我明天再去试试。
僵哥 2009-05-07
  • 打赏
  • 举报
回复
Delphi当中最好不要使用NULL,这是一个函数,返回是一个VarNull的Variant值.正确的写法是Nil.
Storm2008 2009-05-07
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 unsigned 的回复:]
引用 10 楼 Storm2008 的回复:
引用 2 楼 unsigned 的回复:
PostThreadMessage(ProcessInfo.hThread,WM_QUIT,0,0);



我试了,发送消息后,B程序还是没反应。


不知道是不是这句话的问题h1553 := FindWindow(nil, 'BusTest'); if h1553 <>NULL then

上午又写了个例子,这句话这么写好像不对,B程序的父窗体已经不是桌面了。

应该记录一下看看是不是FindWindow失败,如果是的话就需要另外想办法.
[/Quote]



if h1553 <>NULL then
好像是这个判断语句有问题,我换成if h1553 <>0 then,就可以正常判断出没找到窗体了。
用 if h1553 <>NULL then 好像不起作用,每次都把then后面的语句执行了。


我换了个方式把问题解决了,不过新的问题又来了。


B程序的parent是A程序中的一个控件,B是VC写的,当A退出了,B也自动退出了,但不触发OnOK和OnCancel过程,造成有几个过程没执行到,老提示错误。单独运行B程序时,不会提示错误。
我想问下,A退出时,B也会自动退出,B程序中我应该处理那个消息,才能运行窗体退出时的过程。

sanguomi 2009-05-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 Storm2008 的回复:]
引用 2 楼 unsigned 的回复:
PostThreadMessage(ProcessInfo.hThread,WM_QUIT,0,0);



我试了,发送消息后,B程序还是没反应。


不知道是不是这句话的问题h1553 := FindWindow(nil, 'BusTest'); if h1553 <>NULL then

上午又写了个例子,这句话这么写好像不对,B程序的父窗体已经不是桌面了。
[/Quote]

最简单的办法,用SP++拖到那个控件上,查出句柄,太后和FindWindow的返回值比较一下就知拉
僵哥 2009-05-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 Storm2008 的回复:]
引用 2 楼 unsigned 的回复:
PostThreadMessage(ProcessInfo.hThread,WM_QUIT,0,0);



我试了,发送消息后,B程序还是没反应。


不知道是不是这句话的问题h1553 := FindWindow(nil, 'BusTest'); if h1553 <>NULL then

上午又写了个例子,这句话这么写好像不对,B程序的父窗体已经不是桌面了。
[/Quote]
应该记录一下看看是不是FindWindow失败,如果是的话就需要另外想办法.
sparklerl 2009-05-07
  • 打赏
  • 举报
回复
Mark
僵哥 2009-05-06
  • 打赏
  • 举报
回复
PostThreadMessage(ProcessInfo.hThread,WM_QUIT,0,0);
Storm2008 2009-05-06
  • 打赏
  • 举报
回复
TerminateProcess?
Storm2008 2009-05-06
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 xjq2003 的回复:]
引用 3 楼 yhf365 的回复:
把SendMessage换成PostMessage试下

这个可以测试一下,我也遇到过
[/Quote]


B程序是作为A程序的一个进程运行的,PostMessage和SendMessage我都试过,消息用WM_CLOSE和WM_QUIT也都试过,显示B程序已经处理了消息,但就是不退出,不行的。
xjq2003 2009-05-06
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 yhf365 的回复:]
把SendMessage换成PostMessage试下
[/Quote]
这个可以测试一下,我也遇到过
Storm2008 2009-05-06
  • 打赏
  • 举报
回复
关于自定义消息有文章就更好了。

Delphi7 demo里好像有一个程序间通信的例子,找不到是哪个了,有印象的朋友提示下。
phyf_Anlymi 2009-05-06
  • 打赏
  • 举报
回复
和DELPHI差不多,网上例子很多的!~
Storm2008 2009-05-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 unsigned 的回复:]
PostThreadMessage(ProcessInfo.hThread,WM_QUIT,0,0);
[/Quote]

多谢,应该是这个了,明天去公司试试。


B程序是用VC写的,A程序使用Delphi写的,如果B给A发个自定义消息,用VC应该怎么写呢?

随便找个可用的代码段就可以,我在自己去改。本来要写完了,结果笔记本被人拿跑了,没法查帮助了。
starluck 2009-05-06
  • 打赏
  • 举报
回复


PostThreadMessage(ProcessInfo.hProcess
yhf365 2009-05-06
  • 打赏
  • 举报
回复
把SendMessage换成PostMessage试下

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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