2008-11-14 9 views
9

El inspector de objetos Delphi no muestra las propiedades adicionales de los descendientes de TFrame por diseño. Las personas tienden a sugerir el uso de un truco conocido que se usa comúnmente para mostrar las propiedades del descendiente de TForm en el inspector de objetos. El truco es: Registrar módulo personalizado para los descendientes TForm a Delphi IDE a través de diseño de paquete momento como:Mostrando las propiedades adicionales del descendiente de TFrame en el inspector de objetos

RegisterCustomModule(TMyFrame, TCustomModule); 

El inspector de objetos puede mostrar propiedades adicionales de la instancia del TFrame Descendiente de esta manera, pero pierde sus comportamientos marco, si bien es incrustado en una forma. No se puede redistribuir, no es posible implementar eventos para sus subcomponentes y acepta controles secundarios (lo que no debería ser). Pero se comporta normalmente en su propia área de diseño.

Parece, esos comportamientos proporcionados por Delphi IDE especialmente solo para TFrame. Problaly no son tipo de instalaciones genéricas.

¿Hay alguna otra forma de lograr esto sin perder comportamientos de cuadros?

estoy usando Delphi 2007


@Tondrej,

Leer comentarios para el problema, gracias de antemano.

frameunit.dfm:

object MyFrame: TMyFrame 
    Left = 0 
    Top = 0 
    Width = 303 
    Height = 172 
    TabOrder = 0 
    object Edit1: TEdit 
    Left = 66 
    Top = 60 
    Width = 151 
    Height = 21 
    TabOrder = 0 
    Text = 'Edit1' 
    end 
end 

unit frameunit; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

type 
    TBaseFrame = Class(TFrame) 
    protected 
    Fstr: string; 
    procedure Setstr(const Value: string);virtual; 
    published 
    Property str:string read Fstr write Setstr; 
    End; 

    TMyFrame = class(TBaseFrame) 
    Edit1: TEdit; 
    private 
    // This won't be called in designtime. But i need this to be called in designtime 
    Procedure Setstr(const Value: string);override; 
    end; 

implementation 

{$R *.dfm} 

{ TBaseFrame } 

procedure TBaseFrame.Setstr(const Value: string); 
begin 
    Fstr := Value; 
end; 

{ TMyFrame } 

procedure TMyFrame.Setstr(const Value: string); 
begin 
    inherited; 
    Edit1.Text := Fstr; 
    // Sadly this code won't work and Edit1 won't be updated in designtime. 
end; 

end. 

unit RegisterUnit; 

interface 

procedure Register; 

implementation 

uses 
    Windows, DesignIntf, frameunit; 

procedure Register; 
var 
    delphivclide: THandle; 
    TFrameModule: TCustomModuleClass; 
begin 
    delphivclide := GetModuleHandle('delphivclide100.bpl'); 
    if delphivclide <> 0 then 
    begin 
    TFrameModule := GetProcAddress(delphivclide, '@[email protected]@'); 
    if Assigned(TFrameModule) then 
    begin 
     RegisterCustomModule(frameunit.TBaseFrame, TFrameModule); 
     // Just registering that won't cause Tmyframe to loose its frame behaviours 
     // but additional properties won't work well. 

     //RegisterCustomModule(frameunit.TMyFrame, TFrameModule); 
     // That would cause Tmyframe to lose its frame behaviours 
     // But additional properties would work well. 

    end; 
    end; 
end; 


end. 

Respuesta

0

No, yo no creo que esto es totalmente posible.

Lo que suelo hacer cuando tengo necesidades similares es simplemente instalar el descendiente de cuadros como un componente por derecho propio. Pero sí, de esa manera pierde mucho del comportamiento de fotograma típico (especialmente en designtime), p. ya no puede manipular los subcomponentes directamente y los cambios en el marco ya no se propagan automáticamente a los formularios que lo utilizan en designtime; primero tiene que volver a compilar el paquete de tiempo de ejecución que contiene el marco.

Por otra parte, desde una perspectiva de OOP esto no es tan malo. De hecho, impone el concepto de ocultación de la implementación. Aún puede exponer las propiedades individuales y la funcionalidad de los subcomponentes mediante nuevas propiedades y métodos en el propio marco.

4

¿Qué clase de módulo personalizado está registrando para su marco? ¿Qué versión de Delphi estás usando?

De mis experimentos con Delphi 2007, la clase de módulo personalizado que parece funcionar es TFrameModule. Esta clase está contenida en delphivclide100.bpl. Puesto que no hay delphivclide.dcp correspondiente tiene que cargar manualmente:

