首页  编辑  

非主窗体的MDI Form如何创建子窗体

Tags: /超级猛料/VCL/Form,窗体/MDI界面窗体/   Date Created:

感谢Nhdj(nhdj0014@sina.com)提出这个问题。

---------------------------

我有一个程序是这样:一个主窗体,一个mdi主窗体,一个mdi子窗体,当我在主窗体中打开mdi主窗然后再新建一个mdi子窗体时就出现错误,提示"Cannot create form.No Mdi forms are currently active.".请你帮忙解决一下!不胜感激!!!

---------------------------

我们知道,在Delphi中,如果一个MDI Form非主窗体的话,我们就不能创建任何MDI Child Form,实在是遗憾,不过还是可以解决的。

Kingron查看了VCL的源代码,发现在创建窗体的时候,系统会检测MainForm是不是nil和MainForm.ClientHandle是不是nil,对于MainForm就是MDI Form的,因为有ClientHandle,所以没有问题,但是对于非MDI的主窗体,其ClientHandle为nil,因此出现错误。知道原因之后,就好办了,因此我们只要把MainForm.ClientHandle修改称自己的MDI Form的ClientHandle即可,要做这个工作,非指针莫属了!!!

在你的MDI MainForm的创建子窗体的代码中改成类似的即可。我测试通过,不过是否有什么后遗症之类,我就无法保证了,还有错误,请来信告知。

var

  pHandle:^THandle;

begin

  pHandle :=@Application.MainForm.ClientHandle;

  pHandle^:=ClientHandle;      ///关键在这一句!

  with Tform3.Create(Application) do show;

end;

***************************************************

另外在老毛子的站点查找(2002.11.22)到的,也可以参考一下:

-----------------------------------------------------------------

unit Unit3;

interface

uses

 Windows, Messages, SysUtils, Classes, Graphics, Controls,

Forms, Dialogs;

type

 TForm3 = class(TForm)

 private

   { Private declarations }

 protected

   procedure CreateWindowHandle(const Params: TCreateParams);

override;

   procedure DestroyWindowHandle; override;

 public

   { Public declarations }

 end;

var

 Form3: TForm3;

implementation

uses Unit2, Consts;

{$R *.DFM}

procedure TForm3.CreateWindowHandle(const Params: TCreateParams);

var

 CreateStruct: TMDICreateStruct;

begin

 if (FormStyle = fsMDIChild) and not (csDesigning in

ComponentState) then

 begin

   if (Form2 = nil) or (Form2.ClientHandle = 0)

   then raise EInvalidOperation.CreateRes(SNoMDIForm);

   with CreateStruct do

   begin

     szClass := Params.WinClassName;

     szTitle := Params.Caption;

     hOwner := HInstance;

     X := Params.X;

     Y := Params.Y;

     cX := Params.Width;

     cY := Params.Height;

     style := Params.Style;

     lParam := Longint(Params.Param);

   end;

   WindowHandle := SendMessage(Form2.ClientHandle,

     WM_MDICREATE, 0, Longint(@CreateStruct));

   //Include(FFormState, fsCreatedMDIChild);

 end else inherited CreateWindowHandle(Params);

end;

procedure TForm3.DestroyWindowHandle;

begin

 SendMessage(Form2.ClientHandle, WM_MDIDESTROY, Handle, 0);

 inherited DestroyWindowHandle;

end;

end.

-----------------------------------------------------------------