Recent

Author Topic: [SOLVED] Component event handler assignments disappear from object inspector  (Read 5219 times)

russeld

  • New Member
  • *
  • Posts: 17
Hello,

With one of the components I have created, the event handler assignments in the object inspector disappear on closing and re-opening the project in which the component is used.
Normal properties are fine.

When I view the form source, the assignments are still present and look OK:
Code: [Select]

  object Bootloader: TPic33EpBootloader
    VendorID = '$04D8'
    ProductID = '$003C'
    ProgramOnConnect = False
    RunAfterProgram = False
    InhibitTimeout = False
    OnStateChange = BootloaderStateChange
    OnDisconnect = BootloaderDisconnect
    OnHexFileLoaded = BootloaderHexFileLoaded
    OnUpdateTimeout = BootloaderUpdateTimeout
    OnRecordProgrammed = BootloaderRecordProgrammed
    OnReadBootInfo = BootloaderReadBootInfo
    OnReadCRC = BootloaderReadCRC
    OnValidAppChecked = BootloaderValidAppChecked
    left = 112
    top = 112
  end
 

At design time, when the component is placed on the form, it's event handlers can be assigned without problem, and the application builds and runs fine.

VendorID and ProductID use overloaded setters, so that either hex (strings) or integers can be entered in the object inspector. This works, but could it be the causing problems?

Anyone have any ideas on possible causes? I'm using Lazarus 1.4.2 on windows 8.1

Thanks in advance

Russell
« Last Edit: September 19, 2015, 03:23:51 pm by russeld »

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Are your event properties all declared in a published section?
Any possibility of a property name clash?

russeld

  • New Member
  • *
  • Posts: 17
All of the properties are published versions of public properties in a base "custom" class.
Thanks for the suggestion, I'll dig through the class heirarchy and check for name clashes, but wouldn't that show up when I initialy assign the event handlers?

howardpc

  • Hero Member
  • *****
  • Posts: 4144
I'll dig through the class heirarchy and check for name clashes, but wouldn't that show up when I initialy assign the event handlers?

Such clashes are evident in {$mode objfpc} but I think {$mode delphi} allows them (though I'm not too sure, because I never use that mode if I can help it, partly for that reason).

russeld

  • New Member
  • *
  • Posts: 17
Quote
Such clashes are evident in {$mode objfpc}
Everything's in mode objfpc. I'm not at work at the moment, I'll check mode delphi tomorrow morning, thanks.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Well, there is no purpose in changing to a less strict mode if the strictest mode shows there is no name clash.

Clearly, the problem lies elsewhere. You'll have to share the problematic (compilable) code for others to delve deeper.

sky_khan

  • Guest
Most likely its related to loading of properties from resource/stream. How do your procedures check if value represents string or number ? Maybe its lost when one of your procedures is trying to convert string to integer.  I'm just guessing.

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
I always declared events like this:
Code: [Select]
property OnChange: TNotifyEvent read FOnChange write FOnChange; and I never had problems.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

russeld

  • New Member
  • *
  • Posts: 17
Most likely its related to loading of properties from resource/stream.
I suspect you are right, everything works until the form is reloaded. I'll try loading the form from a stream and see if I can catch the bug there.
Quote
How do your procedures check if value represents string or number ?
By overloading of the property setter. The string version used to handle hex values uses TryStringToInt() and raises an exception for invalid hex values. The getter always returns a hex string. The object inspector shows the correct values when the project reopens, so I'm guessing that that's not the issue, but I will try a version with plain integers.
Clearly, the problem lies elsewhere. You'll have to share the problematic (compilable) code for others to delve deeper.
I will have to strip down the code to something manageable - it requires several other packages. But first I want to check if I can find anything when the form is streamed.

russeld

  • New Member
  • *
  • Posts: 17
[SOLVED] Component event handler assignments disapear from object inspector
« Reply #9 on: September 19, 2015, 03:23:19 pm »
I finally got time to have a re-look at this problem and found the answer, it's a gotcha when using code completion on an event handler property:
For example using code completion on the the partial OnAnEvent property declaration in the following class:
Code: [Select]
type
  TTestComponent = class(TComponent)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
    property OnAnEvent : TNotifyEvent  //<--- Use code completion
  end; 
in the class declaration, lazarus produces:
Code: [Select]
  TTestComponent = class(TComponent)
  private
    FOnAnEvent : TNotifyEvent;
    procedure SetOnAnEvent(AValue : TNotifyEvent);
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
    property OnAnEvent : TNotifyEvent read FOnAnEvent write SetOnAnEvent;
  end;
and the setter method in the implementation section
Code: [Select]
procedure TTestComponent.SetOnAnEvent(AValue : TNotifyEvent);
begin
  if FOnAnEvent = AValue then Exit;
  FOnAnEvent := AValue;
end;
In mode objfpc the event handler can be assigned in the object inspector, the code compiles and runs without problems, but the object inspecter assignments disappear when the project is re-opened. When compiled in mode delphi, the compiler raises an error in the setter method, Error: Wrong number of parameters specified for call to "<Procedure Variable>" on the line if FOnAnEvent = AValue then Exit; and this points to the solution: Don't use code completion for event handlers, also there is no need for a setter, simply read and write the field:
Code: [Select]
    property OnAnEvent : TNotifyEvent read FOnAnEvent write FOnAnEvent;

n7800

  • Full Member
  • ***
  • Posts: 190
When compiled in mode delphi, the compiler raises an error in the setter method, Error: Wrong number of parameters specified for call to "<Procedure Variable>" on the line if FOnAnEvent = AValue then Exit; and this points to the solution: Don't use code completion for event handlers, also there is no need for a setter, simply read and write the field:
Code: [Select]
    property OnAnEvent : TNotifyEvent read FOnAnEvent write FOnAnEvent;

This has nothing to do with the problem. In Delphi mode, pointers to procedures must be passed without the "@" symbol.

See the answer in:
https://wiki.freepascal.org/IDE_tricks#Events_.28Method_properties.29_in_the_Object_Inspector

 

TinyPortal © 2005-2018