防止程序被重复执行

delphi 专栏收录该内容
78 篇文章 0 订阅
防止程序被重复执行(第一法)

Windows95的程序一般都可以重复执行,例如你按下WIN+E组合键即启动资
源管理器,如果再按WIN+E组合键又会出现一个资源管理器,这两个程序互不干
扰。有时候你可以需要制作这样一个程序:当该程序已经执行时,若用户企图
再次执行该程序则只会激活那个已执行的程序,而不是又出现一个副本。
  完成这个目的的核心就是要在程序启动时查找该程序是否已经运行,我曾
试过很多种方法,包括向“全局元素表”(Global ATOM Table)写特定字符串等
等,但最简单的方法还是下面这个:

在程序启动时将Application的Title特性字段的值暂时改变。
利用Windows API函数FindWindows()查找窗口
恢复Application的Title值

  上述步骤一般在主Form的OnCreate事件中实现,示例如下:

procedure TForm1.FormCreate(Sender: TObject);
var
ZAppName: array[0..127] of char;
Hold: String;
Found: HWND;
Found: HWND;
begin
Hold := Application.Title;
Application.Title := 'OnlyOne'
+ IntToStr(HInstance); // 暂时修改窗口标题
StrPCopy(ZAppName, Hold); // 原窗口标题
Found := FindWindow(nil, ZAppName); // 查找窗口
Application.Title := Hold; // 恢复窗口标题
if Found<>0 then begin
// 若找到则激活已运行的程序并结束自身
ShowWindow(Found, SW_RESTORE);
Application.Terminate;
end;
end;

相关文章:防止程序被重复执行(另一种方法)


  实现单实例运行的关键是判断前一实例是否存在,Win3.x中运行的程序能获知前
一实例的句柄,从而可以方便地进行判断,但 Windows 95 是抢先式多任务系统,其
程序的前一实例句柄恒为零,所以只有另寻其他办法。目前最有效的办法是通过查看
是否有相同窗口类名的例程存在来进行判断。下面介绍在Delphi中实现的方法。

1、对主窗口程序的改动:

在主窗口(即程序创建的第一个窗口)中interface节加入
const
CM_RESTORE = WM_USER + $1000; {自定义的“恢复”消息}
MYAPPNAME = "My Delphi Program";
并在Form的定义的public节中加入
procedure CreateParams(var Params: TCreateParams); override;
Procedure RestoreRequest(var message: TMessage); message CM_RESTORE;
在implementation节中加入
{指定窗口名称}
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.WinClassName := MYAPPNAME;
end;

{处理“恢复”消息}
procedure TForm1.RestoreRequest(var message: TMessage);
procedure TForm1.RestoreRequest(var message: TMessage);
begin
if IsIconic(Application.Handle) = TRUE then
Application.Restore
else
Application.BringToFront;
end;

经过以上修改,程序的主窗口的类名已经被指定了,这是进行判断的基础。一般在程
序刚开始运行的时候进行判断,所以还要对DPR文件进行修改。

2、对DPR文件的改动

在 uses 节中添加 windows、messages这两个单元加入下列语句,注意两个文件中常
量CM_RESTORE和MYAPPNAME的定义必须一致
const
CM_RESTORE = WM_USER + $1000; {自定义的“恢复”消息}
MYAPPNAME = "My Delphi Program";
var
RvHandle : hWnd;

将下列语句插到程序最前部(在Application.Initialize之前)

RvHandle := FindWindow(MYAPPNAME, NIL);
if RvHandle > 0 then
begin
PostMessage(RvHandle, CM_RESTORE, 0, 0);
Exit;
end;
这段程序的意思是如果找到一个类名相同的窗口,则向该窗口发送一个消息,并退
出,而本例中原窗口收到该消息后会自动激活或从图标还原,从而达到了避免二次运
行且能自动调出前一例程的目的。


  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值