读书人

怎么调用另一个程序实例的函数

发布时间: 2012-08-10 12:19:33 作者: rapoo

如何调用另一个程序实例的函数?
Delphi7编写的一个系统,当系统关闭时,系统会隐藏到托盘区继续运行;如果双击托盘图标,或者点击菜单,就可以还原。还原的函数是procedure mDisplayClick(nil)
注意:当程序隐藏到托盘区,用SendMessage来Restore是不行的。只能用mDisplayClick。只有在程序最小化到任务栏的情况下,才可以用SendMessage来Restore。
现在我想做到,如果系统已经在托盘区运行了,用户如果试图再运行,就把当前已运行的系统还原。
在有Handle的情况下,该如何调用已运行的实例的mDisplayClick这个过程?

1,
我试图用:
TfrmMAIN(FindControl(PSMem^.AppHandle)).mDISPLAYClick(nil);
结果再次运行时提示出错。是否可以通过句柄直接调用函数?如果可以,这是最方便的。

2,
我用消息队列方式,新实例中:
PostMessage(PSMem^.AppHandle,1025,0,0);
然后Application.OnMessage设置:
if Msg.message=1025 then
frmMAIN.mDISPLAYClick(nil);
结果发现没捕捉到消息;

3,我考虑能否用Close或者Restore事件来传递,SendMessage一个SC_CLOSE的消息,然后程序的onClose事件中进行判断,但是难点在于,如何判断本次Close事件是人工点击的呢还是别人Send过来的呢?我的想法是,如果是人工点击关闭,该窗体必然是激活状态;可是如何获得窗体的激活状态?


[解决办法]
发送消息肯定可以的。
因为你鼠标双击托盘或右键点击他在内部都是消息。
应该是你的代码没写好。
[解决办法]
放到工程文件中,CNT_APPLICATION_NAME是窗体标题

Delphi(Pascal) code
var  h: THandle;  prevInst: THandle;  (*******单实例模式*********)  h := CreateMutex(nil, True, CNT_APPLICATION_NAME);  if (GetLastError = ERROR_ALREADY_EXISTS) or (h = 0) then  begin    prevInst := FindWindow(nil, CNT_APPLICATION_NAME);    If prevInst<>0 then          if isiconic(prevInst)then             ShowWindow(prevInst,SW_RESTORE)          ELSE             SetForegroundWindow(prevInst);    Exit;  end;  (***********单实例模式*********)
[解决办法]
探讨
procedure TfrmMAIN.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caNone;
ShowWindow(Handle,SW_HIDE); //隐藏主窗体
ShowWindow(Application.Handle,SW_HIDE);
SetWindowLong(Application.Handle,GWL_EXSTYLE,
GetWindowLong(Application.handle,GWL_EXSTYLE)
or WS_EX_TOOLWINDOW AND NOT WS_EX_APPWINDOW);//隐藏应用程序窗口在任务栏上的显示
end;

读书人网 >.NET

热点推荐