如何让应用程序知道自己已经执行了!

Zboy 1999-12-29 06:06:00
请教各位高人,如何让Delphi编写的应用程序知道它已经执行了,从而避免重复执行。
(我写的某个应用程序被人在其快捷方式上多次点击导致死机)。
请赐教,万分感谢。
...全文
2136 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
riceball 1999-12-31
  • 打赏
  • 举报
回复
u can use Windows Message func.
like this:

program xxxx;

uses
Forms,
Windows,
SysUtils,
MainForm in 'MainForm.pas' {frmMain: TfrmMain};

{$R *.RES}

var
Previous: HWND;
{This code, to allow file association and open doubleclicked file in the running instance of app
was written by Andrius Adamonis}
function EnumWindowsCallback(Handle: HWND; Param: LPARAM): Boolean; stdcall;
function IsMyClass: Boolean;
var
ClassName : array[0..30] of Char;
FormClassName: string;
begin
GetClassName(Handle, ClassName, 30);
Result := (StrIComp(ClassName, 'TfrmMain') = 0) and { this finds my window, TfrmMain }
(SendMessage(Handle, WM_FINDINSTANCE, 0, 0) = MyUniqueConst); { this checks if this is really my application }
end;
begin
Result := not IsMyClass; { needs True to continue }
if not Result { = MyClass } then Previous := Handle;
end;

var
ATOM: TAtom;
begin
Previous := 0;
ATOM := 0;
EnumWindows(@EnumWindowsCallback, 0);
if Previous <> 0 then
begin
PostMessage(Previous, WM_RESTOREAPP, 0, 0);
Exit;
end;
Application.Initialize;
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
end.

unit MainForm;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ShellApi, StdActns, ActnList, ImgList, Menus, ToolWin, ComCtrls;

const
WM_RESTOREAPP = WM_USER + 3;
MyUniqueConst = $118388;

var
WM_FINDINSTANCE: Integer;

type

TfrmMain = class(TForm)
......
protected
procedure WMRestoreApp(var Msg: TMessage); message WM_RESTOREAPP;
public
procedure DefaultHandler(var message); override;
end;

....

procedure TfrmMain.DefaultHandler(var message);
var
S: string;
begin
with TMessage(message) do
if Msg = WM_FINDINSTANCE then
begin
Result := MyUniqueConst;
end
else inherited DefaultHandler(message);
end;

procedure TfrmMain.WMRestoreApp(var Msg: TMessage);
begin
ShowApplication;
end;

initialization
WM_FINDINSTANCE := RegisterWindowMessage('MyForm: find previous instance');
if WM_FINDINSTANCE = 0 then raise Exception.Create('Initialization failed');

end.
BlackSword 1999-12-30
  • 打赏
  • 举报
回复
如果程序是VC做的话,CMutex我决得是最好的选择!
barton 1999-12-30
  • 打赏
  • 举报
回复
//项目文件
...

begin
Application.initialation;
if CreateMutex then begin
Application.CreateForm(Form1, TForm1);
Application.Run;
end else
DestroyMutex;
end;

//主窗体文件

...

implementation

var
Mutex: hWnd;

function CreateMutex: Boolean;
var
PrevInstHandle: THandle;
AppTitle: PChar;
begin
AppTitle := StrAlloc(100);
StrPCopy(AppTitle, Application.Title);
Result := True;
Mutex := Windows.CreateMutex(nil, False, AppTitle);
if (GetLastError = ERROR_ALREADY_EXISTS) or (Mutex = 0) then begin
Result := False;
SetWindowText(Application.Handle, '');
PrevInstHandle := FindWindow(nil, AppTitle);
if PrevInstHandle <> 0 then begin
if IsIconic(PrevInstHandle) then
ShowWindow(PrevInstHandle, SW_RESTORE)
else
BringWindowToTop(PrevInstHandle);
SetForegroundWindow(PrevInstHandle);
end;
if Mutex <> 0 then
Mutex := 0;
end;
StrDispose(AppTitle);
end;

procedure DestroyMutex;
begin
if Mutex <> 0 then
CloseHandle(Mutex);
end;

menxin 1999-12-29
  • 打赏
  • 举报
回复
互斥对象(CreateMutex)应该是最好的方法,但还有很多方法,例如运用注册表等等。
hephaestus 1999-12-29
  • 打赏
  • 举报
回复

微软说:创建Mutex!还给Mutex起个一个怪名字.也才几个API调用而已

有时窗口的Text是变化的,用FindWindow写不出来,而且这样也不专业!
tide 1999-12-29
  • 打赏
  • 举报
回复
有两种方法:
1,用 api 函数 FindWindow .如果你窗口的title 为“test"

HWND FirsthWnd,FirstChildhWnd;
if(FindWindow(NULL,"test"))
{

FirstChildWnd=GetLastActivePopup(FirsthWnd);
BringWindowToTop(FirsthWnd);
if(FirsthWnd!=FirstChildWnd)
BringWindowToTop(FirstChildWnd);

ShowWindow(FirsthWnd,SW_SHOWNORMAL);
return false;
}

2. 创建一个mutex. 用 CreateMutex; 比较复杂一点儿。如果第一种方法不能满足要求再联系。

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