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

  • 主题发起人 主题发起人 Frank_wu
  • 开始时间 开始时间
F

Frank_wu

Unregistered / Unconfirmed
GUEST, unregistred user!
如何制作带有MDI特有功能的SDI界面?
 
如何制作带有MDI特有功能的SDI界面?
 
这种带有MDI特有功能的SDI界面,跟MDI有什么分别?
 
下面API这个函数可以将非MDI窗体设置成MDI的功能,指写子窗体和父窗体,关联成MDI关系:
SetParent(hWndChild Long,hWndNewParent Long)
说明
指定一个窗口的新父(在vb里使用:利用这个函数,vb可以多种形式支持子窗口。例如,可将控件从一个容器移至窗体中的另一个。用这个函数在窗体间移动控件是相当冒险的,但却不失为一个有效的办法。如真的这样做,请在关闭任何一个窗体之前,注意用SetParent将控件的父设回原来的那个)
返回值
Long,前一个父窗口的句柄
参数表
参数 类型及说明
hWndChild Long,子窗口的句柄
hWndNewParent Long,hWndChild的新父
注解
可用这个函数在运行期将vb控件置入容器控件内部(比如将一个按钮设成图象或窗体控件的子窗口),或者将控件从一个容器控件移至另一个。控件移至另一个父后,它的位置将由新父的坐标系统决定。这样一来,有必要重新规定控件的位置,使其能在目标位置显示出来
 
我需要的是在DEPHI中怎么实现
 
转贴Kingron的一些资料

感谢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.
 
//来自:Frank_wu, 时间:2005-9-9 8:04:24, ID:3197661
//我需要的是在DEPHI中怎么实现
//在delphi中直接用这个函数呀,Form1为子窗体,Form2为父窗体
SetParent(Form1.handle,Form2.handle);
 
BOOL MoveWindow(

HWND hWnd, // handle of window
int X, // horizontal position
int Y, // vertical position
int nWidth, // width
int nHeight, // height
BOOL bRepaint // repaint flag
)
 
procedure TForm1.Button1Click(Sender; TObject);
begin
Form2.Parent:=Self;
Form2.Align:=alClient;
Form2.BorderStyle:=bsNone;
end;
以上过程简单地把Form2放到Form1上,成为Form1上的一个控件

procedure TForm1Button2Click(Sender: TObject);
var
Form: TForm;
TabSheet: TTabSheet;
begin
// 创建一个TForm2的实例,并把它放在PageControl1中。
Form:=TForm2.Create(Self);
TabSheet:=TTabSheet.Create(Self);
TabSheet.Caption:=Form.Caption;
TabSheet.PageControl:=PageControl1;
Form.Parent:=TabSheet;
Form.BorderStyle:=bsNone;
Form.Show;
// 创建一个TForm3的实例,并把它放在PageControl1中。
Form:=TForm3.Create(Self);
TabSheet:=TTabSheet.Create(Self);
TabSheet.Caption:=Form.Caption;
TabSheet.PageControl:=PageControl1;
Form.Parent:=TabSheet;
Form.BorderStyle:=bsNone;
Form.Show;
end;
 
后退
顶部