Recent

Author Topic: Issues with subclass creation  (Read 37590 times)

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Issues with subclass creation
« Reply #15 on: January 16, 2014, 04:27:06 pm »
The source for TLabeledEdit will show you how to proceed if you're not clear.

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Issues with subclass creation
« Reply #16 on: January 19, 2014, 04:10:11 pm »
Thanks very much for the info

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Issues with subclass creation
« Reply #17 on: January 25, 2014, 10:46:20 am »
Hi, again

 I have got a problem with  TLabeledNumberEdit

TLabeledNumberEdit  is a  new  control (class) derivated from TLabeledEdit class.

 TLabeledEdit  is a special class in the Lazarus LCL: is based on a TEdit control (parent) and inside has another control: TStaticText called EditLabel.

I would like add new propertys inside TEdit (parent) and other propertys  inside EditLabel (child)

If in the public section  I add

Code: [Select]
property ColorError      : TColor   read FColorError      write FColorError;
This property appears "in the root" of the object inspector (parent propertys). That's right!

I make the same, for adding another property for EditLabel child. This property would be inside EditLabel tag in the object inspector, and not in the root, with the parent properties.

The following source code:
Quote
property EditLabel.ColorErrorLabel      : TColor   read FColorErrorLabel      write FColorErrorLabel;

doesn't works properly. I get a message error when It was compiling

Is there any easy way to add this property to the child class  ( EditLabel ) in the object inspector?


Thanks in advanced

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Issues with subclass creation
« Reply #18 on: January 25, 2014, 11:16:56 am »
You would need to share the complete code for your new component before others could comment sensibly on how to achieve what you are after.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Issues with subclass creation
« Reply #19 on: January 25, 2014, 05:11:03 pm »
Just remove the bold (editLabel)part from the property declaration, it should compile after that. If you want to change the included components then you have to rewrite the full control from the start you need to write 3 controls in total 1 the label with the extra properties you need 2 the edit with the extra properties and 3 rewrite the labelededit do not inherit this one write it from scratch using the new component you just wrote.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Issues with subclass creation
« Reply #20 on: January 26, 2014, 02:40:33 pm »
This is a simplified version - "stupid version", but it works properly if you compile - of source code of new  TLabeledNumberEdit control,   derivated from TLabeledEdit
Code: [Select]
unit LabeledNumberEdit;

{$mode objfpc}{$H+}


interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls;

type
   tNumero = ( real, entero );

   TLabeledNumberEdit = class(TLabeledEdit)
   private
      { Private declarations }
      Fmode                                    : tNumero;
      FColorError                              : TColor;
      FColorErrorLabel                         : TColor;
      FColorErrorTime                          : cardinal;
      FColorErrorLabelTime                     : cardinal;
   protected
     { Protected declarations }
   public
     { Public declarations }
      constructor Create(AOwner : TComponent) ;   override;
      destructor  Destroy;                        override;
   published
     { Published declarations }
      property Mode                : tNumero  read FMode                write FMode;
      property ColorError          : TColor   read FColorError          write FColorError;
      property ColorErrorTime      : cardinal read FColorErrorTime      write FColorErrorTime;
      property ColorErrorLabel     : TColor   read FColorErrorLabel     write FColorErrorLabel;
      property ColorErrorLabelTime : cardinal read FColorErrorLabelTime write FColorErrorLabelTime;
   end;

procedure Register;

implementation

procedure Register;
begin
  {$I labelednumberedit_icon.lrs}
  RegisterComponents('Additional',[TLabeledNumberEdit]);
end;

constructor TLabeledNumberEdit.Create(AOwner : TComponent);
begin
   inherited Create (AOwner);
   FMode                := real;
   FColorError          := clRed;
   FColorErrorLabel     := clRed;
   FColorErrorLabelTime := 500;
   FColorErrorTime      := 500;

end;

destructor TLabeledNumberEdit.Destroy;
begin
   inherited Destroy;
end;



end.   

The ColorErrorLabel and ColorErrorLabelTime are properties for EditLabel child control and not properties for parent control. I think, that the right place for those properties would be inside EditLabel (child) properties in the object inspector,  and not in  the root (parent class).


Quote
property EditLabel.ColorErrorLabel      : TColor   read FColorErrorLabel      write FColorErrorLabel;
Quote
Just remove the bold (editLabel)part from the property declaration, it should compile after that.