unit FrameTestReg; 

interface 

procedure Register; 

implementation 

uses 
    Windows, DesignIntf, 
    FrameTest; 

procedure Register; 
var 
    delphivclide: THandle; 
    TFrameModule: TCustomModuleClass; 
begin 
    delphivclide := GetModuleHandle('delphivclide100.bpl'); 
    if delphivclide <> 0 then 
    begin 
    TFrameModule := GetProcAddress(delphivclide, '@[email protected]@'); 
    if Assigned(TFrameModule) then 
     RegisterCustomModule(TTestFrame, TFrameModule); 
    end; 
end; 

end. 

Mi unidad FrameTest es muy simple, no tiene FrameTest.dfm, sólo la declaración de la nueva descendiente TFrame:

unit FrameTest; 

interface 

uses 
    Forms; 

type 
    TTestFrame = class(TFrame) 
    private 
    FHello: string; 
    published 
    property Hello: string read FHello write FHello; 
    end; 

implementation 

end. 

Usando la clase TFrameModule, todo parece funcionar bien hasta el momento.Puedo crear un nuevo descendiente de TTestFrame para incluirlo en el proyecto y editar sus propiedades publicadas en el Inspector de Objetos, poner instancias de este nuevo descendiente en un formulario en el IDE, editar sus nuevas propiedades publicadas en el Inspector de Objetos, escribir controladores de eventos para sus componentes secundarios, etc. En el recurso .dfm, puedo ver la directiva esperada "en línea" para las instancias. No he encontrado ningún problema hasta ahora, así que tal vez esta es la solución.

+0

Niza, que havn't marcos utilizado durante algún tiempo, porque creo que no vale la pena la molestia. Pero voy a probar este. –

0
procedure TMyFrame.Setstr(const Value: string); 
begin 
    inherited; 
    Edit1.Text := Fstr; 
    // Sadly this code won't work and Edit1 won't be updated in designtime. 
end; 

creo que es porque no debería trabajar en tiempo de diseño. Usted ha registrado TBaseFrame como un módulo personalizado, por lo que las propiedades de TBaseFrame (¡no los descendientes!) Deberían ser editables en el momento del diseño. Delphi IDE solo conoce las propiedades publicadas de la clase que ha registrado; no sabe nada sobre los descendientes y anulaciones que haya realizado en su proyecto. Para que el código en tiempo de diseño, usted debe o incluirlo en la definición TBaseFrame:

procedure TBASEFrame.Setstr(const Value: string); 
begin 
    inherited; 
    Edit1.Text := Fstr; 
end; 

o (además de TBaseFrame) registrar la definición TMyFrame como un módulo personalizado.

Trate de entender: Delphi IDE en el momento del diseño solo conoce las cosas que se han registrado en él. No es una desventaja; es un comportamiento lógico.

+1

Ha pasado mucho tiempo ... Por lo que recuerdo, si registro TMyFrame, sus instancias ya no tienen la capacidad de redisegnablity y muestra solo las propiedades de su descendiente. – Serguzest

0

No hay necesidad de hacer en "forma truco"

uses 
... 
    DMForm, 
    VCLFormContainer, 
... 

procedure Register; 
begin 
... 
    RegisterCustomModule(TYourFrameClass, TFrameModule); // for frames 
    RegisterCustomModule(TYourModuleClass, TDataModuleCustomModule); // for data modules 
... 
end; 

Hay otra manera alrededor de añadir marcos también

type 
    TNestableWinControlCustomModule = class (TWinControlCustomModule) 
    public 
    function Nestable: Boolean; override; 
    end; 

function TNestableWinControlCustomModule.Nestable: Boolean; 
begin 
    Result := True; 
end; 

+

RegisterCustomModule(TYourFrameClass, TNestableWinControlCustomModule); 

Nombres de unidades (probado en XE7):

TCustomModule =>DesignEditors

TDataModuleCustomModule =>DMForm (designide.dcp)

TWinControlCustomModule =>WCtlForm (designide.dcp)

TFrameModule =>VCLFormContainer (vcldesigner.dcp)

supongo que para FireMonkey debería ser posible en forma similar (Encontrar fmxdesigner.dcp & ver que hay dentro de Notepad ++)

PS. En las versiones anteriores de Delphi no era TDataModuleDesignerCustomModule metaclase en lugar de en la unidad TDataModuleCustomModule DMDesigner

PPS. Otros nombres MetaClass existentes:

TCustomFormCustomModule

TIDESourceModuleCustomModule

Cuestiones relacionadas