怎样使才使用户只运行一个应用程序?(100分)

  • 主题发起人 主题发起人 tyuanonline
  • 开始时间 开始时间
T

tyuanonline

Unregistered / Unconfirmed
GUEST, unregistred user!
我写了一个程序, 怎样使才使用户只运行一个应用程序?
 
这个问题都被问烂了。
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;

 
application.title:='aaa';
if findwindow(nil,'bbb')<>0 then
close;
application.title:='bbb';
 
大多数windows内核对象都可以实现这个功能,如互斥体、共享内存、信号量等等,但最方便的
是互斥体。使用方法如bclangren所述。
 
这是在《delphi5开发人员指南》里面的一个单元。
建一个新单元copy过去就行了
以后只要在主窗体里面 uses MultInst; 就可以了!
原来自己的程序什么改动也不用
比上面的多了几个人性化功能
如当发现已经有一个程序在运行了
会使以前那个程序弹到最前面
unit MultInst;

interface

const
MI_QUERYWINDOWHANDLE = 1;
MI_RESPONDWINDOWHANDLE = 2;

MI_ERROR_NONE = 0;
MI_ERROR_FAILSUBCLASS = 1;
MI_ERROR_CREATINGMUTEX = 2;

// Call this function to determine if error occurred in startup.
// Value will be one or more of the MI_ERROR_* error flags.
function GetMIError: Integer;

implementation

uses Forms, Windows, SysUtils;

const
UniqueAppStr = 'DDG.I_am_the_Eggman!';

var
MessageId: Integer;
WProc: TFNWndProc;
MutHandle: THandle;
MIError: Integer;

function GetMIError: Integer;
begin
Result := MIError;
end;

function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint):
Longint; stdcall;
begin
Result := 0;
// If this is the registered message...
if Msg = MessageID then
begin
case wParam of
MI_QUERYWINDOWHANDLE:
// A new instance is asking for main window handle in order
// to focus the main window, so normalize app and send back
// message with main window handle.
begin
if IsIconic(Application.Handle) then
begin
Application.MainForm.WindowState := wsNormal;
Application.Restore;
end;
PostMessage(HWND(lParam), MessageID, MI_RESPONDWINDOWHANDLE,
Application.MainForm.Handle);
end;
MI_RESPONDWINDOWHANDLE:
// The running instance has returned its main window handle,
// so we need to focus it and go away.
begin
SetForegroundWindow(HWND(lParam));
Application.Terminate;
end;
end;
end
// Otherwise, pass message on to old window proc
else
Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end;

procedure SubClassApplication;
begin
// We subclass Application window procedure so that
// Application.OnMessage remains available for user.
WProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC,
Longint(@NewWndProc)));
// Set appropriate error flag if error condition occurred
if WProc = nil then
MIError := MIError or MI_ERROR_FAILSUBCLASS;
end;

procedure DoFirstInstance;
// This is called only for the first instance of the application
begin
// Create the mutex with the (hopefully) unique string
MutHandle := CreateMutex(nil, False, UniqueAppStr);
if MutHandle = 0 then
MIError := MIError or MI_ERROR_CREATINGMUTEX;
end;

procedure BroadcastFocusMessage;
// This is called when there is already an instance running.
var
BSMRecipients: DWORD;
begin
// Prevent main form from flashing
Application.ShowMainForm := False;
// Post message to try to establish a dialogue with previous instance
BSMRecipients := BSM_APPLICATIONS;
BroadCastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE,
@BSMRecipients, MessageID, MI_QUERYWINDOWHANDLE,
Application.Handle);
end;

procedure InitInstance;
begin
SubClassApplication; // hook application message loop
MutHandle := OpenMutex(MUTEX_ALL_ACCESS, False, UniqueAppStr);
if MutHandle = 0 then
// Mutex object has not yet been created, meaning that no previous
// instance has been created.
DoFirstInstance
else
BroadcastFocusMessage;
end;

initialization
MessageID := RegisterWindowMessage(UniqueAppStr);
InitInstance;
finalization
// Restore old application window procedure
if WProc <> Nil then
SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(WProc));
if MutHandle <> 0 then CloseHandle(MutHandle); // Free mutex
end.

 
拜托,搜索一下。 :)

还有一个使用 atom的技术搞定的办法。
 
后退
顶部