Well I thought, that If I add the bold code, the properties appear inside "EditLabel" (The easy way!!) but not!!

Quote
If you want to change the included components then you have to rewrite the full control from the start you need to write 3 controls in total 1 the label with the extra properties you need 2 the edit with the extra properties and 3 rewrite the labelededit do not inherit this one write it from scratch using the new component you just wrote.


The  second attempt was how you said   (very long  way) : created three controls.  My code compile, but I lost  my child (and all their properties) !!

Code: [Select]
unit LabeledNumberEdit;

{$mode objfpc}{$H+}


interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls;



type
   tNumero = ( real, entero );

   TBoundLabelMejorado = class(TBoundLabel)
   private
      { Private declarations }
      FColorErrorLabel                         : TColor;
      FColorErrorLabelTime                     : cardinal;
   protected
     { Protected declarations }
   public
     { Public declarations }
     constructor Create(AOwner : TComponent) ;   override;
   published
     { Published declarations }
      property ColorErrorLabel     : TColor   read FColorErrorLabel     write FColorErrorLabel;
      property ColorErrorLabelTime : cardinal read FColorErrorLabelTime write FColorErrorLabelTime;
   end;


   TCustomLabeledEditMejorado = class(TCustomLabeledEdit)
    private
     FEditLabel: TBoundLabelMejorado;
     FLabelPosition: TLabelPosition;
     FLabelSpacing: Integer;
//     procedure SetLabelPosition(const Value: TLabelPosition);
//     procedure SetLabelSpacing(const Value: Integer);
   protected

   public
     constructor Create(AOwner: TComponent); override;
     property EditLabel: TBoundLabelMejorado read FEditLabel;
//     property LabelPosition: TLabelPosition read FLabelPosition
//                                          write SetLabelPosition default lpAbove;
//     property LabelSpacing: Integer read FLabelSpacing write SetLabelSpacing                                                                       default 3;
   end;

   TLabeledEditMejorado = class(TCustomLabeledEditMejorado)
   published
      property Alignment;
      property Anchors;
      property AutoSelect;
      property AutoSize;
      property BidiMode;
      property BorderSpacing;
      property BorderStyle;
      property CharCase;
      property Color;
      property Constraints;
      property DragCursor;
      property DragMode;
      property EchoMode;
      property EditLabel;
      property Enabled;
      property Font;
      property LabelPosition;
      property LabelSpacing;
      property MaxLength;
      property ParentBidiMode;
      property ParentColor;
      property ParentFont;
      property ParentShowHint;
      property PasswordChar;
      property PopupMenu;
      property ReadOnly;
      property ShowHint;
      property TabOrder;
      property TabStop;
      property Text;
      property Visible;
      property OnChange;
      property OnClick;
      property OnDblClick;
      property OnDragDrop;
      property OnDragOver;
      property OnEditingDone;
      property OnEndDrag;
      property OnEnter;
      property OnExit;
      property OnKeyDown;
      property OnKeyPress;
      property OnKeyUp;
      property OnMouseDown;
      property OnMouseMove;
      property OnMouseUp;
      property OnStartDrag;
      property OnUTF8KeyPress;
   end;


   TLabeledNumberEdit = class(TLabeledEditMejorado)
   private
      { Private declarations }
      Fmode                                    : tNumero;
      FColorError                              : TColor;
      FColorErrorTime                          : cardinal;
   protected
     { Protected declarations }
   public
     { Public declarations }
      constructor Create(AOwner : TComponent) ;   override;
      destructor  Destroy;                        override;
   published
     { Published declarations }
      property Mode                : tNumero  read FMode                write FMode;
      property ColorError          : TColor   read FColorError          write FColorError;
      property ColorErrorTime      : cardinal read FColorErrorTime      write FColorErrorTime;
   end;

procedure Register;

implementation

procedure Register;
begin
  {$I labelednumberedit_icon.lrs}
  RegisterComponents('Additional',[TLabeledNumberEdit]);
end;


constructor TBoundLabelMejorado.Create(AOwner : TComponent);
begin
   inherited Create (AOwner);
     Name := 'SubLabel';
  SetSubComponent(True);
  if Assigned(AOwner) then
    Caption := AOwner.Name;
   FColorErrorLabel     := clRed;
   FColorErrorLabelTime := 500;
end;


constructor TCustomLabeledEditMejorado.Create(AOwner : TComponent);
begin
   inherited Create (AOwner);
     FLabelPosition := lpAbove;
  FLabelSpacing := 3;
  CreateInternalLabel;
