Solved

Setting properties on new components

Posted on 1998-07-01
6
161 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…

726 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