我要完成的功能是:
例如程序:a.exe
如果这个程序正在运行,那么我再次运行这个程序的时候,将会自动关闭;
并且先运行的哪个程序如果已经最小化则使其正常显示,并显示到最前面;以下使我的代码:procedure TForm1.FormCreate(Sender: TObject);
var
errNO: Integer;
hMutex: HWND;
begin
//创建互斥对象
hMutex := CreateMutex(nil, false, PChar(Application.Title));
errNO := GetLastError;
//判断程序是否重复运行
if errNO = ERROR_ALREADY_EXISTS then
begin
hMutex := FindWindow(nil, 'zzz'); //获得程序句柄
ShowWindow(hMutex, SW_NORMAL); //如果最小化则正常显示
SetForegroundWindow(hMutex); //程序显示到最前面
Application.Terminate;
end;
end;procedure TForm1.FormShow(Sender: TObject);
begin
Form1.Caption := 'zzz';
end;
问题是:
如果先运行的哪个程序已经最小化,那么当我再次打开这个程序的时候,先运行的哪个程序便会变为正常显示,但却再也无法最小化了,不知道为什么?请各位大侠指点!
例如程序:a.exe
如果这个程序正在运行,那么我再次运行这个程序的时候,将会自动关闭;
并且先运行的哪个程序如果已经最小化则使其正常显示,并显示到最前面;以下使我的代码:procedure TForm1.FormCreate(Sender: TObject);
var
errNO: Integer;
hMutex: HWND;
begin
//创建互斥对象
hMutex := CreateMutex(nil, false, PChar(Application.Title));
errNO := GetLastError;
//判断程序是否重复运行
if errNO = ERROR_ALREADY_EXISTS then
begin
hMutex := FindWindow(nil, 'zzz'); //获得程序句柄
ShowWindow(hMutex, SW_NORMAL); //如果最小化则正常显示
SetForegroundWindow(hMutex); //程序显示到最前面
Application.Terminate;
end;
end;procedure TForm1.FormShow(Sender: TObject);
begin
Form1.Caption := 'zzz';
end;
问题是:
如果先运行的哪个程序已经最小化,那么当我再次打开这个程序的时候,先运行的哪个程序便会变为正常显示,但却再也无法最小化了,不知道为什么?请各位大侠指点!
不要在FormCreate里
大概是这个样子
var
hMutex:hwnd;
ret:integer;
begin
Application.Initialize; hmutex:=createMutex(nil,false,'program run once');
ret:=getlasterror;
if ret<>error_already_exists then
begin
Application.CreateForm(TForm_Main, Form_Main);
Application.Run;
end
else application.messagebox('程序已经运行','提醒',MB_OK);
releasemutex(hmutex);
end.
FindWindow(nil, 'zzz'); 我获得是form的句柄,要获得Application的句柄就可以。但是我的Application.Title是随时在变的,不知该怎么获得句柄?
或者通过form的句柄得到Application.Title也可以!请大家帮帮忙!!谢谢!
if hprevinst=0 then
//运行
else
begin
Application.Terminate;
Application.Run;
end;
放在dpr单元里就解决你的问题了
if errNO = ERROR_ALREADY_EXISTS then
begin
hMutex := FindWindow(nil, 'zzz'); //获得程序句柄
ShowWindow(hMutex, SW_NORMAL); //如果最小化则正常显示
SetForegroundWindow(hMutex); //程序显示到最前面
Application.Terminate;
end;改为:if errNO = ERROR_ALREADY_EXISTS then
begin
hMutex := FindWindow(nil, 'zzz'); //获得程序句柄
SendMessage(hMutex, WM_USER + 1000, 0, 0);
Application.Terminate;
end;
现在程序中加入消息处理过程.
procedure HandleIconMessage(var Msg: TMessage); Message WM_USER + 1000;实现部分为:
procedure TForm1.HandleIconMessage(var Msg: TMessage);
begin
Application.Restore; //恢复窗体
Application.BringToFront; //窗体放到最前
end;包你解决
有这样一种情况,一个程序同时运行两个副本。同时查找窗体(都没找到),然后再同时创建窗体。然后都运行起来了。这是以前我遇到的问题。
现在我使用另一种方法来避免重复运行。使用CreateSemaphore( )创建信号量,如果成功则是首次运行,再次运行时,创建同名的信号量会失败。这样可做到万无一失,并且实现也很简单。我对CreateSemaphore( )进行了包装,做成了一个单元。
下载:http://www.ahjoe.net/2/PrevInst.pas
使用示例:
prev: TPrevInst;
begin
prev := TPrevInst.Create();
if prev.FindPrev('TMyAppSema') <> 0 then
begin
prev.Free();
Exit;
end;
Application.Initialize();
......
Application.Run();
end;
prev: TPrevInst;
begin
prev := TPrevInst.Create();
if prev.FindPrev('TMyAppSema') <> 0 then
begin
prev.Free();
Exit;
end;
Application.Initialize();
......
Application.Run();
prev.Free()
end;
注意.dpr文件中还有代码... 同时, 也在这里帖上.............//--------------------------------------------------------------------------------
//Unit1.pas 内容
//--------------------------------------------------------------------------------
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;//-----------------------------------------
//常量定义
//-----------------------------------------
const
Const_Params = 'Window_Delphi_Ex';
WM_CM_RESTORE = WM_USER + 1000; type
TForm1 = class(TForm)
private
{ Private declarations }
procedure GetWM_CM_RESTORE(var Msg: TMessage); Message WM_CM_RESTORE;
public
{ Public declarations }
procedure CreateParams(var Params: TCreateParams); override;
end;var
Form1: TForm1;implementation{$R *.dfm}{ TForm1 }procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.WinClassName := Const_Params;
end;//此消息从 Project1.dpr 中发出
procedure TForm1.GetWM_CM_RESTORE(var Msg: TMessage);
begin
Application.Restore;
Application.BringToFront;
end;end.
//--------------------------------------------------------------------------------
//Project1.dpr 内容
//--------------------------------------------------------------------------------
program Project1;uses
Forms, Windows,
Unit1 in 'Unit1.pas' {Form1};{$R *.res}var
h: HWND;
begin
h := FindWindow(Const_Params, NIL);
if h > 0 then
begin
SetForegroundWindow(h);
SendMessage(h, WM_CM_RESTORE, 0, 0);
Exit;
end;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
var
ZAppName: array[0..127] of char;
Hold: String;
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;