Recent

Author Topic: Can't cast Tpanel to TwinControl  (Read 1485 times)

lazer

  • Sr. Member
  • ****
  • Posts: 269
Can't cast Tpanel to TwinControl
« on: September 04, 2025, 08:50:37 pm »
Hi,

I have a new class derived from TPanel, which itself comes from   TWinControl  : https://wiki.lazarus.freepascal.org/TPanel

Code: Pascal  [Select][+][-]
  1. type
  2.   TtextPanel = class(TPanel)
  3.   private
  4.     FbtnMargin:integer;
  5.     FpanelLabel:Tlabel;
  6.     FpanelButton:Tspeedbutton;
  7.     FpanelBtn:Tbutton;
  8.   protected  
  9.  

However, when I attempt to cast it as TwinControl, I get told it's and invalid cast:

Code: Pascal  [Select][+][-]
  1. procedure TSpellwin.textPanelAllClick(Sender: TObject);
  2. var i:integer;
  3. begin
  4.   if (pack<>nil) then with pack do
  5.   begin
  6.     if cardstate=cd_test then
  7.     begin
  8.         i:=TwinControl(sender).tag;                     // centre_panel tag=0
  9.  

This code was originally written under Delphi2 and ported to Lazarus a couple of years ago. ( Not sure what version that would have been.)

Lazarus 4.2 (rev Unknown) FPC 3.2.2 x86_64-linux-gtk2

Why does it now object to this typecast ?

TIA.

jamie

  • Hero Member
  • *****
  • Posts: 7300
Re: Can't cast Tpanel to TwinControl
« Reply #1 on: September 04, 2025, 09:03:08 pm »
What is "PACK" ? is there something in there named SENDER?

Jamie
The only true wisdom is knowing you know nothing

BrunoK

  • Hero Member
  • *****
  • Posts: 716
  • Retired programmer
Re: Can't cast Tpanel to TwinControl
« Reply #2 on: September 04, 2025, 09:13:11 pm »
64 bit compiler.

tag is a nativeint, 64bits. i is an Integer thus 32 bit.

You cannot store a 64 bit pointer in 32 bit Value.

Correcteur orthographique de merde sur ma tablette.

jamie

  • Hero Member
  • *****
  • Posts: 7300
Re: Can't cast Tpanel to TwinControl
« Reply #3 on: September 04, 2025, 09:17:54 pm »
I don't think it's the tag. It's the actual SENDER I believe he has logged in the PACK object and it most likely 32 bit type, like a cardinal and he is using a 64 bit compiler, which the CAST will not work, not the assignment of tag.

Jamie
The only true wisdom is knowing you know nothing

lazer

  • Sr. Member
  • ****
  • Posts: 269
Re: Can't cast Tpanel to TwinControl
« Reply #4 on: September 04, 2025, 10:05:04 pm »
64 bit compiler.

tag is a nativeint, 64bits. i is an Integer thus 32 bit.

You cannot store a 64 bit pointer in 32 bit Value.

Correcteur orthographique de merde sur ma tablette.

Yes, I think you're onto the basic problem. I think I was compiling for a 32 bit target last time. That's what has changed.
I was trying to work out why this worked sometimes and it looked like it was when tag=0 .

Previously I compiled for an old laptop which had 32 Windows and x686 linux on it.

If I step through in the assembler window it's the fpc_do_as line which throws and error.
Code: Pascal  [Select][+][-]
  1. It's the actual SENDER I believe he has logged in the PACK object and it most likely 32 bit type,

I'm not sure what you think I have "logged".

sender is a generic argument of type TObject which points to the UI object whose event has been triggered.

In this case it's inheritted from Tpanel , a TwinControl itself a Tobject.

Whether it's a 32b or a 64b compiler I don't see why I can't cast a TObject sender to TwinControl or Tpanel, they all are inherited from the same souce, be it 32 or 64 bit.

I'm obviously missing something but I'm not sure what.
« Last Edit: September 04, 2025, 10:14:24 pm by lazer »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11792
  • Debugger - SynEdit - and more
    • wiki
Re: Can't cast Tpanel to TwinControl
« Reply #5 on: September 04, 2025, 10:15:31 pm »
Just add "Sender" to the debugger watches window, and in the watch property enable "Use instance class". => then the debugger will tell you what class Sender actually has. Maybe its not the object that you expect.

lazer

  • Sr. Member
  • ****
  • Posts: 269
Re: Can't cast Tpanel to TwinControl
« Reply #6 on: September 04, 2025, 10:36:32 pm »
Just add "Sender" to the debugger watches window, and in the watch property enable "Use instance class". => then the debugger will tell you what class Sender actually has. Maybe its not the object that you expect.

wow, pro tip. Thanks.  Lazarus is much more powerful than I recall it being.


