tecnica taller ppt pmbok origen metodo introduccion estimacion ensayo administracion delphi components tframe

taller - Cómo mejorar el uso de Marcos Delphi



tecnica delphi en administracion (6)

Casi siempre estoy creando instancias de marcos en el código. Esto es fácil y funcionó bien para mí hasta ahora.

He usado marcos en Delphi durante años, y son una de las características más poderosas de la VCL, pero el uso estándar de ellos parece tener algún riesgo, como:

  1. Es fácil mover o editar accidentalmente los subcomponentes de cuadros en el formulario de host de un marco sin darse cuenta de que está ''retocando'' el marco; sé que esto no afecta el código de marco original, pero generalmente no es lo que usted querría.

  2. Al trabajar con el marco, aún está expuesto a sus subcomponentes para la edición visual, incluso cuando el marco tiene años y no debe tocarse.

Entonces llegué a pensar ...

  1. ¿Hay alguna manera de "agrupar" componentes de modo que sus posiciones estén "bloqueadas"? Esto sería útil para formularios terminados y marcos. A menudo, otros desarrolladores me devuelven el código donde solo han cambiado los límites del formulario e incluso ellos no intentaron ningún cambio.

  2. ¿Hay alguna manera de convertir un marco y sus componentes en un solo componente Delphi? Si es así, las partes internas del marco estarían completamente ocultas y su utilidad aumentaría aún más.

Estoy interesado en cualquier pensamiento ...

Brian.


El registro de sus marcos como componente resuelve tanto el 1.o como el 2.

  1. los componentes en el marco están bloqueados cuando pones ese control de marco en un formulario u otro marco
  2. obtendrá un componente (en realidad: control) que puede diseñar visualmente

Pero: hay algunas capturas (que se pueden resolver, ver el enlace del artículo), de las cuales la más importante es esta:

Cuando coloca componentes en su marco y luego los suelta como un componente en un formulario o marco Delphi, los componentes son visibles en el Panel de Estructura.

El problema es que, debido a que son visibles en el panel de estructura, puede eliminarlos y causar violaciones de acceso.

El truco para resolver esto es no olvidar la ''ramita'' .
Aprendí esa valiosa lección de Ray Konopka durante DelphiLive 2009.

Como la lección es tan valiosa, escribí una publicación en el blog que la describe en detalle.

La parte esencial es esta pequeña porción de código (más detalles en la publicación del blog):

procedure RegisterFramesAsComponents(const Page: string; const FrameClasses: array of TFrameClass); var FrameClass: TFrameClass; begin for FrameClass in FrameClasses do begin RegisterComponents(Page, [FrameClass]); RegisterSprigType(FrameClass, TComponentSprig); end; end;

Espero que esto ayude.

--jeroen


Para una solución alternativa, ¿puede hacer que los archivos .dfm solo se lean en su control de origen?


Sí, solo regístrelos como componentes. :-)

Diseña tu marco normalmente y luego de registrarlo. También asegúrese de no tener dependencias no deseadas en diferentes unidades ya que están vinculadas cuando se usa su ''componente''. También puede agregar propiedades published para usarlas en el Inspector de objetos más adelante. Ver por ejemplo el siguiente código generado por el IDE (ver también mis comentarios):

unit myUnit; uses ... type TmyComp = class(TFrame) //set your frame name to be the name your component ToolBar1: TToolBar; //different components added in the form designer aliMain: TActionList; ... published //this section is added by hand property DataSource: TDataSource read FDataSource write SetDataSource; //some published properties added just for exemplification property DefFields: string read FDefFields write SetDefFields; ... end; procedure Register; //added by hand implementation {$R *.DFM} procedure Register; begin RegisterComponents(''MyFrames'', [TmyComp]); //register the frame in the desired component category end;

Compila lo anterior en un paquete de tu elección, instálalo y comprueba tu paleta de componentes. :-)

HTH


Solo para aumentar la contribución, tenga en cuenta que si va a la ventana de Structure y hace clic derecho en el nombre de TFrame que eligió, y hace clic en la opción de menú Add to Palete . Esto hará que un componente salga de tu Marco y no necesitas crear ningún procedimiento de Register . ;-)


También encontré ese problema cuando trato de usar marcos como componentes. Hay varias posibilidades para solucionar los problemas obvios, pero todos socavan el principio de ocultamiento de la información (todos los subcomponentes del marco se exponen como propiedades publicadas, lo que significa que todos pueden acceder a ellos).

Lo resolví implementando un componente genérico de "control de marco":

