要求窗体的新增与销毁与PageControl动态对应,即每个PageControl的tab页与各个子窗体一一对应,并且每个PageControl的tab页的标题栏为子窗体的标题。

解决方案 »

  1.   

    在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.
      

  2.   

    每个tabsheet的tag关联各自的form
      

  3.   

    同时修改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.
      

  4.   

    你把窗口的父窗口设置PageControl的TABSHEET,就会对应起来的 
      

  5.   

    创建新窗体,然后创建新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中保存窗体指针地址,销毁时根据这个地址去处理
      

  6.   

    PageControl的对齐设置为向上对齐,高度为20就可以了,子窗口的父窗口设置PageControl的TABSHEET,试了不太稳定,还是用这种方法比较稳定
      

  7.   

    耦合性太强,扩展性不好,使用插件的方式就更加麻烦了。
    不过想法还是值得肯定的。
    可以使用变通的方法如:
    MainForm更换成Application.MainForm就更好了。
      

  8.   

    哦,子窗体直接在tabsheet里啊,
    我都是使用frame做模块,运行时动态创建并嵌入tabsheet的
      

  9.   

    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
      

  10.   

    楼主300分怎么发的?
    为什么我最多只能发100分的帖子?
    不解中...你可以把某一个窗体的parent设置成PageControl的TabSheet,
    再将对齐方式改为alClient,
    TabSheet的标题改为原来的窗体标题。