在d7环境下,用向导创建一个MDI工程,然后增加pagecontrol控件等,代码事件改为如下:unit MAIN;interfaceuses Windows, SysUtils, Classes, Graphics, Forms, Controls, Menus, StdCtrls, Dialogs, Buttons, Messages, ExtCtrls, ComCtrls, StdActns, ActnList, ToolWin, ImgList, SUITabControl, SUIPageControl;type TMainForm = class(TForm) MainMenu1: TMainMenu; File1: TMenuItem; FileNewItem: TMenuItem; FileOpenItem: TMenuItem; FileCloseItem: TMenuItem; Window1: TMenuItem; Help1: TMenuItem; N1: TMenuItem; FileExitItem: TMenuItem; WindowCascadeItem: TMenuItem; WindowTileItem: TMenuItem; WindowArrangeItem: TMenuItem; HelpAboutItem: TMenuItem; OpenDialog: TOpenDialog; FileSaveItem: TMenuItem; FileSaveAsItem: TMenuItem; Edit1: TMenuItem; CutItem: TMenuItem; CopyItem: TMenuItem; PasteItem: TMenuItem; WindowMinimizeItem: TMenuItem; StatusBar: TStatusBar; ActionList1: TActionList; EditCut1: TEditCut; EditCopy1: TEditCopy; EditPaste1: TEditPaste; FileNew1: TAction; FileSave1: TAction; FileExit1: TAction; FileOpen1: TAction; FileSaveAs1: TAction; WindowCascade1: TWindowCascade; WindowTileHorizontal1: TWindowTileHorizontal; WindowArrangeAll1: TWindowArrange; WindowMinimizeAll1: TWindowMinimizeAll; HelpAbout1: TAction; FileClose1: TWindowClose; WindowTileVertical1: TWindowTileVertical; WindowTileItem2: TMenuItem; ToolBar2: TToolBar; ToolButton1: TToolButton; ToolButton2: TToolButton; ToolButton3: TToolButton; ToolButton4: TToolButton; ToolButton5: TToolButton; ToolButton6: TToolButton; ToolButton9: TToolButton; ToolButton7: TToolButton; ToolButton8: TToolButton; ToolButton10: TToolButton; ToolButton11: TToolButton; ImageList1: TImageList; pc: TPageControl; tv1: TTreeView; procedure FileNew1Execute(Sender: TObject); procedure FileOpen1Execute(Sender: TObject); procedure HelpAbout1Execute(Sender: TObject); procedure FileExit1Execute(Sender: TObject); procedure pcChange(Sender: TObject); procedure pcMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { Private declarations } procedure CreateMDIChild(const Name: string); public { Public declarations } Formarray : array[0..127] of TForm; len:Integer; MouseClose:Boolean; end;var MainForm: TMainForm;implementation{$R *.dfm}uses CHILDWIN, about;procedure TMainForm.CreateMDIChild(const Name: string); var Child: TMDIChild; tab :TTabSheet; begin { create a new MDI child window } if len>15 then begin ShowMessage('你打开的窗口太多了'); Exit; end; Child := TMDIChild.Create(Application); Child.Caption := Name; Formarray[len]:=Child; tab :=TTabSheet.Create(pc); tab.PageControl :=pc; tab.Caption := Name; len:=len+1; if FileExists(Name) then Child.Memo1.Lines.LoadFromFile(Name); end;procedure TMainForm.FileNew1Execute(Sender: TObject); begin CreateMDIChild('NONAME123456789-' + IntToStr(MDIChildCount + 1));end;procedure TMainForm.FileOpen1Execute(Sender: TObject); begin if OpenDialog.Execute then CreateMDIChild(OpenDialog.FileName); end;procedure TMainForm.HelpAbout1Execute(Sender: TObject); begin AboutBox.ShowModal; end;procedure TMainForm.FileExit1Execute(Sender: TObject); begin Close; end;procedure TMainForm.pcChange(Sender: TObject); begin if pc.PageCount > 0 then begin Formarray[pc.ActivePageIndex].Show; end; end;procedure TMainForm.pcMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var Index , temp , I: Integer; begin temp := 0; Index := 0; MouseClose:=True; if (Button = mbLeft) and (ssDouble in Shift) then begin if pc.PageCount > 0 then begin Index := pc.IndexOfTabAt(X, Y); if assigned(Formarray[Index]) then begin Formarray[Index].Close; len:=len-1; temp := Index; if Index < pc.PageCount - 1 then begin for I := Index to pc.PageCount - 1 do Formarray[i] := Formarray[i + 1]; end; temp := pc.PageCount - 1; Formarray[temp] := nil; pc.Pages[Index].Free;// .Destroy; end; end; end; MouseClose:=False; end;end.
每个tabsheet的tag关联各自的form
同时修改CHILDWIN单元的关闭事件unit CHILDWIN;interfaceuses Windows, Classes, Graphics, Forms, Controls, StdCtrls;type TMDIChild = class(TForm) Memo1: TMemo; procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end;implementationuses MAIN;{$R *.dfm}procedure TMDIChild.FormClose(Sender: TObject; var Action: TCloseAction); var temp ,I,J : Integer; begin Action := caFree; if MainForm.MouseClose then Exit; temp := 0; for I := 0 to MainForm.pc.PageCount - 1 do begin if MainForm.ActiveMDIChild = MainForm.Formarray[I] then begin MainForm.len:=MainForm.len-1; if I < MainForm.pc.PageCount - 1 then begin for J := I to MainForm.pc.PageCount - 1 do MainForm.Formarray[J] := MainForm.Formarray[J + 1]; end; temp := MainForm.pc.PageCount - 1; MainForm.Formarray[temp] := nil; MainForm.pc.Pages[I].Destroy; Break; end; end; end;end.
你把窗口的父窗口设置PageControl的TABSHEET,就会对应起来的
创建新窗体,然后创建新tab,将窗体的parent指向为tab//根据名称检查tab是否已经存在 function FindTab(pagecontrol:TPageControl;tabName:string):integer; var i:integer; begin Result := -1; for i := 0 to pagecontrol.PageCount - 1 do begin if pagecontrol.Pages[i].Name = tabName then begin Result := i; Break; end; end; end;procedure FormToSheet(pagecontrol:TPageControl;frm:TForm;tabName,tabCaption:string); var i:integer; tab:TTabSheet; begin i := FindTab(pagecontrol,tabName); if i > 0 then begin pagecontrol.Pages[i].TabVisible := True; pagecontrol.ActivePageIndex := i; end else begin tab := TTabSheet.Create(pagecontrol); tab.Name := tabName; tab.Caption := tabCaption; tab.PageControl := pagecontrol; pagecontrol.ActivePage := tab; frm.ParentWindow := tab.Handle; frm.Tag :=tab.TabIndex; tab.InsertControl(frm); frm.Show; end; frm.Show; end; 销毁时,可以查找tab上的组件,找到窗体,然后freeandnil,当然也可以通过指针处理,在tag中保存窗体指针地址,销毁时根据这个地址去处理
implementation uses Unit5,Unit2,Unit4; {$R *.dfm} procedure TForm1.N4Click(Sender: TObject); var ts: TRzTabSheet; Form2:TForm2; i,j:integer; begin i:=0; j:=0; if TForm2(FindComponent('form2')) = nil then begin ts:= TRzTabSheet.Create(Self); ts.PageControl := RzPageControl1; Form2 := TForm2.Create(Self); ts.Caption:='form2'; Form2.Parent := ts; Form2.Align := alClient; Form2.BorderStyle := bsNone; Form2.Show; Rzpagecontrol1.ActivePage:=ts; end else begin for i:=0 to rzpagecontrol1.PageCount -1 do begin if rzpagecontrol1.Pages.Caption ='form2' then begin j:=i; break; end; end; RzPageControl1.ActivePage :=RzPageControl1.Pages[j]; end; end; procedure TForm1.N3Click(Sender: TObject); var ts: TRzTabSheet; Form4:TForm4; i,j:integer; begin i:=0; j:=0; if TForm4(FindComponent('form4')) = nil then begin ts:= TRzTabSheet.Create(Self); ts.PageControl := RzPageControl1; Form4 := TForm4.Create(Self); ts.Caption:='form4'; Form4.Parent := ts; Form4.Align := alClient; Form4.BorderStyle := bsNone; Form4.Show; Rzpagecontrol1.ActivePage:=ts; end else begin for i:=0 to rzpagecontrol1.PageCount -1 do begin if rzpagecontrol1.Pages.Caption ='form4' then begin j:=i; break; end; end; RzPageControl1.ActivePage :=RzPageControl1.Pages[j]; end; end; procedure TForm1.RzPageControl1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var index:integer; begin if (Button = mbLeft) and (ssDouble in Shift) then begin Index := RzPageControl1.TabAtPos (X, Y); if rzpagecontrol1.PageCount >1 then begin if index<rzpagecontrol1.PageCount-1 then begin RzPageControl1.Pages[Index].Free; RzPageControl1.ActivePage :=RzPageControl1.Pages[index]; end else begin RzPageControl1.Pages[Index].Free; RzPageControl1.ActivePage :=RzPageControl1.Pages[index-1]; end;
end else RzPageControl1.Pages[Index].Free; end; end; ////////////////注意下载三方控件RzPageControl1 要原程序 就留E-Mial
StdCtrls, Dialogs, Buttons, Messages, ExtCtrls, ComCtrls, StdActns,
ActnList, ToolWin, ImgList, SUITabControl, SUIPageControl;type
TMainForm = class(TForm)
MainMenu1: TMainMenu;
File1: TMenuItem;
FileNewItem: TMenuItem;
FileOpenItem: TMenuItem;
FileCloseItem: TMenuItem;
Window1: TMenuItem;
Help1: TMenuItem;
N1: TMenuItem;
FileExitItem: TMenuItem;
WindowCascadeItem: TMenuItem;
WindowTileItem: TMenuItem;
WindowArrangeItem: TMenuItem;
HelpAboutItem: TMenuItem;
OpenDialog: TOpenDialog;
FileSaveItem: TMenuItem;
FileSaveAsItem: TMenuItem;
Edit1: TMenuItem;
CutItem: TMenuItem;
CopyItem: TMenuItem;
PasteItem: TMenuItem;
WindowMinimizeItem: TMenuItem;
StatusBar: TStatusBar;
ActionList1: TActionList;
EditCut1: TEditCut;
EditCopy1: TEditCopy;
EditPaste1: TEditPaste;
FileNew1: TAction;
FileSave1: TAction;
FileExit1: TAction;
FileOpen1: TAction;
FileSaveAs1: TAction;
WindowCascade1: TWindowCascade;
WindowTileHorizontal1: TWindowTileHorizontal;
WindowArrangeAll1: TWindowArrange;
WindowMinimizeAll1: TWindowMinimizeAll;
HelpAbout1: TAction;
FileClose1: TWindowClose;
WindowTileVertical1: TWindowTileVertical;
WindowTileItem2: TMenuItem;
ToolBar2: TToolBar;
ToolButton1: TToolButton;
ToolButton2: TToolButton;
ToolButton3: TToolButton;
ToolButton4: TToolButton;
ToolButton5: TToolButton;
ToolButton6: TToolButton;
ToolButton9: TToolButton;
ToolButton7: TToolButton;
ToolButton8: TToolButton;
ToolButton10: TToolButton;
ToolButton11: TToolButton;
ImageList1: TImageList;
pc: TPageControl;
tv1: TTreeView;
procedure FileNew1Execute(Sender: TObject);
procedure FileOpen1Execute(Sender: TObject);
procedure HelpAbout1Execute(Sender: TObject);
procedure FileExit1Execute(Sender: TObject);
procedure pcChange(Sender: TObject);
procedure pcMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations } procedure CreateMDIChild(const Name: string);
public
{ Public declarations }
Formarray : array[0..127] of TForm;
len:Integer;
MouseClose:Boolean;
end;var
MainForm: TMainForm;implementation{$R *.dfm}uses CHILDWIN, about;procedure TMainForm.CreateMDIChild(const Name: string);
var
Child: TMDIChild;
tab :TTabSheet;
begin
{ create a new MDI child window }
if len>15 then
begin
ShowMessage('你打开的窗口太多了');
Exit;
end;
Child := TMDIChild.Create(Application);
Child.Caption := Name; Formarray[len]:=Child;
tab :=TTabSheet.Create(pc);
tab.PageControl :=pc;
tab.Caption := Name;
len:=len+1; if FileExists(Name) then Child.Memo1.Lines.LoadFromFile(Name);
end;procedure TMainForm.FileNew1Execute(Sender: TObject);
begin
CreateMDIChild('NONAME123456789-' + IntToStr(MDIChildCount + 1));end;procedure TMainForm.FileOpen1Execute(Sender: TObject);
begin
if OpenDialog.Execute then
CreateMDIChild(OpenDialog.FileName);
end;procedure TMainForm.HelpAbout1Execute(Sender: TObject);
begin
AboutBox.ShowModal;
end;procedure TMainForm.FileExit1Execute(Sender: TObject);
begin
Close;
end;procedure TMainForm.pcChange(Sender: TObject);
begin
if pc.PageCount > 0 then
begin
Formarray[pc.ActivePageIndex].Show;
end;
end;procedure TMainForm.pcMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Index , temp , I: Integer;
begin
temp := 0;
Index := 0;
MouseClose:=True;
if (Button = mbLeft) and (ssDouble in Shift) then
begin
if pc.PageCount > 0 then
begin
Index := pc.IndexOfTabAt(X, Y);
if assigned(Formarray[Index]) then
begin
Formarray[Index].Close;
len:=len-1;
temp := Index;
if Index < pc.PageCount - 1 then
begin
for I := Index to pc.PageCount - 1 do
Formarray[i] := Formarray[i + 1];
end;
temp := pc.PageCount - 1;
Formarray[temp] := nil;
pc.Pages[Index].Free;// .Destroy;
end;
end;
end;
MouseClose:=False;
end;end.
TMDIChild = class(TForm)
Memo1: TMemo;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;implementationuses MAIN;{$R *.dfm}procedure TMDIChild.FormClose(Sender: TObject; var Action: TCloseAction);
var
temp ,I,J : Integer;
begin
Action := caFree;
if MainForm.MouseClose then Exit;
temp := 0;
for I := 0 to MainForm.pc.PageCount - 1 do
begin
if MainForm.ActiveMDIChild = MainForm.Formarray[I] then
begin
MainForm.len:=MainForm.len-1;
if I < MainForm.pc.PageCount - 1 then
begin
for J := I to MainForm.pc.PageCount - 1 do
MainForm.Formarray[J] := MainForm.Formarray[J + 1];
end;
temp := MainForm.pc.PageCount - 1;
MainForm.Formarray[temp] := nil;
MainForm.pc.Pages[I].Destroy;
Break;
end;
end;
end;end.
function FindTab(pagecontrol:TPageControl;tabName:string):integer;
var
i:integer;
begin
Result := -1;
for i := 0 to pagecontrol.PageCount - 1 do
begin
if pagecontrol.Pages[i].Name = tabName then
begin
Result := i;
Break;
end;
end;
end;procedure FormToSheet(pagecontrol:TPageControl;frm:TForm;tabName,tabCaption:string);
var
i:integer;
tab:TTabSheet;
begin
i := FindTab(pagecontrol,tabName);
if i > 0 then
begin
pagecontrol.Pages[i].TabVisible := True;
pagecontrol.ActivePageIndex := i;
end
else
begin
tab := TTabSheet.Create(pagecontrol);
tab.Name := tabName;
tab.Caption := tabCaption;
tab.PageControl := pagecontrol;
pagecontrol.ActivePage := tab;
frm.ParentWindow := tab.Handle;
frm.Tag :=tab.TabIndex;
tab.InsertControl(frm);
frm.Show;
end;
frm.Show;
end;
销毁时,可以查找tab上的组件,找到窗体,然后freeandnil,当然也可以通过指针处理,在tag中保存窗体指针地址,销毁时根据这个地址去处理
不过想法还是值得肯定的。
可以使用变通的方法如:
MainForm更换成Application.MainForm就更好了。
我都是使用frame做模块,运行时动态创建并嵌入tabsheet的
uses Unit5,Unit2,Unit4;
{$R *.dfm}
procedure TForm1.N4Click(Sender: TObject);
var
ts: TRzTabSheet;
Form2:TForm2;
i,j:integer;
begin
i:=0;
j:=0;
if TForm2(FindComponent('form2')) = nil then
begin
ts:= TRzTabSheet.Create(Self);
ts.PageControl := RzPageControl1;
Form2 := TForm2.Create(Self);
ts.Caption:='form2';
Form2.Parent := ts;
Form2.Align := alClient;
Form2.BorderStyle := bsNone;
Form2.Show;
Rzpagecontrol1.ActivePage:=ts;
end
else
begin
for i:=0 to rzpagecontrol1.PageCount -1 do
begin
if rzpagecontrol1.Pages.Caption ='form2' then
begin
j:=i;
break;
end;
end;
RzPageControl1.ActivePage :=RzPageControl1.Pages[j];
end;
end;
procedure TForm1.N3Click(Sender: TObject);
var
ts: TRzTabSheet;
Form4:TForm4;
i,j:integer;
begin
i:=0;
j:=0;
if TForm4(FindComponent('form4')) = nil then
begin
ts:= TRzTabSheet.Create(Self);
ts.PageControl := RzPageControl1;
Form4 := TForm4.Create(Self);
ts.Caption:='form4';
Form4.Parent := ts;
Form4.Align := alClient;
Form4.BorderStyle := bsNone;
Form4.Show;
Rzpagecontrol1.ActivePage:=ts;
end
else
begin
for i:=0 to rzpagecontrol1.PageCount -1 do
begin
if rzpagecontrol1.Pages.Caption ='form4' then
begin
j:=i;
break;
end;
end;
RzPageControl1.ActivePage :=RzPageControl1.Pages[j];
end;
end;
procedure TForm1.RzPageControl1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
index:integer;
begin
if (Button = mbLeft) and (ssDouble in Shift) then
begin
Index := RzPageControl1.TabAtPos (X, Y);
if rzpagecontrol1.PageCount >1 then
begin
if index<rzpagecontrol1.PageCount-1 then
begin
RzPageControl1.Pages[Index].Free;
RzPageControl1.ActivePage :=RzPageControl1.Pages[index];
end
else
begin
RzPageControl1.Pages[Index].Free;
RzPageControl1.ActivePage :=RzPageControl1.Pages[index-1];
end;
end
else
RzPageControl1.Pages[Index].Free;
end;
end;
////////////////注意下载三方控件RzPageControl1 要原程序 就留E-Mial
为什么我最多只能发100分的帖子?
不解中...你可以把某一个窗体的parent设置成PageControl的TabSheet,
再将对齐方式改为alClient,
TabSheet的标题改为原来的窗体标题。