Sender @$00007F97ED561210 = TLabel( FALIGNMENT: TALEFTJUSTIFY;  FFOCUSCONTROL: nil;  FOPTIMALFILL: False;
......


type
  TtextPanel = class(TPanel)
  private
    FbtnMargin:integer;
    FpanelLabel:Tlabel;
    FpanelButton:Tspeedbutton;
    FpanelBtn:Tbutton;
  protected

My custom Tpanel does indeed include a Tlabel.
Code: Pascal  [Select][+][-]
  1.   public
  2.     constructor Create(AOwner: TComponent); override;
  3.   published
  4.     procedure textChanged(sender:tobject);
  5.     property panelLabel :TLabel read FpanelLabel;
  6.     property panelButton:Tspeedbutton read FpanelButton;
  7.     property panelBtn   :Tbutton read FpanelBtn;
  8.     property btnMargin:integer read FbtnMargin;
  9. //     property OnResize : TNotifyEvent;  override;
  10.   end;
  11.  

It seems that sometimes I click on the label which does not inherit from TwinConfrol.

I'm confused why I've never seen this producing problems before.

jamie

  • Hero Member
  • *****
  • Posts: 7300
Re: Can't cast Tpanel to TwinControl
« Reply #7 on: September 04, 2025, 11:09:57 pm »
Please tell me if you have an identifier of "Sender" inside of the PACK object which you have the current name space focused to?

P.S.
  I can type cast a TWinControl over a TLAbel object and I don't get that at run-time. It works fine when I set the TAG that way or even read the tag.
Jamie
« Last Edit: September 04, 2025, 11:12:55 pm by jamie »
The only true wisdom is knowing you know nothing

lazer

  • Sr. Member
  • ****
  • Posts: 269
Re: Can't cast Tpanel to TwinControl
« Reply #8 on: September 05, 2025, 12:08:36 am »
Setting cntl-f  to  'sender' in pack.pas:

Code: Pascal  [Select][+][-]
  1. Search string 'sender' not found!

jamie

  • Hero Member
  • *****
  • Posts: 7300
Re: Can't cast Tpanel to TwinControl
« Reply #9 on: September 05, 2025, 12:23:20 am »
Does this run without debugging?

Jamie
The only true wisdom is knowing you know nothing

Zvoni

  • Hero Member
  • *****
  • Posts: 3135
Re: Can't cast Tpanel to TwinControl
« Reply #10 on: September 05, 2025, 08:26:03 am »
Please tell me if you have an identifier of "Sender" inside of the PACK object which you have the current name space focused to?

P.S.
  I can type cast a TWinControl over a TLAbel object and I don't get that at run-time. It works fine when I set the TAG that way or even read the tag.
Jamie
The Pack-Object has nothing to do with his problem despite sitting inside the With Do.
It's the wrong control being "sent"

Aircode
Code: Pascal  [Select][+][-]
  1. If Sender is TWinControl Then i:=TWinControl(Sender).Tag;
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

jamie

  • Hero Member
  • *****
  • Posts: 7300
Re: Can't cast Tpanel to TwinControl
« Reply #11 on: September 05, 2025, 01:26:50 pm »
Please tell me if you have an identifier of "Sender" inside of the PACK object which you have the current name space focused to?

P.S.
  I can type cast a TWinControl over a TLAbel object and I don't get that at run-time. It works fine when I set the TAG that way or even read the tag.
Jamie
The Pack-Object has nothing to do with his problem despite sitting inside the With Do.
It's the wrong control being "sent"

Aircode
Code: Pascal  [Select][+][-]
  1. If Sender is TWinControl Then i:=TWinControl(Sender).Tag;
In trying to debug what code is presented here leads me to several questions and yes, my question was answered so that case could be eliminated.

The point here is the code did not use an "IS" operator to perform that check which leads me to believe additional code is being inserted that was not intended by the originator!

 Which is the case being why I asked if that code executes without Debug info!

 I can perform any type of cast (Not type check) with or without debug info with the Windows target and as for the TAG property it works fine, because it is part of a lower ladder of the cast inheritance.

 So, this leads me to believe the debugger on the Linux system being used for this is intentionally inserting the "IS" check when the coder did not instruct it to do so, because here, that is valid code since the TAG property is way below that level.

 Jamie


The only true wisdom is knowing you know nothing

Zvoni

  • Hero Member
  • *****
  • Posts: 3135
Re: Can't cast Tpanel to TwinControl
« Reply #12 on: September 05, 2025, 01:38:44 pm »
An alternative to Typecasting it to TWinControl might be to TypeCast it to TComponent, since the Tag-Property stems from there, and TComponent is the common Ancestor for TLabel and whatever else he has in that Panel.

In that sense:
Code: Pascal  [Select][+][-]
  1. procedure TSpellwin.textPanelAllClick(Sender: TObject);
  2. var i:integer;
  3. begin
  4.   if (pack<>nil) then with pack do
  5.   begin
  6.     if cardstate=cd_test then
  7.     begin
  8.         i:=TComponent(sender).tag;  //<-- HERE
  9.  

In case he clicks the Label, he wouldn't get an invalid TypeCast, but in that case he would receive the "Tag" of the Label
No idea if that is intended behavior
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

jamie

  • Hero Member
  • *****
  • Posts: 7300
Re: Can't cast Tpanel to TwinControl
« Reply #13 on: September 05, 2025, 01:43:06 pm »
casting with a TControl is also enough but it does not change the facts that the compiler in their case must be inserting a Type check when clearly the coder didn't specify that, this only slows the code down.

Jamie
The only true wisdom is knowing you know nothing

lazer

  • Sr. Member
  • ****
  • Posts: 269
Re: Can't cast Tpanel to TwinControl
« Reply #14 on: September 05, 2025, 05:53:23 pm »
Yes , I should be using "is" test.

The following is what I should have been doing that this seems to work fine.

Code: Pascal  [Select][+][-]
  1.    begin
  2.       if sender is Tlabel then
  3.         i:= Tlabel(sender).parent.tag
  4.       else
  5.         i:=TComponent(sender).tag;                     // centre_panel tag=0
  6.      

It's certainly interesting what this invalid typecast error implies. Maybe someone should look into that.

 

TinyPortal © 2005-2018