Solved

Making a component with other components

Posted on 2002-04-16
5
307 Views
Last Modified: 2010-04-04
This question is a simplified version of what I'm actually trying to do in real life.  I will give these points to the person who helps me build the following component.  Once this is built successfully, I will know what to do to solve the real problem I have at hand.

I want to make a component called TRadioAndCombo.  It has two components: a radio button and a combo box.  When the radio button is selected, I want the combo box to be enabled.  When it is not selected, the combo box should be disabled and ItemIndex should revert back to -1.  TRadioAndCombo will also have some new properties which I will write which are independent of the child components.

At design-time, I do not want to allow the application developer to directly manipulate the radio button and combo box.  For instance, I do not want them to be able to reposition them within the TRadioAndCombo border; plus I don't want them to be able to enable and disable each component independently.

When the programmer uses TRadioAndCombo at design-time, he/she should have access to an Items property, which is merely a wrapper for the Combo's Items property.  The ItemIndex property will simply read and return the value of ItemIndex from the combo.  TRadioAndCombo.Caption should read and write to the radio button caption.  The Tag property will not read either Tag property of the radio button or combo box, but will simply be a tag for TRadioAndCombo.  Do you see where I'm going?  The new component will expose some key properties of the components that it contains, but not ALL of those properties.

As you can see, I can't inherit from TRadioButton or TComboBox because I want the functionality of both objects.  Plus, I want to hide stuff about them.  An event in TRadioButton must manipulate the ComboBox object, as described above.  I have tried using a TFrame to do all this, but that doesn't work for me since the developer has access to the two inside components.  Plus, the properties I added to the frame were not visible in the Object Inspector, even though they were published simple types.  I also seemed to have lost the radio button event handler that I wrote in the frame's unit.

When a user forward-tabs into my component, I want the radio button to have focus.  If the combo box is enabled, then another forward-tab will move the focus to the combo box.  If the user backward-tabs into my component, then focus will go to the combo box if it is enabled, and to the radio button otherwise.  TRadioAndCombo will not appear to the user as ever having focus.  The user will see the two components and just know that they work together.

I feel sure that TRadioAndCombo will have to inherit from TCustomComponent, TWinControl, or something basic like that.  Maybe it will be a TGroupBox; I don't know.  If I must design the component programmatically, then so be it, as long as it's easy for someone like me who's not quite comfortable with concepts like painting and low-level Windows messaging.  I don't think I'll have the option to design the component visually.

So, EE experts, how do I get this thing to work? :)
0
Comment
Question by:Pummel
  • 3
5 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6945112
hi pummel(chen) :-)),

you have to write two wrapper-classes
(for the combo and the radio),
(maybe it works also with one)
which inherited from tpersistent,
where you passthrough the properties you want

as base-class, which does the both controls
bundles, you could use a twincontrol

just as kick off

meikl ;-)

0
 
LVL 1

Expert Comment

by:Alone
ID: 6945123
Try to inherit it from TCustomGroup box or TCustomPanel. When I've solved similar problem I've used TCustomPanel descedant
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 300 total points
ID: 6945154
an older sample,
just for showing, what i meant

a panel which holds a speedbutton

unit SBPanel;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, Buttons;

type
  TSBPanelBtn = class(TSpeedButton)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    Procedure Click; OverRide;
  published
    { Published declarations }
  end;

  TButtonProperties = class(TPersistent)
  private
    fButton : TSpeedButton;
  protected
    function  GetCaption : TCaption;
    procedure SetCaption(ACaption : TCaption);
    function  GetFlat : Boolean;
    procedure SetFlat(ABoolean : Boolean);
    function  GetGlyph : TBitmap;
    procedure SetGlyph(ABitmap : TBitmap);
  public
    constructor Create(AButton : TSpeedButton); OverLoad;
  published
    property Caption : TCaption read GetCaption write SetCaption;
    property Flat : Boolean read GetFlat write SetFlat;
    property Glyph : TBitmap read GetGlyph write SetGlyph;
  end;


  TSBPanel = class(TPanel)
  private
    fSBPanelBtn : TSBPanelBtn;
    fButtonProperties : TButtonProperties;
  protected
    function  GetOnButtonClick : TNotifyEvent;
    procedure SetOnButtonClick(AEvent : TNotifyEvent);
  public
    constructor Create(AOwner : TComponent); OverRide;
    destructor destroy; OverRide;
  published
    property ButtonProperties : TButtonProperties read fButtonProperties write fButtonProperties;
    property OnButtonClick : TNotifyEvent read GetOnButtonClick write SetOnButtonClick;
  end;

procedure Register;

implementation


//Button
procedure TSBPanelBtn.Click;
begin
  inherited Click;
  if (assigned(Parent)) and
     (parent is TSBPanel) then
    TSBPanel(parent).Click;
end;

//ButtonProperties (make it visible and storeable to the Objectinspector)
constructor TButtonProperties.Create(AButton : TSpeedButton);
begin
  inherited Create;
  if assigned(AButton) then
    fButton := AButton;
end;

function  TButtonProperties.GetCaption : TCaption;
begin
  result := '';
  if assigned(fButton) then
    result := fButton.Caption;
end;

procedure TButtonProperties.SetCaption(ACaption : TCaption);
begin
  if assigned(fButton) then
    fButton.Caption := ACaption;
end;

function  TButtonProperties.GetFlat : Boolean;
begin
  result := false;
  if assigned(fButton) then
    result := fButton.Flat;
end;

procedure TButtonProperties.SetFlat(ABoolean : Boolean);
begin
  if assigned(fButton) then
    fButton.Flat := ABoolean;
end;

function  TButtonProperties.GetGlyph : TBitmap;
begin
  result := nil;
  if assigned(fButton) then
    result := fButton.Glyph;
end;

procedure TButtonProperties.SetGlyph(ABitmap : TBitmap);
begin
  if assigned(fButton) then
    fButton.Glyph := ABitmap;
end;


//The Panel
constructor TSBPanel.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  Caption := '';
  fSBPanelBtn := TSBPanelBtn.Create(Self);
  fSBPanelBtn.Parent := self;
  fSBPanelBtn.Align := alClient;
  fButtonProperties := TButtonProperties.Create(fSBPanelBtn);
end;

destructor TSBPanel.destroy;
begin
  fButtonProperties.free;
  inherited destroy;
end;


function  TSBPanel.GetOnButtonClick : TNotifyEvent;
begin
  result := nil;
  if assigned(fSBPanelBtn) then
    result := fSBPanelBtn.OnClick;
end;

procedure TSBPanel.SetOnButtonClick(AEvent : TNotifyEvent);
begin
  if assigned(fSBPanelBtn) then
    fSBPanelBtn.OnClick := AEvent;
end;


procedure Register;
begin
  RegisterComponents('Samples', [TSBPanel]);
end;

end.

meikl ;-)
0
 

Author Comment

by:Pummel
ID: 6945322
That should do it.  Thank you.  Code always serves as a good teacher to me--more than just words and definitions.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6945353
>Code always serves as a good teacher to me
>--more than just words and definitions.

to me too :-)

thanks for points,
hope you get it work as you recommended,
if you've problems just ask in this thread,
and i will try to help you further

meikl ;-)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
searching for DavidI's "Mobile Summer School download" 3 128
Making delphi communicate with a c# service 16 91
How to debug For loops? 3 46
Multiple image collision 13 69
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
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 Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Both in life and business – not all partnerships are created equal. As the demand for cloud services increases, so do the number of self-proclaimed cloud partners. Asking the right questions up front in the partnership, will enable both parties …

863 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

19 Experts available now in Live!

Get 1:1 Help Now