end;

constructor TLabeledNumberEdit.Create(AOwner : TComponent);
begin
   inherited Create (AOwner);
   FMode                := real;
   FColorError          := clRed;
   FColorErrorTime := 500;
end;

destructor TLabeledNumberEdit.Destroy;
begin
   inherited Destroy;
end;



end.   



I Modified TBoundLabel for adding new properties. New control name: TBoundLabelMejorado ( Mejorado = enhanced, in Spainsh). Next , I made TCustomLabeledEditMejorado from TCustomLabeledEdit changed only FEditLabel from TBoundLabel type to TBoundLabelMejorado type. And I finaly, TLabeledEditMejorado.  I don't know where I lost my child class TLabeledEditMejorado.

Any suggestions?

There is other way. I think, the easiest way is to edit the extctrl.pp file and  add on line 822 one private section with my new variables. Not the most elegant, but it works. I prefer the second attempt, but I don't know how I do
Any ideas?

Thanks in advanced

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Issues with subclass creation
« Reply #21 on: February 01, 2014, 07:49:55 pm »
I've finished the new control but I have a question. I've duplicated TBoundLabel (adding  extra properties ) and  TCustomLabeledEdit controls (changing
Code: [Select]
FEditLabel                               : TBoundLabel;  to FEditLabel                               : TBoundLabelMejorado; ).

This last control ,TCustomLabeledEdit, in the protected  section has the following statement:

Code: [Select]
class procedure WSRegisterClass; override;
and more later:

Quote
class procedure TCustomLabeledEdit.WSRegisterClass;
begin
  inherited WSRegisterClass;
  RegisterCustomLabeledEdit;
end;   

RegisterCustomEdit function is defined in the ws32wsfactory file:

Code: [Select]
function RegisterCustomLabeledEdit: Boolean;
Quote
function RegisterCustomLabeledEdit: Boolean; alias : 'WSRegisterCustomLabeledEdit';
begin
  Result := False;
end;

I don't understand the meaning of this function. What does it do? Is "WSRegisterClass"  function necessary to duplicate  for working properly the new version of  TCustomLabeledEdit control?

Regards

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12345
  • Debugger - SynEdit - and more
    • wiki
Re: Issues with subclass creation
« Reply #22 on: February 01, 2014, 08:19:40 pm »
"WSRegister"

Is only needed if you need new widgetset functionality (code that is specific to win, gtk2 or carbon, ...).

And even then, in your own component, you would normally use IFDEF.

In short, you should not need any WSRegister...

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Issues with subclass creation
« Reply #23 on: February 02, 2014, 10:37:04 am »
OK! Thanks a lot

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Issues with subclass creation
« Reply #24 on: February 05, 2014, 12:47:43 pm »
Hi again!!
I've got another problem. I'm  trying  to put together 3 TEdit controls inside a TGroupBox control (TGroupBox1 is the name of new class/control).

This is the code and compiles OK!!:

Code: [Select]
unit GroupBox1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, Lmessages;

type
  TGroupBox1 = class(TGroupBox)
  private
    { Private declarations }
    FLigado1                                 : TEdit;
    FLigado2                                 : TEdit;
    FLigado3                                 : TEdit;
    procedure x3SetColor (FColor : TColor);
    function  x3GetColor (): TColor;
    procedure x3SetFont (FFont : TFont);
    function  x3GetFont (): TFont;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner : TComponent) ;   override;
    destructor  Destroy;                        override;
  published
    { Published declarations }
    property x3Color      : TColor   read x3GetColor write x3SetColor;
    property x3Font       : TFont    read x3GetFont       write x3SetFont;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Standard',[TGroupBox1]);
end;



procedure TGroupBox1.x3SetColor (FColor : TColor);
begin
   Fligado1.Color := FColor;
   Fligado2.Color := FColor;
   Fligado3.Color := FColor;
end;

function TGroupBox1.x3GetColor : TColor;
begin
   x3GetColor := FLigado1.Color;
end;

procedure TGroupBox1.x3SetFont (FFont : TFont);
begin
   if FLigado1.Font = FFont then Exit;
   FLigado1.Font.Assign (FFont);
   FLigado2.Font.Assign (FFont);
   FLigado3.Font.Assign (FFont);
   Perform(CM_FONTCHANGED, 0, 0);
end;

