防止程序的多次运行 (恳请看过代码在回答) 当第二次运行的时候,我要得不是提示,而是让第一次运行的程序变成当前窗口(Restore)(100分)

  • 主题发起人 主题发起人 fanwendou
  • 开始时间 开始时间
F

fanwendou

Unregistered / Unconfirmed
GUEST, unregistred user!
//再program 中的代码
program Project1;
uses
Windows,
Messages,
Forms,
SysUtils,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
H:THandle;
const WM_RESTOREFORM=WM_USER+1206;
begin
CreateMutex(nil, True, '1232');
if GetLastError = ERROR_ALREADY_EXISTS then
begin
H:=FindWindow('TForm1',nil);
if H<>0 then
postMessage(H,WM_RESTOREFORM,0,0);
Exit;
// 退出
end;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
//在form1中的代码
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
const WM_RESTOREFORM=WM_USER+1206;
type
TForm1 = class(TForm)
private
procedure RestoreForm(var Msg:TMessage);message WM_RESTOREFORM;
//恢复窗体
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure tform1.RestoreForm(var Msg: TMessage);
begin

Application.Restore;
end;
end.
为什么我RestoreForm得不到运行,希望你运行以后在回答.
 
我的做法,呵呵!互相学习可以老大就不用了,网上学的
program Project1;
uses
Forms,
Windows,
Unit1 in 'Unit1.pas' {Form1},
uShortCut in 'uShortCut.pas';
{$R *.res}
var
MutexHandle: THandle;
hPrevInst: Boolean;
begin
MutexHandle := CreateMutex(nil, True, 'MyProgramAppMutex');
if MutexHandle <> 0 then
begin
if GetLastError = ERROR_ALREADY_EXISTS then
begin
MessageBox(0, '该程序已经运行!.',
'MyProgram',
MB_ICONHAND);
hPrevInst := True;
CloseHandle(MutexHandle);
Halt;
end
else
hPrevInst := False;
end
else
hPrevInst := False;
Application.Initialize;
Application.Title := 'MyProgram';
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
 
对 啊。说不是很明白,是否用过一次,关了再用也算,还是已经有一个在运行不能第二个?
 
if H <> 0 then
PostMessage(H, WM_RESTOREFORM, 0, 0);
Sleep(10);
//or
if H <> 0 then
SendMessage(H, WM_RESTOREFORM, 0, 0);
 
不同进程间发消息必须RegisterWindowMessage
http://www.delphibbs.com/keylife/iblog_show.asp?xid=604
 
var
hMutex: THandle;

begin

hMutex := CreateMutex(nil, False, 'ArmyLife');
if WaitForSingleObject(hMutex, 0) = wait_TimeOut then

begin
application.messagebox( '程序已經運行,'提示!',mb_OK);
Exit;
end;
Application.Initialize;
Application.CreateForm(TUserLog, UserLog);
Application.CreateForm(TFmain, Fmain);
Application.Run;
end.
 
to aizhuzhu
我得意思CreateMutex()这个函数可以表达
 
if OpenMutex(MUTEX_ALL_ACCESS,True,'P_Star')>0 then
begin
MessageBox(0,'程序已经在运行','错误',MB_OK);
end
else
begin
CreateMutex(nil,True,'P_Star');
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
CloseHandle(OpenMutex(MUTEX_ALL_ACCESS,True,'P_Star'));
end;
上面这段程序写在工程文件里,代替
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
 
to :yidianhong
当第二次运行的时候,我要得不是提示,而是让第一次运行的程序变成当前窗口(Restore)
 
>>问题:防止程序的多次运行(那个能解决认他做我老大)
呵呵,我可不愿意要这样的小弟,本来查查资料再自己调试一下就可以解决的问题非要来问,有这样的小弟那还不累死?!
轻舞肥羊的方法是正道
 
to zswang
sendmessage()我已经用过了 .但还是RestoreForm得不到运行呀!!
请不指教!
 
我一直这么用
http://www.delphiun.com/article_view.asp?id=137
 
to godelphi2004
教训的是,
但这个问题我已经纠缠一天多,才敢来问,不用 "那个能解决认他做我老大",高手会出来吗?
我试了"轻舞肥羊"的不知道你注意到程序在状态栏上的变化了吗?
 
uses这个单元即可
  unit RunOne;
  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 = 'ShuanYuan_SoftWare';
  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;
  proceduredo
FirstInstance;
  // 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.
  do
FirstInstance
   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.
 
其实这个问题很简单。下面这个是最简单的:(uses windows,forms)
function AppRunOnce: Boolean;
var
HW: Thandle;
sClassName, sTitle: string;
begin
sClassName := Application.ClassName;
sTitle := Application.Title;
Application.Title := '{3D4110B7-F0B0-466A-9C92-DA997006D542}';
//更改当前Application的标题
HW := FindWindow(pchar(sClassName), pchar(sTitle));
SetForegroundWindow(HW);
ShowWindow(HW, SW_SHOWDEFAULT);
(*如果发现已有实例在运行,则关闭自己*)
if HW <> 0 then
Application.Terminate;
Application.Title := sTitle;
//恢复app标题
Result := HW <> 0 //存在则返回true,无返回false
end;

调用方法如下:
if AppRunOnce then
Halt;
 
防止一个程序多次运行,只需在程序开始写段代码,用API来检查你的窗口标题就可以了,代码网上有很多
 
这么简单的问题:
在unit1中
const
hfck=wm_user+$1000;
appname='youname';
procedure createparams(var params:tcreateparams);override;
procedure restorerequest(var msg:tmessage);message hfck;
////
procedure TFrmMain.createparams(var params:tcreateparams);
begin
inherited
createparams(params);
params.WinClassName:=appname;
end;
procedure TFrmMain.restorerequest(var msg:tmessage);
begin
if isiconic(application.Handle )=true then
application.Restore
else
application.BringToFront;
end;

工程部分:
const
hfck=wm_user+$1000;
appname='youname';
var
myhandle:hwnd;
myhandle:=findwindow(appname,nil);
if myhandle>0 then
begin
postmessage(myhandle,hfck,0,0);
exit;
end;
以上的效果就是,当第二次运行程序的时候,如果程序已经打开.那么把第一次的程序做为当前窗口
一直这样写
我是老大,给分吧;哈哈
 
//写在主程序中
const
hfck=wm_user+$1000;
appname='youname';
procedure createparams(var params:tcreateparams);override;
procedure restorerequest(var msg:tmessage);message hfck;

procedure TFrmMain.createparams(var params:tcreateparams);
begin
inherited
createparams(params);
params.WinClassName:=appname;
end;
procedure TFrmMain.restorerequest(var msg:tmessage);
begin
if isiconic(application.Handle )=true then
application.Restore
else
application.BringToFront;
end;

//写在程序的工程部分
const
hfck=wm_user+$1000;
appname='youname';
var
myhandle:hwnd;
myhandle:=findwindow(appname,nil);
if myhandle>0 then
begin
postmessage(myhandle,hfck,0,0);
exit;
end;

第二种方法
program Project1;
uses
Forms,windows,
Unit1 in 'Unit1.pas' {Form1};
var hw:hwnd;
{$R *.RES}
begin
Application.Initialize;
application.title:='test';//名字自己定义
hw:=createmutex(nil,false,'test');
if getlasterror<>error_already_exists then
begin
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
end.
 
多人接受答案了。
 
后退
顶部