Cómo acceder a la variable privada de una clase

5002 vistas

Ejemplo concreto:
Queremos, por ejemplo, acceder desde código a la variable privada FImageIndex de un TMenuItem (aunque no importarÃa ni la variable, ni el objeto ni la unidad).

Solución:
Todo está en las posibilidades del casteo, y de hacer que los tipos clase no son otra cosa que tipos de punteros particulares.

Lo primero que necesitamos es declarar una clase TMenuItemPublic de tal manera que derive de la misma clase que TMenuItem, es decir, de TComponent.

Observar que hay las mismas variables y exactamente en el mismo orden que en la clase TMenuItem, a diferencia que estas variables estarán declaradas como públicas.

De esta manera obtenemos una clase que tendrá la misma estructura en memoria que la clase TMenuItem, ¡¡lo que nos permite hacer un casteo de TMenuItem a TMenuItemPublic permitiéndonos acceder a todas las variables privadas de la primera como si fueran públicas!!



delphi
  1. type
  2. TMenuItemPublic=class(TComponent)
  3.   public
  4.     FCaption: string;
  5.     FHandle: HMENU;
  6.     FChecked: Boolean;
  7.     FEnabled: Boolean;
  8.     FDefault: Boolean;
  9.     FAutoHotkeys: TMenuItemAutoFlag;
  10.     FAutoLineReduction: TMenuItemAutoFlag;
  11.     FRadioItem: Boolean;
  12.     FVisible: Boolean;
  13.     FGroupIndex: Byte;
  14.     FImageIndex: TImageIndex;
  15.     FActionLink: TMenuActionLink;
  16.     FBreak: TMenuBreak;
  17.     FBitmap: TBitmap;
  18.     FCommand: Word;
  19.     FHelpContext: THelpContext;
  20.     FHint: string;
  21.     FItems: TList;
  22.     FShortCut: TShortCut;
  23.     FParent: TMenuItem;
  24.     FMerged: TMenuItem;
  25.     FMergedWith: TMenuItem;
  26.     FMenu: TMenu;
  27.     FStreamedRebuild: Boolean;
  28.     FImageChangeLink: TChangeLink;
  29.     FSubMenuImages: TCustomImageList;
  30.     FOnChange: TMenuChangeEvent;
  31.     FOnClick: TNotifyEvent;
  32.     FOnDrawItem: TMenuDrawItemEvent;
  33.     FOnAdvancedDrawItem: TAdvancedMenuDrawItemEvent;
  34.     FOnMeasureItem: TMenuMeasureItemEvent;
  35.     FAutoCheck: Boolean;
  36.   end;



La variable que nos interesa es FImageIndex, el problema queda resuelto asÃ:



delphi
  1. var
  2.   UnMenuItem: TMenuItem;
  3. begin
  4. ....
  5.   TMenuItemPublic(UnMenuItem).FImageIndex := NewIndex;
  6. ....
  7. end;