function  TGroupBox1.x3GetFont (): TFont;
begin
   x3GetFont.Assign (Fligado1.Font);
end;

constructor TGroupBox1.Create(AOwner : TComponent);
begin      (* Parametros iniciales de TGRoupBox*)
   inherited Create (AOwner);
   BidiMode := bdRightToLeft;
   Height := 136;
   Width := 176;
   ClientHeight := 118;
   ClientWidth := 172;
   Constraints.MaxHeight:=136;
   Constraints.MaxWidth:=176;
   Constraints.MinHeight:=136;
   Constraints.MinWidth:=176;
   FLigado1:= TEdit.Create(Self);
   FLigado1.Parent:= Self;
   FLigado1.SetSubComponent(true);
   FLigado1.Name:= 'X';
   FLigado1.ControlStyle := FLigado1.ControlStyle - [csNoDesignSelectable];
   FLigado1.Left := 40;
   FLigado1.Height := 24;
   FLigado1.Top := 5;
   FLigado1.Width := 130;
   FLigado2:= TEdit.Create(Self);
   FLigado2.Parent:= Self; (* Parametros iniciales del SEGUNDO Subcontrol dentro de TGRoupBox*)
   FLigado2.SetSubComponent(true);
   FLigado2.Name:= 'Y';
   FLigado2.ControlStyle := FLigado2.ControlStyle - [csNoDesignSelectable];
   FLigado2.Left := 40;
   FLigado2.Height := 24;
   FLigado2.Top := 44;
   FLigado2.Width := 130;
   FLigado3:= TEdit.Create(Self);
   FLigado3.Parent:= Self; (* Parametros iniciales del TERCER Subcontrol dentro de TGRoupBox*)
   FLigado3.SetSubComponent(true);
   FLigado3.Name:= 'Z';
   FLigado3.ControlStyle := FLigado3.ControlStyle - [csNoDesignSelectable];
   FLigado3.Left := 40;
   FLigado3.Height := 24;
   FLigado3.Top := 83;
   FLigado3.Width := 130;
end;

destructor TGroupBox1.Destroy;
begin
   inherited Destroy;
end;





end.                     

I've a created a new property  (x3Color) in the object inspector to change Color inside each TEdit  control simultaneously and it works properly, but if I do the same, for changing the font in each TEdit, I get "Acess violation" error. If I delete all the code about "fonts" (x3Font property and functions/procedure, the code is OK)

What's wrong with the font source code?

Best Regards!!

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Issues with subclass creation
« Reply #25 on: February 05, 2014, 01:34:29 pm »
This function does not return a value (did you read your compiler messages?). More over it calles itself and it assigns a value to a result that does not exist!  :)
 
Code: [Select]
function  TGroupBox1.x3GetFont (): TFont;
begin
   x3GetFont.Assign (Fligado1.Font);
end;

pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Issues with subclass creation
« Reply #26 on: February 05, 2014, 02:18:16 pm »
Engkin, the  source code  compiles Ok, without any error Messages and no warnings (no compiler messages!!, only OK!! ).

How I must change this function and particulary this statement

 x3GetFont.Assign (Fligado1.Font);

for X3GetFont (type TFont) is equal to Fligado1.Font (type TFont)?

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Issues with subclass creation
« Reply #27 on: February 05, 2014, 03:05:08 pm »
Engkin, the  source code  compiles Ok, without any error Messages and no warnings (no compiler messages!!, only OK!! ).
I got
Quote
groupbox1.pas(67,13) Warning: Function result variable does not seem to initialized

I assume you need to change it to:
Result := Fligado1.Font;


pusuni

  • Jr. Member
  • **
  • Posts: 72
Re: Issues with subclass creation
« Reply #28 on: February 05, 2014, 04:09:57 pm »
engkin, it's very strange: I haven't got any error messages from the compiler and I do not remember changing any compiler options ( all is "by default")

Anyway, your code is  right. I compile and it does what it is supposed to do


Thanks a lot, engkin!!

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Issues with subclass creation
« Reply #29 on: February 06, 2014, 02:56:08 am »
Glad it worked for you.

engkin, it's very strange: I haven't got any error messages from the compiler and I do not remember changing any compiler options ( all is "by default")
On my side I can hide/show hints, warnings...etc using:
Project Options (Shift + Ctrl + F11)
  Compiler Options
    Verbosity
Maybe you want to check that.

 

TinyPortal © 2005-2018