现状如下:(1). A.exe 是主程序,上面有一个button1,点击后,运行子系统B.exe,并融合到A.exe的pageControl(或panel)上来。
通过 windows.SetParent来实现B.exe融合到A.exe中来的。(2). B.exe中有一个按钮,点击代码如下:
form1:=Tform1.create(self);
form1.showmodal;
form1.release;运行后,B能正常融合,点击B中的按钮,表单form1也能正常工作,包括TAB等都能正常工作。但是:无意中切换到已打开的EXCEL或其他任务栏中的程序,再回来时,发现刚打开的form1不见了,
于是用ALT+TAB 进行切换,找到了刚找开的form1,原来跑到A.exe(最大化)后面去了。于是:修改B.exe中按钮的代码:
form1:=Tform1.create(self);
form1.ParentWindow:=application.MainForm.Handle; //加了这句
form1.showmodal;
form1.release;再运行,并点击任务栏下的其他内容,再回到A.exe中来,form1还在(这次没有“消失”),但是form1窗体标题始终不能成激活状态,即使用鼠标点击窗体标题,也不能成激活状态。后发现,点击B.exe按钮,form1出现时,窗体就不能成激活状态。后来又用了 setActiveWindow、SetForcegroundWindow、PostMessage等想将form1设置成激活状态,一直不行。后来又用SPY想强行激活,也不行。所以,请教各位高手,我哪一个环节出现问题了。网上也找了DLL融合的方法进行参考,没有能解决。
通过 windows.SetParent来实现B.exe融合到A.exe中来的。(2). B.exe中有一个按钮,点击代码如下:
form1:=Tform1.create(self);
form1.showmodal;
form1.release;运行后,B能正常融合,点击B中的按钮,表单form1也能正常工作,包括TAB等都能正常工作。但是:无意中切换到已打开的EXCEL或其他任务栏中的程序,再回来时,发现刚打开的form1不见了,
于是用ALT+TAB 进行切换,找到了刚找开的form1,原来跑到A.exe(最大化)后面去了。于是:修改B.exe中按钮的代码:
form1:=Tform1.create(self);
form1.ParentWindow:=application.MainForm.Handle; //加了这句
form1.showmodal;
form1.release;再运行,并点击任务栏下的其他内容,再回到A.exe中来,form1还在(这次没有“消失”),但是form1窗体标题始终不能成激活状态,即使用鼠标点击窗体标题,也不能成激活状态。后发现,点击B.exe按钮,form1出现时,窗体就不能成激活状态。后来又用了 setActiveWindow、SetForcegroundWindow、PostMessage等想将form1设置成激活状态,一直不行。后来又用SPY想强行激活,也不行。所以,请教各位高手,我哪一个环节出现问题了。网上也找了DLL融合的方法进行参考,没有能解决。
解决方案 »
- 随机函数请教
- TIdUDPClient TIdUDPServer聊天程序,收发消息问题
- 为什么一删除vclskin皮肤,程序就报错
- Delphi能在手机上开发软件吗
- 如何获取,TComboBox中的所有数值.
- 谁有 PsFRExportFilters for delphi 7.0 控件的最新注册版?万分感谢!在线等!!
- 用delphi控制word
- 最近我接到一个中小企业的信息管理系统的定单临时需要4名程序员协作开发,有意者请回复或mail to me [email protected]
- 怎样能缩短分包发与整包发之间的时间差距?
- 在serversocket中如何用IP地址实现消息转发?急
- 用Tadoquery调用oracle的存储过程的问题.
- DELPHI里改变颜色为什么要*256
你这种做法不好控制的,有个解决方案不知道是否适合你,你可以尝试把B改成带窗体的动态库,然后,把A的application句柄传入B.dll,控制起来就很自如了。
还有form1:=Tform1.create(self); 这个也改为application创建
然后在A.exe中写一个消息处理函数,如果收到消息,立即给B.exe发消息,把LParam设置成A的Application.handle,然后在B.exe中添加一个消息处理函数,
收到A的消息之后,把LParam转换成Application,取个名字App_A之后
form1:=Tform1.create(App_A);
form1.ParentWindow:=App_A.MainForm.Handle; //加了这句
form1.showmodal;
form1.release
这个方法试试可不可以,我这里没你的代码,没法试验。我估计应该差不多。
H:HWND;
begin
H:=FindWindow('A的标题',nil);
if H>0 then
begin
form1:=Tform1.create(App_A);
windows.SetParent(form1.Handle,H); //后来看了ParentWindow还是调用SetParent,就直接用
form1.showmodal;
form1.release
end;
end;
但是这样有一个缺点还没解决:尽管目前B.exe的 form1能够正常工作了,而且窗体也有焦点,且不会“消失"
可是,此时A中所有的按钮及其他控件都还能够使用,而不是象常规EXE调用窗体showmodal后,必须关闭后,才可以使用主窗体中的内容。因此,还有一些细节还有待进行学习、探讨。
就改为form1:=Tform1.create(application);
我身边没环境,你试下这样看看
在a程序点击运行时先createprocess运行b.exe,然后waiteforsingleobject等待b运行结束,然后b再showmodel,此时a是阻塞状态,不会响应鼠标事件的
*********************************************************
这种方法只能改变激活或者非激活的状态吧,但是还是不能阻止a form上的按钮点击还是用发送消息好些,想了想 不用禁用键盘和鼠标消息,直接修改form.enable属性就行了
a.exe运行b.exe b showmodel时给a发一个消息m1,重载a 的wndproc,接到消息后a form.enable=false
b 关闭模式窗体同样发送消息m2 ,a收到m2 form.enable=true,
2、DLL中表单的融合
3、BPL表单的融合4、目前正在偿试EXE之间的融合。
仅个人兴趣。
谢谢,我就是这样操作的,只不过我只是把B程序有些功能按钮disable,但A程序是允许,因为还会运行其他程序。