CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

怎样才能禁止同一个程序同时运行

楼主iceicebug(toby)2002-04-11 10:41:40 在 Delphi / VCL组件开发及应用 提问

已经在运行的程序,在未退出之前又运行这个程序,给出警告。在正常退出之后才能再次运行该程序,这能做到吗?请指教 问题点数:50、回复次数:7Top

1 楼iceboy2000(不死鸟一辉)回复于 2002-04-11 10:45:08 得分 25

只要在工程文件中作下面的处理就搞定了  
  var  
      hmutex:hwnd;  
      ret:integer;  
  begin  
      Application.Initialize;  
      hmutex:=createmutex(nil,false,'project1');  
      ret:=getlasterror;  
      if   ret<>error_already_exists   then  
      begin  
      Application.CreateForm(TForm1,   Form1);  
      end  
      else  
      begin  
      messagedlg('程序已运行。',mtinformation,[mbok],0);  
      releasemutex(hmutex);  
      end;Top

2 楼yuanjunjing(danny)回复于 2002-04-11 10:45:23 得分 0

var  
    hwnd:THandle;  
  hwnd:=findwindow('tfrm_main',nil);  
  if   hwnd=0   then  
    begin  
      Application.Initialize;  
      Application.Title   :=   '&sup1;&atilde;&para;&laquo;&Ograve;&ccedil;&acute;&iuml;&Otilde;&euml;&Ouml;&macr;&Oacute;&ETH;&Iuml;&THORN;&sup1;&laquo;&Euml;&frac34;&Ocirc;&shy;&Eacute;&acute;&sup2;&Ouml;&sup1;&Uuml;&Agrave;í&Iuml;&micro;&Iacute;&sup3;';  
      Application.Title   :=   '&Otilde;&euml;&Ouml;&macr;&sup1;&Uuml;&Agrave;í&ETH;&Aring;&Iuml;&cent;&Iuml;&micro;&Iacute;&sup3;&Ouml;&reg;&Eacute;&acute;&sup2;&Ouml;&sup1;&Uuml;&Agrave;í';  
      Application.CreateForm(TMainDataModule,   MainDataModule);  
      Application.CreateForm(TMainForm,   MainForm);  
      Application.Run;  
    end  
  else  
      setforegroundwindow(hwnd);Top

3 楼yuanjunjing(danny)回复于 2002-04-11 10:46:21 得分 25

var  
    hwnd:THandle;  
  hwnd:=findwindow('tfrm_main',nil);  
  if   hwnd=0   then  
    begin  
      Application.Initialize;  
      Application.CreateForm(TMainDataModule,   MainDataModule);  
      Application.CreateForm(TMainForm,   MainForm);  
      Application.Run;  
    end  
  else  
      setforegroundwindow(hwnd);  
   
  Top

4 楼whycats(雪狐)回复于 2002-04-11 10:46:53 得分 0

或者用findform(),还有对象互斥。Top

5 楼errorcode(errorcode)回复于 2002-04-11 10:59:24 得分 0

good   to   一楼Top

6 楼wind8bell(风之铃)回复于 2002-04-11 11:00:28 得分 0

