DELPHI 动态创建的控件以及其上包含的子控件,用什么方式可以保存到文件中.....

解决方案 »

  1.   

    for i := 0 Component.count -1 do 
      begin
      end;
    通过遍历倥件的方法 把符合要求的控件保存即可
      

  2.   

    var
      fs: TFileStream;
    begin
      fs := TFileStream.Create('C:\test.dat', fmOpenWrite);
      fs.WriteComponent(Self);
      fs.Free;
    end;
    这个就是把dfm文件记录的内容以二进制方法保存,保存的原则是以Self为根,递归写入它所有Component的属性及事件值。var
      fs: TFileStream;
    begin
      fs := TFileStream.Create('C:\test.dat', fmOpenRead);
      fs.ReadComponent(Self);
      fs.Free;
    end;
    这个就是把它读出来,原则跟上面一样。
      

  3.   

    比如我动态创建了PANEL,在PANEL上又建立了几个BUTTON,WriteComponent应该保存些什么属性?
    在用READComponent时是不是也要动态创建这些控件,然后把保存的属性重新读进去?
      

  4.   

    比如我动态创建了PANEL,在PANEL上又建立了几个BUTTON,WriteComponent应该保存些什么属性?
    在用READComponent时是不是也要动态创建这些控件,然后把保存的属性重新读进去?
      

  5.   

    WriteComponent会把Button的类名,你修改过的属性都保存下来,在ReadComponent的时候读到TButton它就会动态创建这个对象,然后读取到它的属性,并给属性赋值,所以这个组件树会以Form为根节点重新创建起来,而你只需要调用一下这个方法而已。
      

  6.   

    var
    i:integer;
    begin
    for i:=0 to controlcount-1 do
    begin
      controls[i].name
      controls[i].left
      controls[i].top
      controls[i].width
      controls[i].heigth
      controls[i].parent //这个非常重要
    (**存的时候,存以上几个属性或更多创建的时候要注意parent的问题!**)
    end;
    end;
      

  7.   

    当一个PANEL上有BUTTON,另一个PANEL上有IMAGE时,在读出控件的时候会出现"Property TabOrder does not exist"这是什么原因引起的?写这些控件时应该怎样才能让读出来的正确啊??哪位大师可以详细说一下么??谢谢了...
      

  8.   

    //打开
    procedure TForm1.Button3Click(Sender: TObject);  var
        S: TStream;
        i,j: Integer;
        Map: TImage;
        PanelM: TPanel;
        panel:Tpanel;    buttona:tbutton;
        {buttonb:tbutton;
        buttonc:tbutton;
        buttond:tbutton;
        buttone:tbutton;}    tmpStrList, btnStrList: TStrings;
        tmpStr, tmpLeft, tmpTop, tmpWidth, tmpHeight, tmpFileName: String;
        btnStr, btnLeft, btnTop, btnWidth, btnHeight, bntFileName: string;
        bLeft,bTop,bWidth,bHeight:String;
      begin
        for i := 0 to RichEditNew.ControlCount - 1 do
        begin
          RichEditNew.Controls[0].Free;
        end;
        if OpenDialog1.Execute then
        begin
          tmpFileName := OpenDialog1.FileName;
          bntFileName:=tmpFileName+'bnt';
          tmpStrList := TStringList.Create;
          btnStrList:=TStringList.Create;
          S := TFileStream.Create(tmpFileName, fmOpenRead);
          S.ReadComponent(RichEditNew);
          tmpStrList.LoadFromFile(ExtractFilePath(tmpFileName) + ExtractFileName(tmpFileName)+'.info');
          for i := 0 to tmpStrList.Count - 1 do
          try
            tmpStr := tmpStrList.Strings[i];
            tmpLeft := ListValue(tmpStr, 2);
            tmpTop := ListValue(tmpStr, 3);
            tmpWidth := ListValue(tmpStr, 4);
            tmpHeight := ListValue(tmpStr, 5);        Panel := TPanel.Create(Self);
            Panel.Parent := RichEditNew;
            Panel.Name := 'myPanel' + IntToStr(i+1);        Map := TImage.Create(Self);
            Map.Parent := Panel;
            Map.Name := 'myMap' + IntToStr(i+1);        S.ReadComponent(Panel);
            S.ReadComponent(Map);        Panel.Parent := RichEditNew;
            Panel.Left := StrToInt(tmpLeft);
            Panel.Top := StrToInt(tmpTop);
            Panel.Width := StrToInt(tmpWidth);
            Panel.Height := StrToInt(tmpHeight);        Map.OnMouseMove := FMouseMove;
            Map.Parent := Panel;
          except
            Map.Free;
            Panel.Free;
          end;btnStrList.LoadFromFile(ExtractFilePath(bntFileName) + ExtractFileName(bntFileName)+'.info');
          for j := 0 to btnStrList.Count - 1 do
          try
            btnStr := btnStrList.Strings[j];
            btnLeft := ListValue(btnStr, 2);
            btnTop := ListValue(btnStr, 3);
            btnWidth := ListValue(btnStr, 4);
            btnHeight := ListValue(btnStr, 5);
            bLeft:=ListValue(btnStr,6);
            bTop:=ListValue(btnStr,7);
            bWidth:=ListValue(btnStr,8);
            bHeight:=ListValue(btnStr,9);        PanelM := TPanel.Create(Self);
            PanelM.Parent := RichEditNew;
           // PanelM.Name := 'myPanelm' + IntToStr(j+1);
            panelM.onMouseDown:=PanelMMouseDown;        buttona:=Tbutton.Create(self);
            buttona.parent:=panelm;
           // buttona.Name :='mybuttona'+inttostr(j+1);        S.ReadComponent(Panelm);
            S.ReadComponent(buttona);        PanelM.Parent := RichEditNew;
            Panelm.Left := StrToInt(btnLeft);
            Panelm.Top := StrToInt(btnTop);
            Panelm.Width := StrToInt(btnWidth);
            Panelm.Height := StrToInt(btnHeight);        buttona.Parent:=panelm;
            buttona.Left:=StrToInt(bLeft);
            buttona.Top:=strtoint(btop);
            buttona.width:=strtoint(bwidth);
            buttona.height:=strtoint(bheight);      except
            buttona.Free;
            {buttonb.Free;
            buttonc.Free;
            buttond.Free;
            buttone.Free; }
            Panelm.Free; 
          end;
            S.Free;
          end;   
     // end;
    end;procedure TForm1.Button4Click(Sender: TObject);//保存
    var   
        S: TStream;
        i,j: Integer;
        tmpStrList: TStrings;//记录图片的位置
        btnStrList: TStrings;//记录PANEL上BUTTON的位置
        tmpFileName,bntFileName: String;
      begin
          if SaveDialog1.Execute then
          begin
            tmpFileName := SaveDialog1.FileName;
            bntFileName:=tmpFileName+'bnt';
              //   保存元件到文件   
            tmpStrList := TStringList.Create;
            btnstrList:=TStringList.Create;
            S := TFileStream.Create(tmpFileName, fmCreate);
            try
              S.WriteComponent(RichEditNew);
              for i := 0 to RichEditNew.ControlCount - 1 do
              begin
                if RichEditNew.Controls[i] is TPanel then
                begin
                  S.WriteComponent(TPanel(RichEditNew.Controls[i]));
                  if  TPanel(RichEditNew.Controls[i]).Controls[0] is TImage then
                    begin
                      S.WriteComponent(TImage(TPanel(RichEditNew.Controls[i]).Controls[0]));
                      tmpStrList.Add('myPanel'+IntToStr(i + 1)+','+'myImage'+IntToStr(i + 1)+','
                                        +IntToStr(TPanel(RichEditNew.Controls[i]).Left)+','
                                        +IntToStr(TPanel(RichEditNew.Controls[i]).Top)+','
                                        +IntToStr(TPanel(RichEditNew.Controls[i]).Width)+','
                                        +IntToStr(TPanel(RichEditNew.Controls[i]).Height));
                    end;
                end;
              end;
              tmpStrList.SaveToFile(ExtractFilePath(tmpFileName) + ExtractFileName
                (tmpFileName)+'.info');
                        for j := 0 to RichEditNew.ControlCount - 1 do
              begin
                if RichEditNew.Controls[j] is TPanel then
                begin
                 // S.WriteComponent(TPanel(RichEditNew.Controls[j]));
                //for j:= 0 to Tpanel(RichEditNew.controls[i]).controlcount -1 do
                //begin
                if  TPanel(RichEditNew.Controls[j]).Controls[0] is Tbutton then
                  begin
                    S.WriteComponent(Tbutton(TPanel(RichEditNew.Controls[j]).Controls[0]));
                    btnStrList.Add('myPanelM'+IntToStr(j + 1)+','+'mybuttona'+IntToStr(j + 1)+','
                                        +IntToStr(TPanel(RichEditNew.Controls[j]).Left)+','
                                        +IntToStr(TPanel(RichEditNew.Controls[j]).Top)+','
                                        +IntToStr(TPanel(RichEditNew.Controls[j]).Width)+','
                                        +IntToStr(TPanel(RichEditNew.Controls[j]).Height)+','
                                        +IntToStr(Tbutton(TPanel(RichEditNew.Controls[j]).controls[0]).Left)+','
                                        +IntToStr(Tbutton(TPanel(RichEditNew.Controls[j]).controls[0]).Top)+','
                                        +IntToStr(Tbutton(TPanel(RichEditNew.Controls[j]).controls[0]).Width)+','
                                        +IntToStr(Tbutton(TPanel(RichEditNew.Controls[j]).controls[0]).Height));
                  end;
                end;
              end;
              btnStrList.SaveToFile(ExtractFilePath(bntFileName) + ExtractFileName
                  (bntFileName)+'.info');
              //end;
            finally
              S.Free;
              tmpStrList.Free;
              btnStrList.Free;
            end;
          end;
      end;
      

  9.   

    上面是保存和打开控件的代码..不知道什么原因.在打开时提示IMAGE的BevelOuter属性不存在.
      

  10.   

    第一次做这个,都没有思路,是上网找一些读写的方法.那对于动态MAP和BUTTON的读写应该怎么样?
      

  11.   

    动态地插入图片和加入按键.它们都被放在PANEL上.这些动态的PANEL的PARENT是RichEditnew.实现它们的保存和打开.其中图片和按键的插入个数都是不确定的.
      

  12.   

    这种需求你就别用什么WriteComponent了,你又不用保存组件的所有属性
    直接用XML节点表示这些控件就行了
    如:
    <?xml version="1.0" encoding="UTF-8">
    <Control ClassName="RichEditNew">
    <Control ClassName="Image">
    <Left>100<Left>
    <Top>12<Top>
    <Width>200<Width>
    <Height>400<Height>
    </Control>
    <Control ClassName="Button">
    <Left>20<Left>
    <Top>12<Top>
    <Width>20<Width>
    <Height>40<Height>
    </Control>
    </Control>
    保存的时候递归遍历RichEditNew的所有子控件,写入到XML,读的时候就递归遍历XML节点,创建控件设置属性即可
      

  13.   

    其实,你如果创建组件的时候指定Owner是那个Panel的话,你要保存Panel的控件只要用
    WriteComponent(Panel1)就可以了
    而你要还原Panel的控件,只要ReadComponent(Panel1)就可以了
    但是前提是你要保存的控件的Owner是Panel1。
    例如:
    btn1 := TButton.Create(Panel1);
    btn1.Parent := Panel1;
    Img1 := TImage.Create(Panel1);
    Img1.Parent := Panel1;
    这样你调用WriteComponent(Panel1)就会把btn1和Img1写入流。
    而使用ReadComponent(Panel1)就会创建btn1和Img1,并把它的Parent设置为Panel1
      

  14.   

    给你个示例:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      img: TImage;
      btn: TButton;
      fs: TFileStream;
    begin
      img := TImage.Create(Panel1);
      img.Parent := Panel1;
      img.SetBounds(0, 0, 100, 100);
      btn := TButton.Create(Panel1);
      btn.Parent := Panel1;
      btn.SetBounds(100, 100, 80, 20);
      fs := TFileStream.Create('C:\a.dat', fmCreate or fmOpenWrite);
      fs.WriteComponent(Panel1);
      fs.Free;
    end;procedure TForm1.Button2Click(Sender: TObject);
    var
      fs: TFileStream;
    begin
      RegisterClasses([TImage, TButton]);
      fs := TFileStream.Create('C:\a.dat', fmOpenRead);
      fs.ReadComponent(Panel1);
      fs.Free;
    end;
      

  15.   

    lake_cx 不知道你有没试过,按照你说的方法.PANEL上的BUTTON在读出来的时候就显示不出来了..
      

  16.   

    我试过了,可以显示出来的,只是Image因为没有装载图片,是看不到的,你把Panel1弄大一点看看
      

  17.   

    button在创建的时候看的到,保存后再打开就没有了.只剩下一个PANEL
      

  18.   

    哦,对了.我是把PANEL也换成动态生成的.你那样写是打的开.但是如果PANEL也是动态生成的.那BUTTON就看不到了..
      

  19.   

    我写好的那个程序根据网上动态保存的方法.RichEditnew上动态创建Panel1,Panel1上又有动态创建的Image,Panel2,Panel2上又有动态创建的几个Button(可多个..点击一次产生一个).当RichEditnew只有Panel1(也就是只有图片)或只有多个Panel2(也就是只有按钮)都可以保存和正确读出.但是如果RichEditnew上同时有图片和按钮时.读出来的就不正确了.会提示Image的一些属性不存在.如TabOrder.
      

  20.   

    Panel动态生成也没问题,但不推荐这么做,因为Panel的Owner就不能确定了。
    procedure TForm1.Button1Click(Sender: TObject);
    var
      img: TImage;
      btn: TButton;
      fs: TFileStream;
    begin
      img := TImage.Create(Panel1);
      img.Parent := Panel1;
      img.SetBounds(0, 0, 100, 100);
      btn := TButton.Create(Panel1);
      btn.Parent := Panel1;
      btn.SetBounds(100, 100, 80, 20);
      fs := TFileStream.Create('C:\a.dat', fmCreate or fmOpenWrite);
      fs.WriteComponent(Panel1);
      fs.Free;
    end;procedure TForm1.Button2Click(Sender: TObject);
    var
      fs: TFileStream;
      pnl: TPanel;
    begin
      RegisterClasses([TImage, TButton, TPanel]);
      fs := TFileStream.Create('C:\a.dat', fmOpenRead);
      pnl := fs.ReadComponent(nil) as TPanel;
      pnl.Parent := Self;
      fs.Free;
    end;
      

  21.   

    就是一个Panel用于保存图片.另一个Panel用于保存一组的按钮(并可产生多个这样按钮).当这两种Panel同时出现时保存出现问题..分开只出现一个可以正确..
      

  22.   

    你不会把两个Panel都放到一个Panel上,然后保存这一个Panel啊
      

  23.   

    而且两个Panel分开保存和同时保存肯定不会有什么问题的
    你自己写个Demo来试,试不出来再贴出来,你原来那代码太乱了
      

  24.   

    我是为了要生成多组的按钮.如果保存在一个Panel上那就不合题意了.
      

  25.   


    function ComponentToString(Component: TComponent): string;var
      BinStream:TMemoryStream;
      StrStream: TStringStream;
      s: string;
    begin
      BinStream := TMemoryStream.Create;
      try
        StrStream := TStringStream.Create(s);
        try
          BinStream.WriteComponent(Component);
          BinStream.Seek(0, soFromBeginning);
          ObjectBinaryToText(BinStream, StrStream);
          StrStream.Seek(0, soFromBeginning);
          Result:= StrStream.DataString;
        finally
          StrStream.Free;    end;
      finally
        BinStream.Free
      end;
    end;function StringToComponent(Value: string): TComponent;
    var
      StrStream:TStringStream;
      BinStream: TMemoryStream;
    begin
      StrStream := TStringStream.Create(Value);
      try
        BinStream := TMemoryStream.Create;
        try
          ObjectTextToBinary(StrStream, BinStream);
          BinStream.Seek(0, soFromBeginning);
          Result := BinStream.ReadComponent(nil);    finally
          BinStream.Free;
        end;
      finally
        StrStream.Free;
      end;
    end;