老话题了,禁止程序二次运行,可我的程序是托盘程序,于是新的问题产生了?
新问题就是当我的程序最小化的托盘时,用户二次打开程序(用户常犯这样的毛病),使托盘的程序醒来,而不是仅出一个提示!,winamp就是这样做的,如何实现,谢谢! 问题点数:20、回复次数:11Top
1 楼快乐老猫(高亚男 无米下炊)回复于 2005-02-20 02:50:54 得分 5
发消息给托盘栏图标Top
2 楼Cappuccino(加奶的咖啡)回复于 2005-02-21 13:15:51 得分 5
用互斥量!
Top
3 楼firstshine(黑里透红)回复于 2005-02-21 13:46:38 得分 5
程序写成如下结构
var
hMutex:hwnd;
ret:integer;
BroadcastList : DWORD;
sName:String;
{$R *.res}
begin
Application.Initialize;
sName:=...;//这个名称必须是唯一的,可以用GUID字符串
BringTopMessage := RegisterWindowMessage(PChar(sName));//注册消息
hMutex:=CreateMutex(nil,false,PChar(sName)); ret:=GetLastError;
if ret=ERROR_ALREADY_EXISTS then//程序已经运行
begin
BroadcastList := BSM_APPLICATIONS;
BroadcastSystemMessage(BSF_POSTMESSAGE,@BroadcastList,BringTopMessage,0,0);//广播一个消息
end
else begin
Application.CreateForm(TMDIFrame, MDIFrame);//你的主程序界面
Application.Run;
ReleaseMutex(hMutex);
end;
CloseHandle(hMutex);
end.
另外,在你的程序主窗体中作如下处理
var
BringTopMessage:UInt;//该变量定义在Interface段
写如下函数
procedure TMDIFrame.ApplicationMessage(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.Message = BringTopMessage then
begin
//在这里写代码唤醒你的托盘程序
Handled := true;
end;
end;
//在主窗体的Create事件中加入如下代码
procedure TMDIFrame.FormCreate(Sender: TObject);
begin
Application.OnMessage:=ApplicationMessage;
end;
这样就没有问题了Top
4 楼firstshine(黑里透红)回复于 2005-02-21 13:46:58 得分 0
程序写成如下结构
var
hMutex:hwnd;
ret:integer;
BroadcastList : DWORD;
sName:String;
{$R *.res}
begin
Application.Initialize;
sName:=...;//这个名称必须是唯一的,可以用GUID字符串
BringTopMessage := RegisterWindowMessage(PChar(sName));//注册消息
hMutex:=CreateMutex(nil,false,PChar(sName)); ret:=GetLastError;
if ret=ERROR_ALREADY_EXISTS then//程序已经运行
begin
BroadcastList := BSM_APPLICATIONS;
BroadcastSystemMessage(BSF_POSTMESSAGE,@BroadcastList,BringTopMessage,0,0);//广播一个消息
end
else begin
Application.CreateForm(TMDIFrame, MDIFrame);//你的主程序界面
Application.Run;
ReleaseMutex(hMutex);
end;
CloseHandle(hMutex);
end.
另外,在你的程序主窗体中作如下处理
var
BringTopMessage:UInt;//该变量定义在Interface段
写如下函数
procedure TMDIFrame.ApplicationMessage(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.Message = BringTopMessage then
begin
//在这里写代码唤醒你的托盘程序
Handled := true;
end;
end;
//在主窗体的Create事件中加入如下代码
procedure TMDIFrame.FormCreate(Sender: TObject);
begin
Application.OnMessage:=ApplicationMessage;
end;
这样就没有问题了Top
5 楼UC80862056(Alizee艾莉婕的粉丝)回复于 2005-02-22 23:56:21 得分 0
《Delphi5开发人员指南》第13章中有非常详细的介绍。还有个mutex.pas单元直接引用就行。Top
6 楼DDGG(叮叮当当)回复于 2005-02-23 01:33:36 得分 1
不管是用哪种方式判断已经存在一个实例,关键是要在.dpr里写判别代码,如果发现已经存在实例后就退出,这时主窗体还未创建,即使你用控件实现托盘图标,由于窗体都没创建,此时是不会显示出第2个托盘图标的。Top
7 楼FigoZhu(谢慕安)回复于 2005-02-23 17:02:30 得分 1
对,楼上说的很好!
主要是判断的代码是要写在dpr里。Top
8 楼ly_liuyang(Liu Yang LYSoft http://lysoft.7u7.net)回复于 2005-02-23 17:14:13 得分 1
方法很多的,Google上N多的
都是Mutex等的
http://lysoft.7u7.netTop
9 楼ahjoe(强哥)回复于 2005-02-24 20:44:43 得分 1
我也用 MutexTop
10 楼DDGG(叮叮当当)回复于 2005-02-25 14:45:30 得分 1
用Mutex的话,如果程序死掉了,用任务管理器强行终止后,互斥量可能无法清除,再运行程序就运行不起来了。Top
11 楼ahjoe(强哥)回复于 2005-03-17 14:14:14 得分 0
我用Mutex,程序强制结束,XP系统下会自动清除 Mutex.Top




