Solved

Setting properties on new components

Posted on 1998-07-01
6
158 Views
Last Modified: 2010-04-04
My problems is about setting componentproperties as runtime.

I have made 2 test components to show my problem, TMyEdit and TMyGroupBox.
TMyEdit.Enable will (in this test) set its background to red.
MyGroupBox.Enable will iterate all components in it and set the Enable property on them.

Here are snips from my code:

  TMyEdit = class(TEdit)
  private
    Function GetEnabled: Boolean;
    Procedure SetEnabled(ABoolean: Boolean);
  protected
  public
  published
    Property Enabled: Boolean Read GetEnabled Write SetEnabled;
  end;

Function TMyEdit.GetEnabled: Boolean;
begin
  Result := Inherited Enabled;
end;

Procedure TMyEdit.SetEnabled(ABoolean: Boolean);
begin
  if ABoolean <> Enabled then
  begin
    if ABoolean then
      Color := clWindow
    else
      Color := clRed;
    Inherited Enabled := ABoolean;
  end;
end;



  TMyGroupBox = class(TGroupBox)
  private
    Function GetEnabled: Boolean;
    Procedure SetEnabled(ABoolean: Boolean);
  protected
  public
  published
    Property Enabled: Boolean Read GetEnabled Write SetEnabled;
  end;

Function TMyGroupBox.GetEnabled: Boolean;
begin
  Result := Inherited Enabled;
end;

Procedure TMyGroupBox.SetEnabled(ABoolean: Boolean);
Var
  i: Integer;
begin
  if ABoolean <> Enabled then
  begin
    for i := 0 to ControlCount-1 do
      Controls[i].Enabled := ABoolean;
    Inherited Enabled := ABoolean;
  end;
end;


What I do is that I put a MyGroupBox on a form and drops a MyEdit in it. Now, if I at runtime change the Enabled value of MyEdit, the background will change accordingly.
If I change Enabled for MyGroupBox, it will not call (Set)Enabled for MyEdit but instead it calls it on TEdit (the parent component).
Now, if I change the For loop to read

    for i := 0 to ControlCount-1 do
      if (Controls[i] is TMyListBox) then
      (Controls[i] As TMyListBox).Enabled := ABoolean
      else
        Controls[i].Enabled := ABoolean;

it will work. But I don't want MyGroupBox to know all possible components that I will drop in it.

Anyone has a clue?
0
Comment
Question by:BlackMan
  • 4
  • 2
6 Comments
 
LVL 7

Author Comment

by:BlackMan
ID: 1356746
Edited text of question
0
 
LVL 3

Accepted Solution

by:
vladika earned 100 total points
ID: 1356747
Here is Delphi source

procedure TControl.SetEnabled(Value: Boolean);
begin
  if FEnabled <> Value then
  begin
    FEnabled := Value;
    Perform(CM_ENABLEDCHANGED, 0, 0);
  end;
end;

So you can process CM_ENABLEDCHANGED message as

  TMyEdit = class(TEdit)
  private
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  end;

  TMyGroupBox = class(TGroupBox)
  private
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  end;


procedure TMyEdit.CMEnabledChanged(var Message: TMessage);
begin
 if Enabled then Color := clWindow else Color := clRed;
end;

procedure TMyGroupBox.CMEnabledChanged(var Message: TMessage);
var I: Integer;
begin
  for I := 0 to ControlCount-1 do
    Controls[I].Enabled := Enabled;
end;


0
 
LVL 7

Author Comment

by:BlackMan
ID: 1356748
That one works, but can you explain why MyEdit.Enabled is not called in my component?
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 7

Author Comment

by:BlackMan
ID: 1356749
Oops, I was to quick to send the other comment :-)
Your code works fine for Enabled but what if it was another property, like one I made myself?
0
 
LVL 3

Expert Comment

by:vladika
ID: 1356750
The problem is that GetEnabled and SetEnabled in TControl is not virtual.
If it were virtual you simple override it and all.
Suppose exists two class
type
  TClass1 = class
  public
    procedure Print;
  end;

  TClass2 = class(TClass1)
  public
    procedure Print;
  end;

procedure TClass1.Print;
begin
  // print 'Class 111'
end;

procedure TClass2.Print;
begin
  // print 'Class 222'
end;

 and procedure ..
procedure Test(C: TClass1);
begin
  C.Print;
end;

 and you have two variables
var C1: TClass1;
     C2: TClass2;

C1 := TClass1.Create;  // Type of C1 is Class1
C2 := TClass2.Create;  // Type of C2 is Class2

if you call Test(C1) you see 'Class 111'
if you call Test(C2) you as well as see 'Class 111' becouse Print is not virtual

if Print was virtual you see in first case 'Class 111' and 'Class 222' in second case

It is reason.

So, Delphi does not allow you override property Enabled but
notify you about its changing.

If it was another property and Get/Set not virtual and no notify message
I am afraid it is impossible

So, If you write components yourself make Get/Set protected and virtual.


0
 
LVL 7

Author Comment

by:BlackMan
ID: 1356751
Thanks
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to renew a Delphi rad-studio licence? 5 69
Performance of SQL statement 37 124
Multi-layered image in FireMonkey 9 48
MS Access from Delphi 31 59
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

791 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question