在MDI的dll子窗口中,主窗口如何知道已经创建了哪些子窗口,避免重复创建子窗口?(100分)

  • 主题发起人 主题发起人 jacklin
  • 开始时间 开始时间
J

jacklin

Unregistered / Unconfirmed
GUEST, unregistred user!
照一般的方法,我用mdichildcount得到的子窗口数总是为0,我想知道的是已经调用了dll
窗口里的创建子窗口过程,如何才能知道已经创建了哪些子窗口呢?
 
在调用dll之内前用变量把要创建的窗口记录下来不就行了
 
在DLL中引用Application对象,然后对Application.MainForm.MDIChildCount进行判断!
如:
Procedure CallForm(MainApp:TApplication);stdcall;
var
ptr:pLongInt;
I:Integer;
Begin
ptr:=@(Application.MainForm);
ptr^:=LongInt(MainApp.MainForm);
For I:=0 To MainApp.MainForm.MDIChildCount-1 Do
If MainApp.MainForm.MDIChild.ClassName='TForm1' Then Exit;
Form1:=TForm1.Create(MainApp.MainForm);
End;
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus, ToolWin, ComCtrls, Buttons, jpeg, ExtCtrls;

type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
ToolBar1: TToolBar;
StatusBar1: TStatusBar;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
ToolButton1: TToolButton;
SpeedButton4: TSpeedButton;
SpeedButton5: TSpeedButton;
SpeedButton6: TSpeedButton;
ToolButton2: TToolButton;
SpeedButton7: TSpeedButton;
SpeedButton8: TSpeedButton;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
private
FClientInstance:TFarProc;
FPrevClientProc:TFarProc;
procedure ClientWndProc(var Message: TMessage);

{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit2, Unit3;

{$R *.DFM}
procedure OpenForm(FormClass: TFormClass; var fm; AOwner:TComponent);
var
I:Integer;
Child:TForm;
begin
for I:=0 to Screen.FormCount -1 do
if Screen.Forms.ClassType=FormClass then
begin
Child:=Screen.Forms;
if Child.WindowState=wsMinimized then
ShowWindow(Child.handle,SW_SHOWNORMAL)
else
ShowWindow(Child.handle,SW_SHOWNA);
if (not Child.Visible) then
Child.Visible:=True;
Child.BringToFront;
Child.Setfocus;
TForm(fm):=Child;
Exit;
end;
Child:=TForm(FormClass.NewInstance);
TForm(fm):=Child;
Child.Create(AOwner);
end;


procedure TForm1.ClientWndProc(var Message: TMessage);//这一段是在主窗口放背景图可以去掉
var
Dc:hDC;
Row:Integer;
Col:Integer;
begin
with Message do
case Msg of
WM_ERASEBKGND:
begin
Dc := TWMEraseBkGnd(Message).Dc;
for Row := 0 to ClientHeight div Image1.Picture.Height do
for Col := 0 to ClientWidth div Image1.Picture.Width do
BitBlt(Dc,Col * Image1.Picture.Width,
Row * Image1.Picture.Height,
Image1.Picture.Width,
Image1.Picture.Height,
Image1.Picture.Bitmap.Canvas.Handle,
0,
0,
SRCCOPY);
Result := 1;
end;
else
Result := CallWindowProc(FPrevClientProc,
ClientHandle,
Msg,
wParam,
lParam);
end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
FClientInstance:=MakeObjectInstance(ClientWndProc);
FPrevClientProc:=Pointer(GetWindowLong(ClientHandle,GWL_WNDPROC));
SetWindowLong(ClientHandle,GWL_WNDPROC, LongInt(FClientInstance));
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
OpenForm(TForm2,Form2,self);
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
OpenForm(TForm3,Form3,self);
end;

end.
 
在创建之前先判断是不是已经创建了该窗体!
 
判断FORM是否已经创建并显示(适用于所有类型的form)
function FormExists(FormClassName:string):boolean;
var
i:integer;
sClassName:String;
begin
Result :=false;
sClassName:= UpperCase(FormClassName);
for i:=0 to Screen.FormCount-1 do
if UpperCase(Screen.Forms.ClassName) = sClassName then
begin
Result := true;
Screen.Forms.bringToFront;
exit;
end;
end;

然后可以用该函数
if PubFun2000.FormExists('TForm1') then exit;
frm := TForm1.Create(parentapp.mainForm);//ParentForm);
frm.show;
其中parentapp为你指定的主程序
 
我采用rainxy2002的方法了。
 
后退
顶部