TMYPanel控件设计期,在TcomponentEditor右键,弹出一个元件编辑窗口,在这个元件编辑窗中动态生成一些控制,并放在TmyPanel上.TMYPanel如何知元件编辑窗口动态生成什么控件,并放在自己的Panel上.

解决方案 »

  1.   

    设计期,在TmyPanel组件上右键,弹出元件编辑窗口.元件编辑窗口有个Button一按就动态生成一个Tedit,它的parent是Tmypanel.如何实现这个过程.
      

  2.   

    代码如下:
    unit reg;interface
    uses DesignIntf,DesignEditors, StdCtrls,Uform,DsnDBCst, DesignWindows, TypInfo,
         Windows, SysUtils, Messages, Classes, Graphics, Controls, Forms,
       ExtCtrls, DB, DBCtrls;
    type
          TEditcomponentEditor=class(TComponentEditor)
       private   public    procedure Edit;override;
        procedure ExecuteVerb(Index: Integer); override;
        function GetVerb(Index: Integer): string; override;
        function GetVerbCount: Integer; override;   end;
    procedure Register;implementation
    uses testPanel,ADODB,dialogs;procedure Register;
    begin
      RegisterComponentEditor(TMYpanel,TEditcomponentEditor);
      RegisterComponents('AMy', [TMYpanel]);
    end;{ TEditcomponentEditor }procedure TEditcomponentEditor.Edit;
    var
       ed1:Tedit;begin
      //inherited;
      ed1:=Tedit.Create(designer.Root);
      ed1.Left:=100;
      ed1.Top:=100;
      ed1.Width:=100;
      ed1.Height:=20;
      //ed1.Parent:=Tpanel(component);
      ed1.Parent:=TWinControl(designer.Root);
      designer.Modified;
     
      except
         exit;
      end;}
    end;procedure TEditcomponentEditor.ExecuteVerb(Index: Integer);
    var
      i:integer;
      editform:Teditform;//元件编辑器窗体
    begin
      //inherited;
      case index of
      0:
      begin
         messagedlg('00',mtinformation,[mbOK],0);
      
          editform:= Teditform.Create(designer.Root);
          Try
            
            editform.ShowModal;
            
            if editform.ModalResult = mrOK then
            begin            //CopyProperty(editform, Component);          // 将修改过的属性赋值到控件中
                Designer.Modified;
              
            end;
          finally
            editform.Free;
          End;
      end;  end;
    end;function TEditcomponentEditor.GetVerb(Index: Integer): string;
    begin
       case index of
       0:result:='调用元件编辑器';
       end;
    end;function TEditcomponentEditor.GetVerbCount: Integer;
    begin
       result:=1;
    end;end.//元件编辑器代码
    unit Uform;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,designIntf,designEditors,DesignWindows,testPanel,ADODB;
    type  TEditForm = class(TDesignWindow)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        //mypanel:TmyPanel;
      end;//var
      //EditForm: TEditForm;implementation{$R *.dfm}procedure TEditForm.Button1Click(Sender: TObject);
    var
       ed:Tedit;
    begin
       ed:=Tedit.Create(designer.Root);
       ed.Left:=30;
       ed.Top:=50;
       ed.Width:=120;
       ed.Height:=20;
       ed.Parent:=TwinControl(designer.Root);   self.ModalResult:=mrOK;
    end;end.
      

  3.   

    运行结束出错,不能创建TEDIT
    各位大侠帮帮忙...
      

  4.   

    元件编辑器窗体里面,不要创建控件,只是提供一个让用户选择控件类型的radiobox之类的东西.
    function GetNewComponentName(AOwner: TComponent; const BaseName: string; TryNoIndex: Boolean = True): string;
    var
      I: Integer;
    begin
      Result := BaseName;
      if TryNoIndex then
      begin
        if AOwner.FindComponent(Result) = nil then
          Exit;
      end;  I := 0;
      repeat
        Inc(I);
        Result := BaseName + IntToStr(I);
      until AOwner.FindComponent(Result) = nil;
    end;procedure TEditcomponentEditor.ExecuteVerb(Index: Integer); 
    var 
      i:integer; 
      editform:Teditform;//元件编辑器窗体 
    begin 
      //inherited; 
      case index of 
      0: 
      begin 
        messagedlg('00',mtinformation,[mbOK],0); 
      
          editform:= Teditform.Create(Application); 
          Try 
            
            editform.ShowModal; 
            
            if editform.ModalResult = mrOK then 
            begin 
              
               if editForm.RadioBox1.Checked then  //如果选择的是创建一个Edit
               begin
                 with TEdit.Create(Component) do   //这里再创建
                 begin               
                   Parent := TWinControl(Component);
                   Top := 10;
                   //........赋值其他属性,属性值可以来源于你的editForm上用户的输入
                   Name := GetNewComponentName(Designer.GetRoot, 'Edit', False);
                   Text := 'Test';
                 end;
               end;
                Designer.Modified; 
              
            end; 
          finally 
            editform.Free; 
          End; 
      end;   end; 
    end; 
      

  5.   

    TO:suton 
    谢谢,收到你发给我的代码.
      

  6.   

    :),其实设计期和运行期差不了多少.不过编写设计期的代码时小心点,一不小心,就出乱子,我经常搞得delphi报N多错误,然后保存,重启delphi.
      

  7.   

    谢谢SUTON,
    就是说元件编辑器只是一个反回些信息值给TEditcomponentEditor.ExecuteVerb(Index: Integer); 的过程,而不是为了动态创建控件(如TEDIT).讨论:我曾在editform:Teditform;//元件编辑器窗体 动态创建过TEDIT.在Button的onclikc事件.代码如下.procedure TEditForm.Button1Click(Sender: TObject); 
    var 
      ed:Tedit; 
    begin 
      ed:=Tedit.Create(designer.Root); 
      ed.Left:=30; 
      ed.Top:=50; 
      ed.Width:=120; 
      ed.Height:=20; 
      ed.Parent:=TwinControl(designer.Root); 
    end;找不到哪天OK的代码,(生成的EDIT是放在FORM1上面(FORM1是主窗体),而不是TmyPanel上面。)
      

  8.   

    谢谢SUTON, 
    就是说元件编辑器只是一个反回些信息值给TEditcomponentEditor.ExecuteVerb(Index:   Integer);   的过程,而不是为了动态创建控件(如TEDIT). 讨论:我曾在editform:Teditform;//元件编辑器窗体   动态创建过TEDIT.在Button的onclikc事件.代码如下. procedure   TEditForm.Button1Click(Sender:   TObject);   
    var   
        ed:Tedit;   
    begin   
        ed:=Tedit.Create(designer.Root);   
        ed.Left:=30;   
        ed.Top:=50;   
        ed.Width:=120;   
        ed.Height:=20;   
        ed.Parent:=TwinControl(designer.Root);   
    end; 找不到哪天OK的代码,(生成的EDIT是放在FORM1上面(FORM1是主窗体),而不是TmyPanel上面。)
      

  9.   

    哪个代码我写出来了。如下:reg.pas注册单元
    procedure TEditcomponentEditor.ExecuteVerb(Index: Integer);
    var
      i:integer;
      editform:Teditform;
    begin
      //inherited;
      case index of
      0:
      begin
         messagedlg('00',mtinformation,[mbOK],0);
      
          editform:= Teditform.Create(Application);
          editform.Designer:=designer;
            editform.ShowModal;
      end;
      end;
    end;//元件编辑窗口单元。下面的代码基本没有变
    注意:TEditForm = class(TDesignWindow)是从TDesignWindow继承下来
    procedure TEditForm.Button1Click(Sender: TObject);
    var
       ed:Tedit;
    begin
       ed:=Tedit.Create(designer.Root);
       ed.Left:=30;
       ed.Top:=50;
       ed.Width:=120;
       ed.Height:=20;
       ed.Name:=designer.UniqueName('edit');
       ed.Parent:=TWinControl(designer.Root);   //self.ModalResult:=mrOK;
    end;
      

  10.   

    TO:suton 
    是不是和TDesignWindow继承有关系,因为给了个editform.Designer:=designer; 
      

  11.   

    找了半天,才看到TDesignWindow,原来在ToolsAPI目录下.
    这个类是从TForm继承的,实现了一些接口(这些接口干什么的?没仔细看).
    editform.Designer:=designer;  
    这个其实没什么.
    TDesignWindow里面,Designer的定义:
    property Designer: IDesigner read FDesigner write FDesigner;editform.Designer:=designer; 这个只是用TDesignWindow的FDesigner这个私有成员,将designer的指针值(我一直这么理解:接口就可以看成指针.当调用接口的函数时,就是通过这个指针值,找到函数的入口地址)保存起来. 
    那么,在TDesignWindow内部,通过私有成员FDesigner,或者通过他自己的属性Designer去调用某个函数,事实上,就跟直接用disigner去调用是一样的.
      

  12.   

    TO:SUTON谢谢你的解析.
    我在你的解析的基础上在editform上添加了一个Tcomponent类是来接受在Reg中Component的指针,,就可以达到在editform中动态创建军TEDIT并把其PARENT指给刚刚添加的Tcomponent类.代码如下:EDITFORM代码
    unit Uform;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,designIntf,designEditors,DesignWindows,testPanel,ADODB;
    type  TEditForm = class(TDesignWindow)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        mypanel:TComponent;
      end;//var
      //EditForm: TEditForm;implementation{$R *.dfm}uses reg;procedure TEditForm.Button1Click(Sender: TObject);
    var
       ed:Tedit;
    begin
       ed:=Tedit.Create(designer.Root);
       ed.Left:=30;
       ed.Top:=50;
       ed.Width:=120;
       ed.Height:=20;
       ed.Name:=designer.UniqueName('edit');
       ed.Parent:=TWincontrol(mypanel);   //self.ModalResult:=mrOK;
    end;end.reg代码;
    procedure TEditcomponentEditor.ExecuteVerb(Index: Integer);
    var
      editform:Teditform;
    begin
      //inherited;
      case index of
      0:
      begin
         messagedlg('00',mtinformation,[mbOK],0);
      
          editform:= Teditform.Create(Application);
          editform.Designer:=designer;
          editform.mypanel:=component;

            editform.ShowModal;            Designer.Modified;
      end;
     end;
    end;
    这样就可以真接在元件的编辑窗口中创建控件.这样可以方面好多,不用在REG哪里面判断.REG的代码变得简单明了.