我想让我的应用程序只允许一次
请问怎么做啊
还有就是 如果我有父窗体和子窗体
父窗体的button1 事件如下:
Form2:=TForm2.create(self);
我按了button几次,它就创建了几个form2
我想做的是
如果form2 已经创建了就不创建了
直接show就可以了
请问怎么做啊
还有就是 如果我有父窗体和子窗体
父窗体的button1 事件如下:
Form2:=TForm2.create(self);
我按了button几次,它就创建了几个form2
我想做的是
如果form2 已经创建了就不创建了
直接show就可以了
解决方案 »
- 怎么作一个实时显示摄像头拍摄内容的程序,而且最好是不考虑摄像头差异的,通用的
- 关于Params修改不完全的问题!
- 请问D7的IdPOP31,怎么用啊(怎么写收邮件的).
- 请问如何做一个当某个目录有文件时就执行某段代码?
- ActiveForm上控件怎么了(懂的人一看就明白)?
- 天佑华夏!请大家签名支持抗击“非典”!
- 怎样使ActivexForm 变透明? 真的没人知道吗?
- 如何用DLEPHI编DOS代码?那里有这方面的资料找。
- 讨论个问题,有人知道怎么做透明窗体码,当然,不是把透明值设为0
- 关于BDE中Paradox的设置问题
- 深度探讨ansichar转16进制字符问题。请高手解答。最好有代码贴出。
- 如何增加明细记录(思路)
在主窗口(即程序创建的第一个窗口)中interface节加入
const
CM_RESTORE = WM_USER + $1000; {自定义的“恢复”消息}
MYAPPNAME = "My Delphi Program";
并在Form的定义的public节中加入
procedure CreateParams(var Params: TCreateParams); override;
Procedure RestoreRequest(var message: TMessage); message CM_RESTORE;
在implementation节中加入
{指定窗口名称}
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.WinClassName := MYAPPNAME;
end;
{处理“恢复”消息}
procedure TForm1.RestoreRequest(var message: TMessage);
begin
if IsIconic(Application.Handle) = TRUE then
Application.Restore
else
Application.BringToFront;
end;
经过以上修改,程序的主窗口的类名已经被指定了,这是进行判断的基础。一般在程序刚开始运行的时候进行判断,所以还要对DPR文件进行修改。
2、对DPR文件的改动
在 uses 节中添加 windows、messages这两个单元加入下列语句,注意两个文件中常量CM_RESTORE和MYAPPNAME的定义必须一致
const
CM_RESTORE = WM_USER + $1000; {自定义的“恢复”消息}
MYAPPNAME = "My Delphi Program";
var
RvHandle : hWnd;
将下列语句插到程序最前部(在Application.Initialize之前)
RvHandle := FindWindow(MYAPPNAME, NIL);
if RvHandle > 0 then
begin
PostMessage(RvHandle, CM_RESTORE, 0, 0);
Exit;
end;
这段程序的意思是如果找到一个类名相同的窗口,则向该窗口发送一个消息,并退出,而本例中原窗口收到该消息后会自动激活或从图标还原,从而达到了避免二次运行且能自动调出前一例程的目的。
检测程序是否运行
在某些情况下,我们编写的应用程序同时只能有一个实例在内存中运行,例如服务器程序、需要独占某设备的程序,甚至我们仅仅是让程序同时只有一个实例运行(如UltraEdit就是这样做的,让你不能同时运行多个UltraEdit)。要实现此功能,需要在程序中加一点判断的代码,在Windows 95或Win32环境下的Delphi版本中实现的程序如下:
按Ctrl+F12键,选择Project1,加入下列语句
program Project1;
uses
windows, {加入该句才能调用函数}
Forms,
Unit1 in 'Unit1.pas'{Form1};
{$R *.RES}
const classname='TForm1'; {声明为主窗体的类名}
var handle:integer; {变量}
begin
{-----------------主要为该判断部分----------------------}
handle:=findwindow(classname,nil);{查找是否有此类的窗体}
if handle<>0 then {不为0则程序已运行}
begin
messagebox(0,'该程序已经有一个在运行中!','运行',0);{提示程序已运行}
halt; {退出程序}
end;
{------------------------------------------------------}
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Form2:=TForm2.create(self);
Form2.show;这样就OK啦
begin
CreateMutex(nil, True, 'hlyy');
if GetLastError = ERROR_ALREADY_EXISTS then
begin
MessageBox(0, '某某系统已经运行了', '运行错误!',
MB_ICONERROR);
Halt;
end;
引用windows单元
if Not assigned(frmChild) then
frmChild:=TfrmChild.create(Self);
try
frmChild.ShowModel;
finally
frmChild.free;
frmChild:=Nil;
end;
已经创建的就不会再创建,只能Show出来
begin
H :=FindWindow('TForm1', nil);
if H=0 then
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end
else
begin
showmessage('程序已经启动');
SetActiveWindow(H);
end;
用这段试试
program programname;
{$R *.res}
uses
......
var
hMutex: THandle;
begin
hMutex:= CreateMutex(nil, true, PChar(ExtractFileName(Application.ExeName)));
if GetLastError = ERROR_ALREADY_EXISTS then
begin
ReleaseMutex(hMutex);
Halt;
end;
Application.Initialize;
.....
Application.Run;
end.
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;Const
CM_Restore=WM_User+$1000;{自定义的"恢复"消息}
MyAppName='MyDelphiProgram';
type
TForm1 = class(TForm)
private
{ Private declarations }
public
Procedure CreateParams(var Params:TCreateParams);override;
Procedure RestoreRequest(var message:TMessage);message CM_Restore;
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}{指定窗口名称}
Procedure TForm1.CreateParams(var Params:TCreateParams);
begin
Inherited CreateParams(Params);
Params.WinClassName:=MyAppName;
end;{处理“恢复”消息}
Procedure TForm1.RestoreRequest(var message:TMessage);
begin
if IsIconic(Application.Handle)=TRUE then
Application.Restore
else
Application.BringToFront;
end;end.
{$R *.res}
uses
......
var
hMutex: THandle;
begin
hMutex:= CreateMutex(nil, true, PChar(ExtractFileName(Application.ExeName)));
if GetLastError = ERROR_ALREADY_EXISTS then
begin
ReleaseMutex(hMutex);
Halt;
end;
Application.Initialize;
.....
Application.Run;
end.
Form2:=TForm2.create(self);
Form2.show;
if Form2 <> nilthen
Form2.show
else
Exit;
if Form2 = nil then Form2 := TForm2.Create(Self)else
Form2.Show;
工程文件实现的话如下:program Project1;uses
Windows,
Messages,
Forms,
Unit1 in 'Unit1.pas' {Form1};{$R *.RES}var
AppWnd, MainWnd: HWND; I: Integer;
ParamString: string; CopyDataStruct: TCopyDataStruct;
begin AppWnd := FindWindow('TApplication', 'This is my project title');
if AppWnd <> 0 then
begin
if IsIconic(AppWnd) then
ShowWindow(AppWnd, SW_RESTORE)
else
SetForegroundWindow(AppWnd);
Exit;
end; Application.Initialize;
Application.Title := 'This is my project title';
Application.CreateForm(TForm1, Form1);
Application.Run;
procedure tform1.button1click;
begin
form2.free;
application.creatform(tform2,form2);
form2.show;
end;
在interface 下,implementation上声明一个公用方法: function Execute: TForm2;implementationvar
frm: TForm2 = nil;function Execute: TForm2;
begin
if frm = nil then
frm := TForm2.Create(Application);
Result := frm;
end;当然,不要忘记:
procedure TForm2.FormDestroy(Sender: TObject);
begin
FreeAndNil(frm);
end;
frmChild:=TfrmChild.create(TForm2,Form2);
try
Form2.ShowModel;
finally
Form2.free;
Form2:=Nil;
end;
注意:把STR_UNIQUE设置为你的字符串,可以生成一个GUDI,每个软件使用不同的GUID就不会有错//==============================================================================
// Unit Name: MultInst
// Author : ysai
// Date : 2003-05-20
// Purpose : 解决应用程序多实例问题
// History :
//==============================================================================//==============================================================================
// 工作流程
// 程序运行先取代原有向所有消息处理过程,然后广播一个消息.
// 如果有其它实例运行,收到广播消息会回发消息给发送程序,并传回它自己的句柄
// 发送程序接收到此消息,激活收到消息的程序,然后关闭自己
//==============================================================================
unit MultInst;interfaceuses
Windows ,Messages, SysUtils, Classes, Forms;implementationconst
STR_UNIQUE = '{1E1084F3-A7FA-49B0-BEF4-CBF1F5451962}';
MI_ADDMESSAGE = 0; //新增一条消息
MI_ACTIVEAPP = 1; //激活应用程序
MI_GETHANDLE = 2; //取得句柄var
iMessageID : Integer;
OldWProc : TFNWndProc;
MutHandle : THandle;
BSMRecipients : DWORD;function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint):
Longint; stdcall;
begin
Result := 0;
if Msg = iMessageID then
begin
case wParam of
MI_ACTIVEAPP: //激活应用程序
if lParam<>0 then
begin
//收到消息的激活前一个实例
//为什么要在另一个程序中激活?
//因为在同一个进程中SetForegroundWindow并不能把窗体提到最前
if IsIconic(lParam) then
OpenIcon(lParam);
ShowWindow(lParam,SW_SHOW);
SetForegroundWindow(lParam);
//终止本实例
Application.Terminate;
end;
MI_GETHANDLE: //取得程序句柄
begin
PostMessage(HWND(lParam), iMessageID, MI_ACTIVEAPP,
Screen.ActiveForm.Handle);
end;
end;
end
else
Result := CallWindowProc(OldWProc, Handle, Msg, wParam, lParam);
end;procedure InitInstance;
begin
//取代应用程序的消息处理
OldWProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC,
Longint(@NewWndProc))); //打开互斥对象
MutHandle := OpenMutex(MUTEX_ALL_ACCESS, False, STR_UNIQUE);
if MutHandle = 0 then
begin
//建立互斥对象
MutHandle := CreateMutex(nil, False, STR_UNIQUE);
end
else begin
Application.ShowMainForm := False;
//已经有程序实例,广播消息取得实例句柄
BSMRecipients := BSM_APPLICATIONS;
BroadCastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE,
@BSMRecipients, iMessageID, MI_GETHANDLE,Application.Handle);
end;
end;initialization
//注册消息
iMessageID := RegisterWindowMessage(STR_UNIQUE);
InitInstance;finalization
//还原消息处理过程
if OldWProc <> Nil then
SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(OldWProc)); //关闭互斥对象
if MutHandle <> 0 then CloseHandle(MutHandle);end.
我试了,只要把代码贴进去就ok!
就能限制程序只运行一次.
至于第二个问题简单.
if not Assigned(Form2) Form2 := TForm2.Create(Application);
Form2.Show;
然后在Form2.CloseQuery中加
Form2 := nil;