bnz
asked on
Component Properties read component#2
Another question regarding properties.
I have a TControl property in my component, I place the component and a checkbutton on the form then assign then checkbutton to the control-property.
I then select the checkbox again and cut it using ctrl+x, bang I get a big error and have to close delphi. What can I do?
I have a TControl property in my component, I place the component and a checkbutton on the form then assign then checkbutton to the control-property.
I then select the checkbox again and cut it using ctrl+x, bang I get a big error and have to close delphi. What can I do?
ASKER
I just choose the checkbox in TControl property via Object Inspector.
I will post the code - it's a free component I'm working on. Hope it's not too big.
unit CheckGroupBox;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
//Hack to read protected properties
TControlFake = class(TControl);
TButtonControlFake = class(TButtonControl);
TEnabledEvent = procedure(Sender: TObject; Enabled: boolean) of object;
TCheckGroupBox = class(TGroupBox)
private
OldCaption: string;
FPositionCheckComponent: Boolean;
FOnEnabled: TEnabledEvent;
FCheckComponent: TControl;
FOldCheckComponentOnClick: TNotifyEvent;
procedure SetCaption(const Value: TCaption);
procedure SetCheckComponent(const Value: TControl);
procedure CheckComponentOnClick(Send er: TObject);
function CheckComponentChecked: boolean;
procedure SetPositionCheckComponent( const Value: Boolean);
function ComponentToString(Componen t: TComponent): string;
protected
procedure SetEnabled(Value: Boolean); override;
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
procedure Update; override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
published
property OnEnabled: TEnabledEvent read FOnEnabled write FOnEnabled;
property Caption write SetCaption;
property CheckComponent: TControl read FCheckComponent write SetCheckComponent;
property PositionCheckComponent: Boolean read FPositionCheckComponent write SetPositionCheckComponent;
end;
procedure Register;
implementation
{$R CheckGroupBox.Res}
procedure Register;
begin
RegisterComponents('Sample s', [TCheckGroupBox]);
end;
constructor TCheckGroupBox.Create(AOwn er: TComponent);
begin
inherited;
PositionCheckComponent := True;
OldCaption := Caption;
end;
procedure TCheckGroupBox.Loaded;
begin
inherited;
Update;
end;
procedure TCheckGroupBox.Update;
begin
inherited;
Caption := Caption;
Left := Left;
Top := Top;
PositionCheckComponent := FPositionCheckComponent;
Enabled := Enabled and CheckComponentChecked;
end;
procedure TCheckGroupBox.SetCaption( const Value: TCaption);
begin
if Value <> '' then
OldCaption := Value;
//if FCheckComponent <> nil clear groupbox caption
if FCheckComponent <> nil then
inherited Caption := ''
else
inherited Caption := OldCaption;
end;
procedure TCheckGroupBox.SetBounds(A Left, ATop, AWidth, AHeight: Integer);
begin
inherited;
//Update CheckComponent position
PositionCheckComponent := FPositionCheckComponent;
end;
procedure TCheckGroupBox.SetCheckCom ponent(con st Value: TControl);
begin
width := width +5;
if Value is TCheckGroupBox then
raise Exception.Create('Assigned TCheckGroupBox to itself');
FCheckComponent := Value;
if FCheckComponent <> nil then
begin
FCheckComponent.FreeNotifi cation(Sel f);
FCheckComponent.BringToFro nt;
//Saves old eventhandler
if Assigned( TControlFake(FCheckCompone nt).OnClic k ) then
FOldCheckComponentOnClick := TControlFake(FCheckCompone nt).OnClic k;
TControlFake(FCheckCompone nt).OnClic k := CheckComponentOnClick;
Update;
end;
end;
procedure TCheckGroupBox.SetPosition CheckCompo nent(const Value: Boolean);
begin
//Align check component at groupbox
FPositionCheckComponent := Value;
if Value and (FCheckComponent <> nil) then
begin
FCheckComponent.Left := Left + 8;
FCheckComponent.Top := Top - 3;
end;
end;
procedure TCheckGroupBox.SetEnabled( Value: Boolean);
var
i: integer;
begin
inherited;
//Disable all controls
for i := 0 to ControlCount-1 do
Controls[i].Enabled := Value and CheckComponentChecked;
if Assigned(OnEnabled) then
FOnEnabled(Self, Value);
end;
function TCheckGroupBox.CheckCompon entChecked : boolean;
var
S: string;
begin
if FCheckComponent is TButtonControl then
Result := TButtonControlFake(FCheckC omponent). Checked
else if FCheckComponent <> nil then
//Read the properties of the CheckComponent, it must have a property named Checked
begin
S := ComponentToString(FCheckCo mponent);
Result := Pos('Checked = True', S) > 0;
end
else
Result := True;
end;
function TCheckGroupBox.ComponentTo String(Com ponent: TComponent): string;
var
StrStream: TStringStream;
begin
StrStream := TStringStream.Create(Resul t);
try
StrStream.WriteComponent(C omponent);
StrStream.Position := 0;
ObjectBinaryToText(StrStre am, StrStream);
StrStream.Position := 0;
Result := StrStream.DataString;
finally
StrStream.Free;
end;
end;
procedure TCheckGroupBox.CheckCompon entOnClick (Sender: TObject);
begin
Enabled := CheckComponentChecked;
//Call old event
if Assigned(FOldCheckComponen tOnClick) then
FOldCheckComponentOnClick( Self);
end;
end.
I will post the code - it's a free component I'm working on. Hope it's not too big.
unit CheckGroupBox;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
//Hack to read protected properties
TControlFake = class(TControl);
TButtonControlFake = class(TButtonControl);
TEnabledEvent = procedure(Sender: TObject; Enabled: boolean) of object;
TCheckGroupBox = class(TGroupBox)
private
OldCaption: string;
FPositionCheckComponent: Boolean;
FOnEnabled: TEnabledEvent;
FCheckComponent: TControl;
FOldCheckComponentOnClick:
procedure SetCaption(const Value: TCaption);
procedure SetCheckComponent(const Value: TControl);
procedure CheckComponentOnClick(Send
function CheckComponentChecked: boolean;
procedure SetPositionCheckComponent(
function ComponentToString(Componen
protected
procedure SetEnabled(Value: Boolean); override;
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
procedure Update; override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
published
property OnEnabled: TEnabledEvent read FOnEnabled write FOnEnabled;
property Caption write SetCaption;
property CheckComponent: TControl read FCheckComponent write SetCheckComponent;
property PositionCheckComponent: Boolean read FPositionCheckComponent write SetPositionCheckComponent;
end;
procedure Register;
implementation
{$R CheckGroupBox.Res}
procedure Register;
begin
RegisterComponents('Sample
end;
constructor TCheckGroupBox.Create(AOwn
begin
inherited;
PositionCheckComponent := True;
OldCaption := Caption;
end;
procedure TCheckGroupBox.Loaded;
begin
inherited;
Update;
end;
procedure TCheckGroupBox.Update;
begin
inherited;
Caption := Caption;
Left := Left;
Top := Top;
PositionCheckComponent := FPositionCheckComponent;
Enabled := Enabled and CheckComponentChecked;
end;
procedure TCheckGroupBox.SetCaption(
begin
if Value <> '' then
OldCaption := Value;
//if FCheckComponent <> nil clear groupbox caption
if FCheckComponent <> nil then
inherited Caption := ''
else
inherited Caption := OldCaption;
end;
procedure TCheckGroupBox.SetBounds(A
begin
inherited;
//Update CheckComponent position
PositionCheckComponent := FPositionCheckComponent;
end;
procedure TCheckGroupBox.SetCheckCom
begin
width := width +5;
if Value is TCheckGroupBox then
raise Exception.Create('Assigned
FCheckComponent := Value;
if FCheckComponent <> nil then
begin
FCheckComponent.FreeNotifi
FCheckComponent.BringToFro
//Saves old eventhandler
if Assigned( TControlFake(FCheckCompone
FOldCheckComponentOnClick := TControlFake(FCheckCompone
TControlFake(FCheckCompone
Update;
end;
end;
procedure TCheckGroupBox.SetPosition
begin
//Align check component at groupbox
FPositionCheckComponent := Value;
if Value and (FCheckComponent <> nil) then
begin
FCheckComponent.Left := Left + 8;
FCheckComponent.Top := Top - 3;
end;
end;
procedure TCheckGroupBox.SetEnabled(
var
i: integer;
begin
inherited;
//Disable all controls
for i := 0 to ControlCount-1 do
Controls[i].Enabled := Value and CheckComponentChecked;
if Assigned(OnEnabled) then
FOnEnabled(Self, Value);
end;
function TCheckGroupBox.CheckCompon
var
S: string;
begin
if FCheckComponent is TButtonControl then
Result := TButtonControlFake(FCheckC
else if FCheckComponent <> nil then
//Read the properties of the CheckComponent, it must have a property named Checked
begin
S := ComponentToString(FCheckCo
Result := Pos('Checked = True', S) > 0;
end
else
Result := True;
end;
function TCheckGroupBox.ComponentTo
var
StrStream: TStringStream;
begin
StrStream := TStringStream.Create(Resul
try
StrStream.WriteComponent(C
StrStream.Position := 0;
ObjectBinaryToText(StrStre
StrStream.Position := 0;
Result := StrStream.DataString;
finally
StrStream.Free;
end;
end;
procedure TCheckGroupBox.CheckCompon
begin
Enabled := CheckComponentChecked;
//Call old event
if Assigned(FOldCheckComponen
FOldCheckComponentOnClick(
end;
end.
ASKER
the width:=width+5 is just to see when the SetCheckComponent is called, it doesn't get called when I cut the component away.
I cannot seem to duplicate your problem.
I compiled the code. I did make a change to the compiler directive. I removed {$R GroupCheckBox.Res}.
I tried putting a Checkbox on the control and then ctrl-x...no problem.
Then I tried a radio button...still no problem
When you used the wizard to create the new control did you select TControl (Controls) or TControls (QControls)..I'm not sure what difference it would make but I selected TControl (Controls). I did not try the QControls....
I compiled the code. I did make a change to the compiler directive. I removed {$R GroupCheckBox.Res}.
I tried putting a Checkbox on the control and then ctrl-x...no problem.
Then I tried a radio button...still no problem
When you used the wizard to create the new control did you select TControl (Controls) or TControls (QControls)..I'm not sure what difference it would make but I selected TControl (Controls). I did not try the QControls....
you should override the notification-method,
and set your property to nil there if your checkbox tells you there that it will be removed
(Action = opRemove)
meikl ;-)
and set your property to nil there if your checkbox tells you there that it will be removed
(Action = opRemove)
meikl ;-)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Yes, very nice... thanks
how did you bind the two together? (...assign the checkbutton to the control-property...) Just undo what ever it is you did.
More information would be beneficial the the other experts and would probably get your problem solved quicker.