0
votes

how can i get dynamic values for my component's property variable

in my component i have a field named ColorDefault and i want to be able to set its value dynamically in program.

Original code

var // global
  _V_TB_DefaultColor: TColor

type
  TMyClass = class
  ...
  property ColorDefault: tcolor read _V_TB_DefaultColor write FDefaultColor;
  //[dcc32 Error] MyButton.pas(85): E2168 Field or method identifier expected
  ...
  end;

Edit:

I did as below as tom described but color is not changing according to the global variable, color stays as when it is complied, for example my global color was clyellow and i complied my component and place it on the form and after that i changed the global color variable to clwhite and when i run the program it is still clyellow

type
  TTestClass = class(TPanel)
  private
    { Private declarations }
  protected
    { Protected declarations }
    FColorDefault:tcolor;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function GetGlobalColorVariable:TColor;
  published
    { Published declarations }
    property DefaultColor:TColor read GetGlobalColorVariable write FColorDefault;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MyComponents', [TTestClass]);
end;


constructor TTestClass.Create(AOwner: TComponent);
begin
  ColorInitiate;
  inherited;
  color:=DefaultColor;
end;

destructor TTestClass.Destroy;
begin
  inherited;
end;

function TTestClass.GetGlobalColorVariable: TColor;
begin
  result:=_V_TB_DefaultColor;
end;

end.
3
There is no much sense in FDefaultColor field, if you want to read property value from another variableMBo
I don't see any property declaration for ColorDefault, neither any declaration of _V_TB_DefaultColor. Please be consistent with your identifiers. This question is different from what you originally asked and is becoming a mess. Did you read the documentation about properties yet? If you want to change a property you have to assign a new value to it.Tom Brunberg
If you expect the ColorDefault property to change, just by changing _V_TB_DefaultColor the answer is no, that will not happen, there's no such automagic. I added a paragraph about this to my answer.Tom Brunberg
Please @Emre, do not change your post so that previously written answers become invalid. In these situations it is preferable to add new code without removing old one. I added the code from your first comments, so lets clean up and delete obsolete comments. If you move te mouse over your comment a round button appears after your comment. Use that to delete.Tom Brunberg
@TomBrunberg sorry about that i need to get used using forum :) i did delete my commentsEmre Acikgoz

3 Answers

0
votes

Looking at your question it seems that you are dealing with two problems.

First problem is how to access some global variable using property.

You can do this by using Getter method of your property like so:

type
  TTestClass = class(TPanel)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    function GetDefaultColor: TColor;
  published
    { Published declarations }
    property DefaultColor: TColor read GetDefaultColor;
  end;

var // global
  _V_TB_DefaultColor: TColor

implementation

function TTestClass.GetGlobalColorVariable: TColor;
begin
  result := _V_TB_DefaultColor;
end;

That is like you did in your question edit. This will always make your DefaultColor property to return the same value as it is stored in your global _V_TB_DefaultColor variable.

But do note that this won't detect when _V_TB_DefaultColor variable was changed. So if you want to update your components after the change you need to execute some updating procedure for each of them yourself.

Also bare in mind that using global variables like this is not a good practice.

If you want certain property of all of your components to have the same value the it would be much better to declare that property as class property like in the code bellow.

type
  TTestClass = class(TPanel)
  private
    { Private declarations }
    class var FDefaultColor: TColot;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    class function GetDefaultColor: TColor;
  published
    { Published declarations }
    class property DefaultColor: TColor read FDefaultColor write FDefaultColor;
  end;

Now changing your DefaultColor in one component will change DefaultColor for all components of the same class. But bare in mind that you will still have to execute proper procedure for each of your components to update itself. That won't be done automatically.


Now your second problem is to detect the change of your DefaultColor variable and update your component/s accordingly.

Now if you use global variable there is no mechanism to detect this. But if you are using class procedure then you can at least write a setter method that will either execute update methods of all of your components that needs to be updated or send them necessary notification so they can perform necessary update by themselves.

How to implement this?

One way would be to loop through all your forms components checking their type and executing necessary update procedure. But that can be quite slow if you have lots of other components that you need to check if they are correct ones.

Another probably better approach would be adding your components on separate list so you don't need to be type checking as you know that such list only contains the right components.

0
votes

You neeed to review the documentation about properties http://docwiki.embarcadero.com/RADStudio/XE7/en/Properties

Your code

property ColorDefault:tcolor read _V_TB_DefaultColor write FDefaultColor;

is not approved by the compiler because _V_TB_DefaultColor is not a field or method of your class. The property should probably be declared as:

property ColorDefault:tcolor read FDefaultColor write FDefaultColor;

To set FDefaultColor equal to the global variable _V_TB_DefaultColor you need

MyClass.ColorDefault := _V_TB_DefaultColor;

at a suitable place in your code, f.ex in the constructor of your class.

Note, that to change the color of your component, you need to assign a new value to the ColorDefault property. Changing the value of your global variable _V_TB_DefaultColor will not automagically change the value of the property.


In your revised code you added

function TTestClass.GetGlobalColorVariable: TColor;
begin
  result:=_V_TB_DefaultColor;
end;

That will not do anything if you dont assign the result of the function to something. Since the function is a member of TTestCalss I believe you want to set the Color property directly in this function:

function TTestClass.GetGlobalColorVariable: TColor;
begin
  Color:=_V_TB_DefaultColor;
end;

If this is the case, you can change it to a procedure because you dont use the return value:

procedure TTestClass.GetGlobalColorVariable;
begin
  Color:=_V_TB_DefaultColor;
end;
0
votes

thanks everyone,

with all the suggestions what i do is using a function to get the value from global variable and using windows messages as trigger to apply the new values to component