Jump to content
Mike Torrettinni

Why control methods (OnClick) can't be defined in Form Private section?

Recommended Posts

I searched but I can't seem to find any reference to this topic - or don't know what I need to look for:

 

I was just trying to move non-global methods into Private section. Why I can't move OnClick or other control used methods into Form Private section?

 

Instead of this:

 

TForm6 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private    
  public    
  end;

Into this:

TForm6 = class(TForm)
    Button1: TButton;    
  private    
    procedure Button1Click(Sender: TObject);
  public    
  end;

It compiles OK, but when running project I get error:  Error reading Button1.OnClick: Invalid property value

 

Why is that?

 

Also, why Button1 can't be defined in Private section, since it belongs to Form only? If I do, I get error: Class TButton not found.

 

 

Share this post


Link to post

All IDE managed components on a form and their event handlers must be published as this is the mechanism the IDE uses to load and save the form layout and event handler.

 

Share this post


Link to post
Posted (edited)
9 minutes ago, David Hoyle said:

All IDE managed components on a form and their event handlers must be published as this is the mechanism the IDE uses to load and save the form layout and event handler.

 

Hm... then why I get same message if I run Project1.exe, without IDE? I get same error message.

So, if I move button1 and Button1Click to Private, IDE doesn't complain. I can still modify control. Compiles OK also.

Edited by Mike Torrettinni
more info

Share this post


Link to post

I was trying to find an updated reference for this but it goes something like this...

 

TComponent and all its derivatives (components on forms) are designed to be loaded and save to the DFM files, in binary format or text. The IDE uses this when you visually design a form and places all event handlers and component references in the top of a class which is a published scope. These contain RTTI information for the loading and saving mechanisms. When you run your application the same streaming mechanisms are used to load your forms from the DFM which are resources within your EXE. If you've moved the declarations to another scope other than published then they cannot be loaded either by the IDE or by your application at run-time.

  • Thanks 1

Share this post


Link to post

Actually, the component will be created at runtime even if its associated field is private, or indeed not existent. What happens is that the streaming framework creates the component, assigns it properties, but is unable to field a field into which to store the reference to the component. 

  • Thanks 1

Share this post


Link to post

I tested this and it works OK when private method is assigned in runtime, not in design time:

 

I removed Button1Click from begin assgned to Button1 OnClick, and assign it in FormCreate:

 

type
  TForm6 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
  private
    procedure Button1Click(Sender: TObject);
  public
  end;

var
  Form6: TForm6;

implementation

{$R *.dfm}

procedure TForm6.FormCreate(Sender: TObject);
begin
  Button1.OnClick := Button1Click;
end;

procedure TForm6.Button1Click(Sender: TObject);
begin
  showmessage('click');
end;

 

This also makes sense why compiler doesn't complain in cases above. I assume this so called 'streaming framework' should be updated. If I can do it in FormCreate, why it can't do while 'creating form'.

Share this post


Link to post
13 minutes ago, Mike Torrettinni said:

I tested this and it works OK when private method is assigned in runtime, not in design time:

 

I removed Button1Click from begin assgned to Button1 OnClick, and assign it in FormCreate:

 


type
  TForm6 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
  private
    procedure Button1Click(Sender: TObject);
  public
  end;

var
  Form6: TForm6;

implementation

{$R *.dfm}

procedure TForm6.FormCreate(Sender: TObject);
begin
  Button1.OnClick := Button1Click;
end;

procedure TForm6.Button1Click(Sender: TObject);
begin
  showmessage('click');
end;

 

This also makes sense why compiler doesn't complain in cases above. I assume this so called 'streaming framework' should be updated. If I can do it in FormCreate, why it can't do while 'creating form'.

The form streaming process relies on run-time type information (the old styele), and that is only generated for published members of a class.

  • Like 1
  • Thanks 1

Share this post


Link to post

RTTI in recent Delphi version can find and update any fields including private ones. So in those versions it could work. But seems it's not implemented.

Share this post


Link to post
8 minutes ago, valex said:

RTTI in recent Delphi version can find and update any fields including private ones. So in those versions it could work. But seems it's not implemented.

The reason I tried to put those methods in Private section, was to limit the list of all 'visible' methods, variables, to put less code to process for error insight, code completion and remove circular references. So, I might be able to do this in one of next versions. Nice! 🙂 

Share this post


Link to post
3 hours ago, Mike Torrettinni said:

The reason I tried to put those methods in Private section, was to limit the list of all 'visible' methods, variables, to put less code to process for error insight, code completion and remove circular references. So, I might be able to do this in one of next versions. Nice! 🙂 

No. What was meant was that the IDE could in principle use new style RTTI to locate private declarations. But it doesn't. It still relies on old style RTTI. I see no reason to expect this to change. 

  • Like 1

Share this post


Link to post
3 hours ago, David Heffernan said:

No. What was meant was that the IDE could in principle use new style RTTI to locate private declarations. But it doesn't. It still relies on old style RTTI. I see no reason to expect this to change. 

Oh, OK. Good to know.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×