我现n个独立的.exe程序,主窗体为A.exe,有次窗体B.exe,C.exe……程序等,但是已经控制次窗体B.exe,C.exe……程序必须要A程序打开之后才能运行,当然允许B、C……程序重复打开;现在需要控制的是当B、C……程序打开后,不允许关闭主窗体A.exe!
我的自己的想法是:设主窗体A.exe一全局变量S,初始值为0,当次窗体B、C……程序每打开一个时,传递数值1到主窗体A.exe中,并使用主窗体A.exe中全局变量S累加;反之当次窗体B、C……程序每关闭一个时,,传递数值1到主窗体A.exe中,并使用主窗体A.exe中全局变量S递减。然后控制当S<>0时,即不能关闭!
请问能否实现这样的需求?(注:程序之间是相互独立开发的!)
我的自己的想法是:设主窗体A.exe一全局变量S,初始值为0,当次窗体B、C……程序每打开一个时,传递数值1到主窗体A.exe中,并使用主窗体A.exe中全局变量S累加;反之当次窗体B、C……程序每关闭一个时,,传递数值1到主窗体A.exe中,并使用主窗体A.exe中全局变量S递减。然后控制当S<>0时,即不能关闭!
请问能否实现这样的需求?(注:程序之间是相互独立开发的!)
//接收消息的窗口 public
procedure Mymessage(var t:TWmCopyData); message WM_COPYDATA;
{ Public declarations }
end;implementation{$R *.dfm}
var
Form2: TForm2;
S:integer;procedure TForm2.FormCreate(Sender: TObject);
begin
S:=0;
end;procedure TForm2.Mymessage(var t:TWmCopyData);
var
XiaoXi:string;
begin
XiaoXi:=copy(StrPas(t.CopyDataStruct^.lpData),1,8);
if XiaoXi='开启窗体' then
begin
Edit1.text:=inttostr(S+1); //接受数据并显示。
S:=strtoint(Edit1.Text);
end
else
begin
if XiaoXi='关闭窗体' then
begin
Edit1.text:=inttostr(S-1); //接受数据并显示。
S:=strtoint(Edit1.Text);
end
else
Exit;
end;
end;//发送消息的窗口uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;procedure TForm1.FormCreate(Sender: TObject);
var
ds: TCopyDataStruct;
hd: THandle;
begin
ds.cbData :=8; //大小为下面'消息'几个汉字长度
GetMem (ds.lpData, ds.cbData ); //为传递的数据区分配内存
StrCopy (ds.lpData, '开启窗体');
Hd := FindWindow (nil, '程序主窗体'); // 获得接受窗口的句柄(即窗体名称)
if Hd <> 0 then
SendMessage (Hd, WM_COPYDATA, Handle,Cardinal(@ds)) // 发送WM_COPYDATA消息
else
FreeMem (ds.lpData); //释放资源
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
ds: TCopyDataStruct;
hd: THandle;
begin
ds.cbData :=8; //大小为下面'消息'几个汉字长度
GetMem (ds.lpData, ds.cbData ); //为传递的数据区分配内存
StrCopy (ds.lpData, '关闭窗体');
Hd := FindWindow (nil, '程序主窗体'); // 获得接受窗口的句柄(即窗体名称)
if Hd <> 0 then
SendMessage (Hd, WM_COPYDATA, Handle,Cardinal(@ds)) // 发送WM_COPYDATA消息
else
FreeMem (ds.lpData); //释放资源
end;
FillChar(ds,sizeof(ds),0);
程序在运行时先Application.Initialize;....
你的一些特殊的初始化可以在这句之前进行,比如检测其他程序的运行:uses Tlhelp32;
function form1.CanRun(ExefileName: string):Integer;
const
ContinueLoop:BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
Result := 0;
FSnapshothandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
while Integer(ContinueLoop) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile =
UpperCase(ExeFileName))) then
Result := 1;
ContinueLoop := Process32Next(FSnapShotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;
end;
end;
这程序可以在你的主程序中比如叫:form1
在Application.Initialize;
Application.createForm(Tform1, from1);后面写:if form1.CanRun('form1.exe') = 0 then
begin
Application.MessageBox(PChar('XX未启动,程序退出!'), PChar('提示'),0);
form1.Destroy;
Application.Terminate;
end;当然你的其他程序也要用,你可以把它做成一个单独的a.EXE,然后在程序中调a.exe,传递当前应用程序的名字作为参数,然后在a.exe中检测是否有这个进程。
手都打累了
检测是否有实例存在
在form1中定义
function Tform1.ExistsExe: Boolean;
var
hSysMutexHandle: THandle;
begin
Result := False;
hSysMutexHandle := createMutex(nil, False, pchar('MutexforOnlineForm2'));
if hSysMutexHandle <> 0 then
begin
if GetLastError = ERROR_ALREADY_EXISTS then
begin
Result := True;
end;
end;
CloseHandle(hSysMutexHandle);
end;form2为必须启动的那个程序。
在Application.Initialize;
Application.createForm(Tform1, from1);后面写:
if not form1.ExistsExe then
begin
Application.MessageBox(PChar('XX未启动,程序退出!'), PChar('提示'),0);
form1.Destroy;
Application.Terminate;
end;