unit RttiBrow.Cbde.FrameControl; interface uses Classes, Controls, Forms, Messages, ExtCtrls; type TFrameClass = class of TFrame; TComponentFrame = class (TFrame) private function GetClientHeight: Integer; function GetClientWidth: Integer; procedure SetClientHeight(const Value: Integer); procedure SetClientWidth(const Value: Integer); function GetOldCreateOrder: Boolean; procedure SetOldCreateOrder(const Value: Boolean); function GetPixelsPerInch: Integer; procedure SetPixelsPerInch(const Value: Integer); function GetTextHeight: Integer; procedure SetTextHeight(const Value: Integer); published { workarounds for IDE bug } property ClientWidth: Integer read GetClientWidth write SetClientWidth stored False; property ClientHeight: Integer read GetClientHeight write SetClientHeight stored False; property OldCreateOrder: Boolean read GetOldCreateOrder write SetOldCreateOrder stored False; property PixelsPerInch: Integer read GetPixelsPerInch write SetPixelsPerInch stored False; property TextHeight: Integer read GetTextHeight write SetTextHeight stored False; end; TComponentFrame<TFrameControl: class { TControl }> = class (TComponentFrame) private function GetController: TFrameControl; inline; protected property Controller: TFrameControl read GetController; public constructor Create (AOwner: TComponent); override; end; TFrameControl<T: TFrame> = class (TWinControl) private FFrame: T; function PlainFrame: TFrame; protected procedure CreateParams (var Params: TCreateParams); override; property Frame: T read FFrame; public constructor Create (AOwner: TComponent); override; property DockManager; published property Align; property Anchors; property BiDiMode; property Color; property Constraints; property Ctl3D; property UseDockManager default True; property DockSite; property DoubleBuffered; property DragCursor; property DragKind; property DragMode; property Enabled; property Font; property ParentBiDiMode; property ParentBackground; property ParentColor; property ParentCtl3D; property ParentDoubleBuffered; property ParentFont; property ParentShowHint; property ShowHint; property TabOrder; property TabStop; property Touch; property Visible; property OnAlignInsertBefore; property OnAlignPosition; property OnCanResize; property OnConstrainedResize; property OnDockDrop; property OnDockOver; property OnDragDrop; property OnDragOver; property OnEndDock; property OnEndDrag; property OnEnter; property OnExit; property OnGesture; property OnGetSiteInfo; property OnMouseActivate; property OnMouseDown; property OnMouseEnter; property OnMouseLeave; property OnMouseMove; property OnMouseUp; property OnResize; property OnStartDock; property OnStartDrag; property OnUnDock; end; implementation uses Windows; { TFrameControl<T> } constructor TFrameControl<T>.Create(AOwner: TComponent); begin inherited; FFrame := T (TFrameClass (T).Create (Self)); PlainFrame.Parent := Self; PlainFrame.Align := alClient; end; procedure TFrameControl<T>.CreateParams(var Params: TCreateParams); begin inherited; Params.Style := Params.Style or WS_CLIPCHILDREN; Params.ExStyle := Params.ExStyle or WS_EX_CONTROLPARENT; end; function TFrameControl<T>.PlainFrame: TFrame; begin Result := FFrame; // buggy compiler workaround end; { TComponentFrame } function TComponentFrame.GetOldCreateOrder: Boolean; begin Result := False; end; function TComponentFrame.GetPixelsPerInch: Integer; begin Result := 0; end; function TComponentFrame.GetTextHeight: Integer; begin Result := 0; end; procedure TComponentFrame.SetClientHeight(const Value: Integer); begin Height := Value; end; procedure TComponentFrame.SetClientWidth(const Value: Integer); begin Width := Value; end; procedure TComponentFrame.SetOldCreateOrder(const Value: Boolean); begin end; procedure TComponentFrame.SetPixelsPerInch(const Value: Integer); begin end; procedure TComponentFrame.SetTextHeight(const Value: Integer); begin end; function TComponentFrame.GetClientHeight: Integer; begin Result := Height; end; function TComponentFrame.GetClientWidth: Integer; begin Result := Width; end; { TComponentFrame<TFrameControl> } constructor TComponentFrame<TFrameControl>.Create(AOwner: TComponent); begin inherited; Assert (AOwner <> nil); Assert (AOwner.InheritsFrom (TFrameControl)); end; function TComponentFrame<TFrameControl>.GetController: TFrameControl; begin Result := TFrameControl (Owner); end; end.

Con esta clase, agregar un marco como componente se convierte en un proceso de dos etapas:

// frame unit type TFilteredList = class; TFrmFilteredList = class (TComponentFrame<TFilteredList>) // lots of published sub-components and event methods like this one: procedure BtnFooClick(Sender: TObject); end; TFilteredList = class (TFrameControl<TFrmFilteredList>) private procedure Foo; public // the component''s public interface published // the component''s published properties end; procedure Register; ... procedure Register; begin RegisterComponents (''CBDE Components'', [TFilteredList]); end; procedure TFrmFilteredList.BtnFooClick(Sender: TObject); begin Controller.Foo; end; procedure TFilteredList.Foo; begin end; ...

Al usar este enfoque, el usuario de su componente no verá sus subcomponentes.