关于防止程序重复运行(50分)

  • 主题发起人 主题发起人 刘建军
  • 开始时间 开始时间

刘建军

Unregistered / Unconfirmed
GUEST, unregistred user!
我编写了一个程序,
其中有一段程序防止该程序多次运行
就如ultraedit一样
最小化时使用application.restore能恢复窗口
但当窗口被其它窗口盖住时
使用application.bringtofront不能将其置于最顶层
而ultraedit能实现
有何技巧
 
SetWindowPOS
 
设置FORM的风格为FsStayTop,我刚试过,可以待在最上面?你的意思如何?
 
我的程序中一直用:
if IsIconic(Application.Handle) then
begin
Application.MainForm.WindowState := wsNormal;
Application.Restore;
end;
SetForegroundWindow(Application.MainForm.Handle);
没问题的。
 
要不先最小化,在restore?
 
应该使用下面的两句
SetForegroundWindow(Application.MainForm.Handle);
BringWindowToTop(Application.MainForm.Handle);
Borland公司的窗口跟标准的windows不大一样,最小化时实际上是隐含了窗口,如果加上判断的话应该IsWindowVisible(Application.MainForm.Handle);
 
修改项目文件:
uses
windows,dialogs,forms,
unit1 in 'unit1.pas'{form1};
{$R*.RES}
var
handle:Thandle;
begin
handle:=findwindow('tform1','form1');
if handle=0 then
begin
application.initialize;
application.createform(tform1,form1);
application.run;
end
else
messagedlg('重复运行',mtinformation,[mbok],0);
setforegroundwindow(handle);
end;
 
In Builder vrey simple, this way:
add the two statements:)

-----------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
CreateMutex(NULL, true, "only_one_copy"); // this
if(GetLastError()!=ERROR_ALREADY_EXISTS) //and this
{
try
{
Application->Initialize();
.....
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}

I don't know if this do in DELPHI
 
好象都不太行。

我用bringtofront在95下可以正常该功能。

在多台机器的98下却不能正常实现该功能。
 
使用原子变量,具体查看WIN32API。
程序启动时,向系统添加一个原子变量,如“myApp”。退出前删除。
程序再次启动前,先得到原子变量“myAPP”,如果成功说明程序已经启动,
可以得到它的窗口句柄,并激活。

下面是个简陋的VC例子:

/* 启动时 */
ATOM atomMainForm;
HWND hWnd;

if (!(atomMainForm=GlobalFindAtom("myApp")) )
{
  // 如果没有得到原子变量,添加一个,名字确保唯一
  atomMainForm=GlobalAddAtom("myApp");
  // 如果添加不成功,可能系统故障
... ... ...
}
else
{
  // 得到了,程序在运行,得到窗口句柄
  if ( (hWnd = ::FindWindow(NULL,"myApp"))==NULL)
  {
     // 得不到窗口句柄,系统故障,删除原子变量
GlobalDeleteAtom(atomMainForm);
return -1;
exit(-1);
  }
  else
  {
    // 激活窗口
    ::SetActiveWindow(hWnd);
  }


/* 程序退出时 */
// 删除原子变量
ATOM atomMainForm;
if ((atomMainForm=GlobalFindAtom("myApp")) )
  GlobalDeleteAtom(atomMainForm);
 
我同意阿朱的意见
 
我并不是要让他一直呆在最顶层。阿朱的方法不行
 
或是张剑波网友的例子或是我得例子,
其他方法更复杂。
 
program waterSave;

uses
Forms,
windows,
sysutils,
Controls,
Unitdata in 'Unitdata.pas' {DtModule: TDataModule},
login in 'login.pas' {LoginForm},
usermess in 'usermess.pas',
newidform in 'newidform.pas' {KHXXXGForm},
grouping in 'grouping.pas' {LLDFORM},
main in 'main.pas' {MainForm},
chgsave in 'chgsave.pas' {ChgSaveForm};

{$R *.RES}
var
tmpPassForm: TloginForm;
wnd:Hwnd;
begin
wnd:=Findwindow(nil,'用户存款处理中心');
application.Terminate;
if wnd=0 then
begin
Application.Initialize;
Application.Title := '用户存款处理中心';
Application.CreateForm(TDtModule, DtModule);
tmpPassForm := TloginForm.Create( Application);
if Assigned( tmpPassForm) then
begin
tmpPassForm.Caption:='用户存款处理中心';
tmpPassForm.ShowModal;
if tmpPassForm.ModalResult = mrOK then
begin
userid:=TmppassForm.UID;
username:=TmppassForm.UName;
Level2:=TmppassForm.Level2;
Level1:=TmppassForm.Level1;

Application.CreateForm(TMainForm, MainForm);
tmpPassForm.Free;
Application.Run;
end
else
tmpPassForm.Free;
end;
end
else
begin
setforegroundwindow(wnd);
showWindow(wnd,SW_SHOW);
Application.Terminate;
end;
end.
朋友你可以使用以上办法,保证没有问题,我可是要钱的
 
王亮是对的
别人的也对但是王亮的最好
 
我一般用这种方法,在我机器上行!
function LookAllWin(Handle:HWND;Temp:LongInt):BOOL;stdcall;
var
WindowsName,ClassName:array[0..255] of Char;
begin
if GetClassName(Handle,ClassName,SizeOf(ClassName))>0 then
//得到窗口的类名
if GetWindowText(Handle,WindowsName,SizeOf(WindowsName))>0 then
//得到窗口的标题
if StrLComp(WindowsName,MyappName,StrLen(MyappName))=0 then begin
//如果具有同样的窗口标题
if Handle<>Application.Handle then
inc (NumFound); //增加找到的实数
LastFound:=Handle; //保存找到的窗口句柄,以便后面利用
// halt;
end;
Result:=true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
NumFound:=0;LastFound:=0;
MyAppname:='Project1';
GetClassname(Application.Handle,MyclassName,sizeOf(MyClassName));
EnumWindows(@lookAllWin,0);
if NumFound>AllowedInstances then begin
MyPopup:=GetLastActivePopup(Lastfound);
BringwindowToTop(Lastfound);
if IsIconic(MyPopup) then
ShowWindow(Mypopup,SW_RESTORE)
else
SetForegroundWindow(MyPopup);
halt;
end;

end;
 
补上变量:
const
AllowedInstances=0;

var
Form1: TForm1;

kwndprev,LastFound,MyPopup:HWND;
MyclassName,Myappname:array[0..255] of Char;
Numfound:integer;
 
http://go.163.com/~longwu/MyFunc.htm
上Process函数库中写了一些相关函数.
你要的功能有三种方法实现.
 
真的!王亮的方法即标准、又正确!
procedure TForm1.FormCreate(Sender: TObject);
begin
{搜寻表看是否程序已运行}
if GlobalFindAtom('PROGRAM_RUNNING') = 0 then
{ 如果没运行,则在表中增加信息 }
atom := GlobalAddAtom('PROGRAM_RUNNING')
else begin
{ 如果程序已运行,则显示信息然后退出 }
MessageDlg('You have the program running
all ready!!', mtWarning,[mbOK], 0);
Halt;
end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
{从表中移走信息以便程序能再运行}
GlobalDeleteAtom(atom);
end;
 

Similar threads

D
回复
0
查看
765
DelphiTeacher的专栏
D
D
回复
0
查看
669
DelphiTeacher的专栏
D
D
回复
0
查看
663
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
后退
顶部