如何制作带有MDI特有功能的SDI界面?(135分)

  • 主题发起人 主题发起人 新黛飞
  • 开始时间 开始时间

新黛飞

Unregistered / Unconfirmed
GUEST, unregistred user!
各位高手请帮忙!

MDI窗口功能强大,窗口切换方便快捷但不安全。
SDI窗口软件体积小,运行快捷,但窗口切换不方便。
我想将它们综合以下,像Word2000那样,虽然是SDI但在他的窗口菜单中确有“全部重排”
窗体列表这些MDI才有的功能。
我还发现EmEditor也是这样,但他好象是用C做的。不知Delphi能否做到这些?

谢谢
 
把子窗口嵌入到form上
 
能具体说说吗?谢谢[:)]
 
SDI是 @_@ ?
 
Single Document Interface
 
(转)
控制Delphi的窗口显示位置
--------------------------------------------------------------------------------

  在使用Delphi进行工作时,也许需要将多个独立的窗口放在一个主窗口中,但又不打算使用多文档界面(MDI),那么下面介绍的方法可能对你会有所启发。直接控制窗口的产生过程,并指定它的容器对象的Parent属性或ParentWindow属性。

  使用容器。这个容器是指可以容纳目标窗口的控制元件(Windows Control),它可以是窗口、面板、页面控制等VCL对象。一个窗口在类别注册后将调用API函数CreateWindow,函数调用时需要传递一个WndParent即父窗口的句柄。Delphi已将该函数封装在TcustomForm对象的CreateParams过程里面了。原函数的参数也封装在一个TCreateparams的记录类型里面。在IDE里,我们重载它,然后在容器控制的单元中调用即可。假设要将Form2和Form3放在Form1的Panel1中,可以这样做:

  Form2单元接口部分

  type TForm2=Class(TForm)

  pubic procedure Loaded;override;

   procedure CreateParams(var Params:TParams);override;

   end;

  实现部分

   procedure TForm2.Loaded;

   begin

  inherited Loaded;

  Visible:=Flase;

  Position:=poDefault;

  BorderIcons:=[];

  BorderStyle:=bsNone;

  //注意此时的窗口边界样式和图标,改变这两个值,看看有无其它变化。

  HandNeeded;

  //如果窗口不存在,就生成它。

  SetBouds(0,0,Width,Height);

  //不改变窗口原来的大小。

   end;

   procedure TForm2.CreateParams(var Params:TCreateParams);

   begin

  inherited CreateParams(Params);

  Params.WndParent:=(Owner as TForm).Handle;//指定父窗口的句柄

  Params.Style:=WS—CHILD or WS—CLIPSIBLINGS;//注意窗口的样式

  params.X:=0;

  params.Y:=0;

   end;

  Form3单元类似于Form2单元。注意理解Loaded方法的重载,以及和Create方法的区别,先后顺序的不同。

  假设Form1单元的客户区上面是控制面板Panel1,下方有两个按扭分别控制Form2和Form3的显示。单元如下:

  Form1接口部分

  type

   TForm1=Class(TForm)

  Panel1:TPanel;

  Form2Button:TButton;

  Form3Button:TButton;

  procedure FormCreate(Sender:TObject);

  procedure FormShow(Sender:TObject);

  procedure FormResize(Sender:TObject);

  procedure Form2ButtonOnClick(Sender:TObject);

  procedure Form3ButtonOnClick(Sender:TObject);

   end;

  Form1实现部分(需要引用Form2和Form3单元)

  procedure TForm1.FormCreate(Sender:TObject);

  begin

   Form2:=TForm2.Create(Self);

  //实际生成窗口。

   Form3:=TForm3.Create(Self);

   Form2.Show;

   Form3.Show;

  end;

  procedure FormShow(Sender:TObject);

  begin

   Form2.BringToFront;

   //将该窗口放置在最上面。

  end;

  procedure FormResize(Sender:TObject);

  begin

  MoveWindow(Form2.Handle,Panel1.Left,Panel1.Top,

   Panel1.ClientWidth,Panel1.ClientHeight,True);//跟随着面板的大小和位置

  MoveWindow(Form3.Handle,Panel1.Left,Panel1.Top,

   Panel1.ClientWidth,Panel1.ClientHeight,True);

  end;

  procedure Form2ButtonOnClick(Sender:TObject);

  begin

   Form2.BringToFront;

  end;

  procedure Form3ButtonOnClick(Sender:TObject);

  begin

   Form2.BringToFront;

  end;

  这样,Form2和Form3由Form1控制生成,而成为Form1的两个子窗口。为了达到目标,还应该从项目窗口选项(Project|Options|Forms)中将两个子窗口从自动生成(Auto_Create)列表中移到有效窗口(Available Forms)列表中。Form1单元中的关键代码是Form?:=TForm?.Create(Self);

  我们看一下另外一种方法。同上面一样生成三个窗口,而且将Form2和Form3设定为有效窗口。在按扭的事件句柄中控制Form2和Form3的显示,而且可以不计较Form2和Form3的边界样式。

  procedure TForm1.Button1Click(Sender: TObject);

  begin

   if Form2=nil then//判断窗口是否已经存在,如果不存在则重新生成它。

   begin

  Form2:=TForm2.Create(Self);

  Form2.Parent:=Panel1;

   end;

   Form2.WindowState:=wsMaximized;

   Form2.Show;

   Form2.BringToFront;

  end;

  procedure TForm1.Button2Click(Sender: TObject);

  begin

   if Form3=nil then

   begin

  Form3:=TForm3.Create(Self);

  Form3.Parent:=Panel1;

   end;

   Form3.WindowState:=wsMaximized;

   Form3.Show;

   Form3.BringToFront;

  end;

  和前面的方法相比,使用Parent属性来控制子窗口要容易一些。

{但是这样“全部重排”,“窗体列表”这些MDI才有的功能需要自己实现,
还没有找到方便的方法,如果有的话告诉我一声哦 )
 
多人接受答案了。
 
可否接着讨论? 这种做法如果FORM2或FORM3中有EDIT等控件, 将无法在其中输入资料, 即
FORM2和FORM3 永远无法取得焦点. 怎么办????
 
怎么样实现重排的功能?
 
后退
顶部