转贴:  
  实现单实例运行的关键是判断前一实例是否存在,Win3.x中运行的程序能获知前一实  
  例的句柄,从而可以方便地进行判断,但   Windows   95   是抢先式多任务系统,其程序  
  的前一实例句柄恒为零,所以只有另寻其他办法。  
  据说有很多方法都可解决这个问题,不过我只知道两种,下面分别加以介绍。  
   
  ★第一种方法:  
  通过查看是否有相同窗口类名的例程存在来进行判断。  
   
  API函数   FindWindow   按照指定类名和窗口名来找到窗口的句柄,该函数并不查找子窗口。  
   
  FindWindow的函数原型为:  
   
  HWND   FindWindow(  
   
  LPCTSTR   lpClassName,         //   address   of   class   name  
  LPCTSTR   lpWindowName           //   address   of   window   name  
  );          
   
  参数:  
   
  lpClassName           欲查找窗口的类名。该变量的类型为以零结尾的字符串,也就是C/C++中  
                  的字符串类型。  
  lpWindowName         窗口名。变量类型同上。  
   
  返回值:  
   
  若成功,返回指定窗口的句柄;否则返回NULL。如果希望得到更多的失败信息,可以调用  
  GetLastError   函数。  
   
  例:  
   
  var  
  PrevWindow:HWND;         //定义一个句柄变量  
   
  begin  
  Application.Initialize;         //程序初始化  
  PrevWindow:=FindWindow('TForm1','运行时实例测试');  
  //窗口的类名为'TForm1',窗口名为'运行时实例测试'  
  //在Delphi中,窗口的类名可以从程序的TYPE区域里看到,而窗口名就是窗口的Caption属性。  
  if   PrevWindow<>0   then                 //如果找到此窗口,说明程序已经运行了一个实例  
  Begin  
  MessageBox(0,"已经运行了该程序!","警告",MB_ICONWARNING+MB_OK);  
  Application.Terminate;         //程序终止运行以保证只有一个实例  
  end;  
  Application.CreateForm(TForm1,   Form1);         //否则程序继续运行  
  Application.Run;  
  end.  
   
  //以上程序在Delphi   3.0   中通过。FindWindow函数的详细用法参见Win32   Api   Help。  
   
  WINAPI   WinMain(HINSTANCE,   HINSTANCE,   LPSTR,   int)  
  {  
  HWND   PreWindows;  
          try  
          {  
          Application->Initialize();  
  PreWindows=FindWindow("TForm1","运行实例测试");  
          if(PreWindows)  
  {  
  MessageBox(0,"已经运行了该程序!","警告",MB_ICONWARNING+MB_OK);  
  Application->Terminate();  
  }  
          Application->CreateForm(__classid(TForm1),   &Form1);  
          Application->Run();  
          }  
          catch   (Exception   &exception)  
          {  
          Application->ShowException(&exception);  
          }  
          return   0;  
  }  
  //以上程序在C++   Builder   1.0   中通过。  
   
  ★第二种方法:  
  第二种方法就是利用API函数CreateMutex。  
   
  CreateMutex函数用来创建一个已命名或是未命名的互斥体。  
   
  CreateMutex的函数原型为:  
   
  HANDLE   CreateMutex(  
   
  LPSECURITY_ATTRIBUTES   lpMutexAttributes,         //   address   of   security   attributes    
  BOOL   bInitialOwner,                         //   flag   for   initial   ownership    
  LPCTSTR   lpName                                     //   address   of   mutex-object   name    
  );          
   
  参数说明:  
   
  lpMutexAttributes         此参数指向一个SECURITY_ATTRIBUTES结构,此结构指定该互斥体的安全            
                          属性,如果该参数为NULL(即为空),则以缺省的安全描述符来创建互斥  
                          体,并且该函数返回的句柄不能被继承。  
                          (此参数好象不好理解,不过在此处你只需将其设为NULL就行了!)  
   
  bInitialOwner                   指定互斥体对象的初始拥有者。在此处设为False。  
   
  lpName                             此参数指定互斥体的名字。参数类型是以NULL结尾的字符串。  
   
  返回值:  
   
  如果函数成功则返回互斥体的句柄,如果指定的互斥体名已经存在,则GetLastError函数返回  
  ERROR_ALREADY_EXISTS。  
   
  例:  
  program   DEL3test;  
   
  uses  
  Forms,Windows,SysUtils,  
  DEL3unit   in   'DEL3unit.pas'   {Form1};  
   
  {$R   *.RES}  
   
  Var  
  hMutex:HWND;  
  Ret:Integer;  
  begin  
  Application.Initialize;  
  Application.Title   :=   'aaaaaa';  
  hMutex:=CreateMutex(nil,False,'aaaaaa');  
  Ret:=GetLastError;  
  If   Ret<>ERROR_ALREADY_EXISTS   Then    
  Begin  
  Application.CreateForm(TForm1,   Form1);  
  Application.Run;  
  End  
  Else  
  Application.MessageBox('Run   Twice!','Notes!',MB_OK);  
  ReleaseMutex(hMutex);  
  end.  
   
  //以上例子在Delphi   3.0中通过。  
   
  说明:  
   
  这两种方法一般来说并没有什么很大的区别,也没有在什么地方看到有关这两者的说明。  
  不过我在自己的程序中正好分别试过这两种方法,发现了这两者还是有一个区别。  
  如果程序中有一个启动画面,如Visual   Foxpro,Delphi,wps97等等,当采用第一种方法  
  时,仍然会出现启动画面,尽管在程序中我是先判断有无实例存在,然后再显示启动画面。  
  为什么会这样,我也不清楚,而用第二种方法就不会出现这种情况,所以我一直都用第二  
  种方法。  
  Top

7 楼tanqth(青蛙)回复于 2002-04-11 11:01:48 得分 0

实现单实例运行的关键是判断前一实例是否存在,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);    
  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;    
  这段程序的意思是如果找到一个类名相同的窗口,则向该窗口发送一个消息,并退   出,而本例中原窗口收到该消息后会自动激活或从图标还原,从而达到了避免二次运行.  
  Top

相关问题

  • 同一个小程序,vc下可以运行,eclipse+minGW下出错
  • 同一个程序只允许本机运行一个,怎么做?
  • 如何用程序控制在同一个局域网中的其他机器的某个程序运行?
  • 如何禁止一个程序运行????
  • 如何禁止程序运行?
  • 怎样禁止程序重复运行?
  • 怎样禁止某个程序运行?
  • 禁止其它程序运行?
  • 禁止其它程序运行?
  • 如何禁止程序二次运行

关键词

  • 函数
  • application
  • 程序
  • 运行
  • 句柄
  • 实例
  • createform
  • myappname
  • findwindow
  • rvhandle

得分解答快速导航

  • 帖主:iceicebug
  • iceboy2000
  • yuanjunjing

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo