Solved

Setting properties on new components

Posted on 1998-07-01
6
153 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
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
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

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Process Javascript errors with Delphi TWebBrowser 1 129
QRReport  TQrmemo vertical stretching 1 45
Convert MS Word document to a PDF file 9 78
Delphi...Split view - idea? 1 67
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

813 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now