Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Class pointer property



Permlink Replies: 5 - Last Post: Jul 6, 2017 11:42 AM Last Post By: Bob Gambler
Bob Gambler

Posts: 61
Registered: 8/23/10
Class pointer property
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 5, 2017 2:59 PM
I want to create my own MenuItem component in order to assign a record pointer to the MenuItem. How can i do that?

Delphi 10.2 Starter

My component:

unit uSmMenuItem;
 
interface
 
uses Classes, Menus;
 
type
  TSmMenuItem = class(TMenuItem)
  private
    { Private declarations }
    fItemMenu : String; // <=== Type pointer
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    property ItemMenu : String read fItemMenu write fItemMenu;  // <=== Type pointer
  end;
 
procedure Register;
 
implementation
 
constructor TSmMenuItem.Create(AOwner : TComponent);
begin
   inherited Create(AOwner);
end;
 
destructor TSmMenuItem.Destroy;
begin
   inherited destroy;
end;
 
procedure Register;
begin
  RegisterComponents('MyComponents', [TSmMenuItem]);
end;
 
end.
Francesco Marano

Posts: 59
Registered: 11/18/02
Re: Class pointer property
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 5, 2017 3:21 PM   in response to: Bob Gambler in response to: Bob Gambler
Hello,

If you need to store a reference to a class instance, you may want to evaluate a weak pointer:
[WEAK]fItemMenu : TMyClass;


or, if you need to store a real record pointer, see the section "Record pointers"
at this link:
http://www.delphibasics.co.uk/Article.asp?Name=Pointers

Regards,
Francesco

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Class pointer property
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 5, 2017 3:37 PM   in response to: Bob Gambler in response to: Bob Gambler
Bob Gambler wrote:

I want to create my own MenuItem component in order to assign a
record pointer to the MenuItem. How can i do that?

The VCL's menu system is not extendable in that way. You can't define
new menu item classes for menus created at design-time.

You can create TMenuItem-derived objects at runtime in code (no
registration needed), and then add them to existing menus using the
TMenuItem.Add() method. This is the approach you will have to take if
you want to add custom properties to menu items.

However, TMenuItem is a TComponent descendant, so it has a public Tag
property, which you can use to hold user-defined values including
pointers.

--
Remy Lebeau (TeamB)
Yannick LANCHEC

Posts: 43
Registered: 1/21/01
Re: Class pointer property
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 6, 2017 3:13 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi,

Yes the best way is to use the Tag, it's a "NativeInt", the size is 4 bytes on x86 or 8 bytes on X64, good for a pointer.

Yannick

Remy Lebeau (TeamB) wrote:
Bob Gambler wrote:

I want to create my own MenuItem component in order to assign a
record pointer to the MenuItem. How can i do that?

The VCL's menu system is not extendable in that way. You can't define
new menu item classes for menus created at design-time.

You can create TMenuItem-derived objects at runtime in code (no
registration needed), and then add them to existing menus using the
TMenuItem.Add() method. This is the approach you will have to take if
you want to add custom properties to menu items.

However, TMenuItem is a TComponent descendant, so it has a public Tag
property, which you can use to hold user-defined values including
pointers.

--
Remy Lebeau (TeamB)
Alex Belo

Posts: 626
Registered: 10/8/06
Re: Class pointer property [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 6, 2017 9:57 AM   in response to: Yannick LANCHEC in response to: Yannick LANCHEC
Yannick LANCHEC wrote:

Tag, it's a "NativeInt", the size is 4
bytes on x86 or 8 bytes on X64, good for a pointer.

This is intentionally.

AFAIR, in the days of old (first 64 bit release) there was big
discussion on size of Tag. It seems that proper size of Tag is merit of
community.

:-)

--
Alex
Bob Gambler

Posts: 61
Registered: 8/23/10
Re: Class pointer property [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 6, 2017 11:42 AM   in response to: Alex Belo in response to: Alex Belo
Thank you all..

I created a small test code, it works as desired.

unit Unit1;
 
interface
 
uses System.SysUtils, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, System.Classes;
 
Type TTest = Record
   FieldA : String;
   FieldB : Integer;
End;
 
type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    procedure FormCreate(Sender: TObject);
    procedure ClickMenu(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var Form1: TForm1;
    Test : Array of ^TTest;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
Var vMenuItem : TMenuItem;
    I : Integer;
begin
   SetLength(Test, 5);
 
   For I := 0 to 4 do
   Begin
      New(Test[I]); Test[I].FieldA := 'Field A'; Test[I].FieldB := I;
 
      vMenuItem         := TMenuItem.Create(MainMenu1);
      vMenuItem.Caption := 'Item ' + I.ToString;
      vMenuItem.OnClick := ClickMenu;
      vMenuItem.Tag     := Integer(Pointer(Test[I])); // Casting
 
      MainMenu1.Items.Add(vMenuItem);
   End;
end;
 
procedure TForm1.ClickMenu(Sender: TObject);
Var vTest : ^TTest;
begin
   vTest := Pointer((Sender as TMenuItem).Tag); // Casting
   ShowMessage('Field A: ' + vTest.FieldA + ', Field B: ' + vTest.FieldB.ToString);
End;
 
end.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02