delphi,只允许让程序运行一次。
发布网友
发布时间:2024-10-21 20:00
我来回答
共2个回答
热心网友
时间:2024-11-13 21:47
楼上提供的代码和楼主提供网页的代码都能达到不让程序同时运行两次,但楼主提供的网页代码有一个与楼上不同的地方:
楼的的供码仅是不让程序两次运行,如果运行两次,将跳出一个MessageBox,点OK后就没有什么了,也就是说仅提示一下。
但那个网页上的代码却有一个好处,当你的程序的窗口被其他窗口遮挡时,两次运行时,你的程序的主窗口就会被激活并被放到其他窗口之上。
实现原理是建立一个互斥对象,然后运行程序时,如果互斥对象不存在,则运行,如果存在,则主被激活本程序窗口并将其放到其他窗口之上.
其实网页中提供的代码是比较详细的,但由于他是在工程文件中写代码,而现在delphi教材中讲工程文件的比较少,或者说初级入门的教材中讲工程文件的比较少,所以楼主看到这个时会迷茫一些!呵呵,不知道说的对不对,下面是我根据网页上的代码写的(仅是复制而已),D7运行通过!
他的源码应该是这样的:
program Project1;
uses
Forms,
Windows,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
hMutex,FindHid:HWND;
MoudleName:string;
function EnumWndProc(hwnd:Thandle;param:Cardinal):bool;stdcall;
var
ClassName,WinMoudleName:string;
WinInstance:THandle;
begin
result:=true;
SetLength(ClassName,100);
GetClassName(hwnd,pchar(ClassName),length(ClassName));//获得当前遍历窗口的类名
ClassName:=pchar(ClassName);//在字符串后加结束符,确定字符串结束
if ClassName=TForm1.ClassName then//比较
begin
WinInstance:=GetWindowLong(hwnd,GWL_HINSTANCE);//获得当前遍历窗口的实例
setlength(WinMoudleName,100);
GetModuleFileName(WinInstance,pchar(WinMoudleName),length(WinMoudleName));
//获得当前遍历窗口的程序文件名
WinMoudleName:=pchar(WinMoudleName);
if WinMoudleName=MoudleName then//MoudleName为工程全局变量,自身程序的文件名
begin
FindHid:=hwnd;//FindHid为工程全局变量保存找到的句炳
result:=false;//找到以后就结束遍历
end;
end;
end;
begin
hMutex:=CreateMutex(nil,false,'hkOneCopy');
if WaitForSingleObject(hMutex,0)<>wait_TimeOut then
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end
else
begin
SetLength(MoudleName,100);
GetModuleFileName(HInstance,pchar(MoudleName),length(MoudleName));
//获得自己程序文件名
MoudleName:=pchar(MoudleName);
EnumWindows(@EnumWndProc,0);//调用枚举函数
if FindHid<>0 then
SetForegroundWindow(FindHid);
end;
end.
在我的博客上有相关的文章,你可以看一下,地址:http://hi.baidu.com/jxsbb/blog/item/049b5d90258a1b8fa877a443.html
这个例子相对来说有一点难,所以我自己写了一个,跟上面差不多,只是添加了几个代码(有点乱,将就着看吧,- -!),但这里有一个缺点,就是当程序运行时,再次运行该程序,的确会将最小化或是被其他窗口遮盖的程序窗体放到其他窗口之上,但这个窗口却无法最小化了,还没弄清是什么原因。
program Project1;
uses
Forms,
Windows,
Messages,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
hMutex,FindHid:HWND;
MoudleName:string;
function EnumWndProc(hwnd:Thandle;param:Cardinal):bool;stdcall;
var
ClassName,WinMoudleName:string;
WinInstance:THandle;
begin
result:=true;
SetLength(ClassName,100);
GetClassName(hwnd,pchar(ClassName),length(ClassName));//获得当前遍历窗口的类名
ClassName:=pchar(ClassName);//在字符串后加结束符,确定字符串结束
if ClassName=TForm1.ClassName then//比较
begin
WinInstance:=GetWindowLong(hwnd,GWL_HINSTANCE);//获得当前遍历窗口的实例
setlength(WinMoudleName,100);
GetModuleFileName(WinInstance,pchar(WinMoudleName),length(WinMoudleName));
//获得当前遍历窗口的程序文件名
WinMoudleName:=pchar(WinMoudleName);
if WinMoudleName=MoudleName then//MoudleName为工程全局变量,自身程序的文件名
begin
FindHid:=hwnd;//FindHid为工程全局变量保存找到的句炳
result:=false;//找到以后就结束遍历
end;
end;
end;
var
han:Thandle;
begin
hMutex:=CreateMutex(nil,false,'hkOneCopy');
if WaitForSingleObject(hMutex,0)<>wait_TimeOut then
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end
else
begin
SetLength(MoudleName,100);
GetModuleFileName(HInstance,pchar(MoudleName),length(MoudleName));
//获得自己程序文件名
MoudleName:=pchar(MoudleName);
EnumWindows(@EnumWndProc,0);//调用枚举函数
if FindHid<>0 then
begin
han:=findWindow(nil,'Form1');//Form1是你的窗口的name
if han<>0 then
begin
sendmessage(han,WM_SYSCOMMAND, SC_RESTORE,0);
end;
end;
SetForegroundWindow(FindHid);
end;
end.
热心网友
时间:2024-11-13 21:53
呵呵,我太菜了,你贴的网址里的内容我看不懂。不过只让程序运行一次好象代码很少,要引用Windows单元,如下:
CreateMutex(nil,False,'NetSend');
if GetLastError=ERROR_ALREADY_EXISTS then
begin
Application.MessageBox('程序已经运行','提示',MB_OK);
Halt(0);
end;
要写在program单元中。我贴出整个单元的代码吧:
program NetSend;
uses
Windows,
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
CreateMutex(nil,False,'NetSend');
if GetLastError=ERROR_ALREADY_EXISTS then
begin
Application.MessageBox('程序已经运行','提示',MB_OK);
Halt(0);
end;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.