Solved

Component Properties read component#2

Posted on 2001-08-07
7
211 Views
Last Modified: 2010-04-06
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?
0
Comment
Question by:bnz
  • 3
  • 2
  • 2
7 Comments
 
LVL 21

Expert Comment

by:gemarti
ID: 6362159
Maybe you need to disassociate the checkbutton from your control when your app detects ctrl x.
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.
0
 

Author Comment

by:bnz
ID: 6362184
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(Sender: TObject);
    function CheckComponentChecked: boolean;
    procedure SetPositionCheckComponent(const Value: Boolean);
    function ComponentToString(Component: 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('Samples', [TCheckGroupBox]);
end;

constructor TCheckGroupBox.Create(AOwner: 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(ALeft, ATop, AWidth, AHeight: Integer);
begin
  inherited;
  //Update CheckComponent position
  PositionCheckComponent := FPositionCheckComponent;
end;

procedure TCheckGroupBox.SetCheckComponent(const 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.FreeNotification(Self);
    FCheckComponent.BringToFront;
    //Saves old eventhandler
    if Assigned( TControlFake(FCheckComponent).OnClick ) then
        FOldCheckComponentOnClick := TControlFake(FCheckComponent).OnClick;

    TControlFake(FCheckComponent).OnClick := CheckComponentOnClick;
    Update;
  end;
end;

procedure TCheckGroupBox.SetPositionCheckComponent(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.CheckComponentChecked: boolean;
var
  S: string;
begin
  if FCheckComponent is TButtonControl then
    Result := TButtonControlFake(FCheckComponent).Checked
  else if FCheckComponent <> nil then
  //Read the properties of the CheckComponent, it must have a property named Checked
  begin
     S := ComponentToString(FCheckComponent);
     Result := Pos('Checked = True', S) > 0;
  end
  else
     Result := True;
end;

function TCheckGroupBox.ComponentToString(Component: TComponent): string;
var
  StrStream: TStringStream;
begin
    StrStream := TStringStream.Create(Result);
    try
      StrStream.WriteComponent(Component);
      StrStream.Position := 0;
      ObjectBinaryToText(StrStream, StrStream);
      StrStream.Position := 0;
      Result := StrStream.DataString;
    finally
      StrStream.Free;
    end;
end;

procedure TCheckGroupBox.CheckComponentOnClick(Sender: TObject);
begin
  Enabled := CheckComponentChecked;
  //Call old event
  if Assigned(FOldCheckComponentOnClick) then
    FOldCheckComponentOnClick(Self);
end;

end.
0
 

Author Comment

by:bnz
ID: 6362187
the width:=width+5 is just to see when the SetCheckComponent is called, it doesn't get called when I cut the component away.
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 21

Expert Comment

by:gemarti
ID: 6362656
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....
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6362676
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 ;-)
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 100 total points
ID: 6362687
a sample

procedure TCheckGroupBox.Notification(AComponent: TComponent; Operation: TOperation);
begin
  If (AComponent = FCheckComponent) and (Operation = opRemove) then
    FCheckComponent := Nil;
end;



 
0
 

Author Comment

by:bnz
ID: 6363181
Yes, very nice... thanks
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

758 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

23 Experts available now in Live!

Get 1:1 Help Now