Link to home
Start Free TrialLog in
Avatar of kretzschmar
kretzschmarFlag for Germany

asked on

qom #1: Speedbutton Component

hi,

as ex-ex has changed the minimum point assignment to 50 points, it is nevermore comfortable for me to post 25 points qows (even i would more like it to do qows than qom.

qom -> question of the month

qom is a more difficult quest with following rules
- the first working solution gets this 100 pts
- each different working solution gets 50 pts in a seperate q
- top 15 experts are not allowed to participate in this quest, but they may post suggestions/hints
- top 15 experts may post a solution after the q is graded
- sponsoring, each one can sponsor this quest, by supplying the seperate q's for differnet solutions rather than me
- sponsors cannot participate on this quest
- a qom is one week open (on demand also longer)
- a qom starts on the first monday of a new month

well, the question now (is based on a paq from mine)

i need a speedbutton-component,
where i can link a same instance on it

a sample

let say i have 4 such buttons dropped on a form
if i press the third
-button1 going down and fires its onclick event
-button2 going down and fires its onclick event
-button3 going down and fires its onclick event

if i press the second
-button1 going down and fires its onclick event
-button2 going down and fires its onclick event

if i press the fourth
-button1 going down and fires its onclick event
-button2 going down and fires its onclick event
-button3 going down and fires its onclick event
-button4 going down and fires its onclick event


the logic should be implemented in the speedbutton-
component by properties

hope thats clear enough,
just ask if not

have fun

meikl ;-)
Avatar of geobul
geobul

Hi meikl,
Something like (tested with run-time creation only):
-----
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure lbClick1(Sender: TObject);
    procedure lbClick2(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TMySpeedButton = class(TSpeedButton)
  private
    FLinkedButton: TMySpeedButton;
    procedure SetLinkedButton(Value: TMySpeedButton);
    function GetLinkedButton: TMySpeedButton;
  public
    procedure Click; override;
  published
    property LinkedButton: TMySpeedButton read GetLinkedButton write SetLinkedButton default nil;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

// TMySpeedButton

procedure TMySpeedButton.Click;
var
  LinkedButton: TMySpeedButton;
begin
  LinkedButton := GetLinkedButton;
  if LinkedButton <> nil then LinkedButton.Click;
  inherited Click;
end;

procedure TMySpeedButton.SetLinkedButton(Value: TMySpeedButton);
begin
  FLinkedButton := Value;
end;

function TMySpeedButton.GetLinkedButton: TMySpeedButton;
begin
  result := FLinkedButton;
end;

// end of TMySpeedButton

procedure TForm1.lbClick1(Sender: TObject);
begin
  ShowMessage('Button 1');
end;

procedure TForm1.lbClick2(Sender: TObject);
begin
  ShowMessage('Button 2');
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  lb1,lb2: TMySpeedButton;
begin
  // create two buttons
  lb1 := TMySpeedButton.Create(Form1);
  with lb1 do begin
    Parent := Form1;
    Left := 50;
    Top := 20;
    OnClick := lbClick1;
  end;
  lb2 := TMySpeedButton.Create(Form1);
  with lb2 do begin
    Parent := Form1;
    Left := 100;
    Top := 20;
    OnClick := lbClick2;
    LinkedButton := lb1; // First button lb1 is linked to the second one
  end;
end;

end.
-----
Regards, Geo
Avatar of kretzschmar

ASKER

geo, mostly the first ;-)
looks good, testing this evening :-))

well others, come on

meikl ;-)
That was about my implementation already.
I would use the new property here:

procedure TMySpeedButton.Click;
begin
 if Assigned(LinkedButton) then
   LinkedButton.Click;
 inherited Click;
end;

Always use the properties as much as possible
in the implementation. It makes changes much easier.
Good point, Robert. It should be done that way, of course. GetLinkedButton function becomes obsolete then.

Regards, Geo
no one more?

maybe an additional feature?
like
a speedbutton (if it is in flatstyle)
raises a bevel if the mouse enters

now, what about, if i want this for all linked buttons?
(well thats no content of this q)

meikl ;-)
I have explored CM_MOUSEENTER/CM_MOUSELEAVE already.
The qom is too simple even with that.
at least you should show a sample, robert ;-)

too simple->every start should be simple
(i'm open for suggestions)

meikl ;-)
Here is a complete small component. It is not perfect (Picture, PicUp, PicDown are not really clean yet).
The CMHitTest ist the main trick.

unit MouseImage;

interface

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

type
  TOnMouseEvent = procedure(Msg: TWMMouse) of object;

  TMouseImage = class(TImage)
  private
    FOnMouseEnter: TOnMouseEvent;
    FOnMouseLeave: TOnMouseEvent;
    FPicDown: TPicture;
    FPicUp: TPicture;
    FDown: Boolean;
    FEntered: Boolean;
    procedure SetPicDown(Value: TPicture);
    procedure SetPicUp(Value: TPicture);
    procedure SetDown(Value: Boolean);
    procedure SetEntered(Value: Boolean);
  protected
    procedure Loaded; override;
    procedure WMMouseEnter(var Msg: TWMMouse); message CM_MOUSEENTER;
    procedure WMMouseLeave(var Msg: TWMMouse); message CM_MOUSELEAVE;
    procedure CMHitTest(var Msg: TWMMouse); message CM_HITTEST;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Down: Boolean read FDown write SetDown;
    property Entered: Boolean read FEntered write SetEntered;
    property PicDown: TPicture read FPicDown write SetPicDown;
    property PicUp: TPicture read FPicUp write SetPicUp;
    property OnMouseEnter: TOnMouseEvent read FOnMouseEnter write FOnMouseEnter;
    property OnMouseLeave: TOnMouseEvent read FOnMouseLeave write FOnMouseLeave;
  end;

procedure Register;

implementation

{$R *.RES}

(*******************************************************************************)

procedure Register;
begin
  RegisterComponents('3rdParty', [TMouseImage]);
end;

(*******************************************************************************)

constructor TMouseImage.Create;
begin
  inherited;
  FPicDown := TPicture.Create;
  FPicUp   := TPicture.Create;
  FDown    := False;
  FEntered := False;
end;

(*******************************************************************************)

destructor TMouseImage.Destroy;
begin
  FreeAndNil(FPicDown);
  FreeAndNil(FPicUp);
  inherited;
end;

(*******************************************************************************)

procedure TMouseImage.Loaded;
begin
  Picture.Assign(PicUp);
end;

(*******************************************************************************)

procedure TMouseImage.WMMouseEnter(var Msg: TWMMouse);
var
 P: TControl;
begin
  inherited;
  P := Self;
  repeat
    P := P.Parent;
  until (P = nil) or (P is TForm);
  if (P = nil) or TForm(P).Active then
  begin
    Entered := True;
    if Assigned(FOnMouseEnter) then
      FOnMouseEnter(Msg);
  end;
end;

(*******************************************************************************)

procedure TMouseImage.WMMouseLeave(var Msg: TWMMouse);
var
 P: TControl;
begin
  inherited;
  P := Self;
  repeat
    P := P.Parent;
  until (P = nil) or (P is TForm);
  if (P = nil) or TForm(P).Active then
  begin
    Entered := False;
    if Assigned(FOnMouseLeave) then
      FOnMouseLeave(Msg);
  end;
end;

(*******************************************************************************)

procedure TMouseImage.CMHitTest(var Msg: TWMMouse);
begin
  inherited;
  if Assigned(PicUp) and Assigned(PicUp.Bitmap) and Transparent and
    (Msg.XPos < PicUp.Bitmap.Width) and (Msg.YPos < PicUp.Bitmap.Height) and
    (PicUp.Bitmap.Canvas.Pixels[Msg.XPos, Msg.YPos] = (Picture.Bitmap.TransparentColor and $FFFFFF)) then
    Msg.Result := 0;
end;

(*******************************************************************************)

procedure TMouseImage.SetPicUp(Value: TPicture);
begin
  FPicUp.Assign(Value);
end;

(*******************************************************************************)

procedure TMouseImage.SetPicDown(Value: TPicture);
begin
  FPicDown.Assign(Value);
end;

(*******************************************************************************)

procedure TMouseImage.SetDown(Value: Boolean);
begin
  FDown   := Value;
  Entered := Value;
end;

(*******************************************************************************)

procedure TMouseImage.SetEntered(Value: Boolean);
begin
  FEntered := Value;
  if Down or Entered then
    Picture.Assign(PicDown)
  else
    Picture.Assign(PicUp);
end;

end.
well ok, robert, now going back to the question

we've like four linked speedbuttons (flatstyle)

if i move the mouse over the third button a bevel is raised
now i want simultan that button1 and button2 also raises a bevel, like as the mousecursor are over there and of course if i move away the mouse from button3, the bevel disappears, also for button1 and button2

is it clear enough?
(i spend additional 100 pts,
if you or any other are providing a sample about this)

meikl ;-)
too hard, robert (or veryone else)?

:-))
Hello

This is all easy ,its just that I use Borland c++builder(its the closest language to delphi) and would take me  alot of time to convert c++builder code to delphi


well freshman, you are out
->no delphi source sample, no points
:-))

but as all stated it is easy,
it would be nice to see
how it would be implemented
(even with the beveling)

meikl ;-)



Hi,
An additional property LinkedBevel is added. The task could be done without such property simply removing 'and LinkedBevel' from the two mouse message procedures.

Regards, Geo
---
unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   procedure lbClick1(Sender: TObject);
   procedure lbClick2(Sender: TObject);
   procedure lbClick3(Sender: TObject);
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

 TMySpeedButton = class(TSpeedButton)
 private
   FLinkedButton: TMySpeedButton;
   FLinkedBevel: Boolean;
   procedure SetLinkedButton(Value: TMySpeedButton);
 protected
   procedure WMMouseEnter(var Msg: TWMMouse); message CM_MOUSEENTER;
   procedure WMMouseLeave(var Msg: TWMMouse); message CM_MOUSELEAVE;
 public
   procedure Click; override;
 published
   property LinkedButton: TMySpeedButton read FLinkedButton write SetLinkedButton default nil;
   property LinkedBevel: Boolean read FLinkedBevel write FLinkedBevel;
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

// TMySpeedButton

procedure TMySpeedButton.Click;
begin
 if Assigned(LinkedButton) then LinkedButton.Click;
 inherited Click;
end;

procedure TMySpeedButton.SetLinkedButton(Value: TMySpeedButton);
begin
 FLinkedButton := Value;
end;

procedure TMySpeedButton.WMMouseEnter(var Msg: TWMMouse);
begin
  if Assigned(LinkedButton) and LinkedBevel then LinkedButton.WMMouseEnter(Msg);
  inherited;
end;

procedure TMySpeedButton.WMMouseLeave(var Msg: TWMMouse);
begin
  if Assigned(LinkedButton) and LinkedBevel then LinkedButton.WMMouseLeave(Msg);
  inherited;
end;

// end of TMySpeedButton

procedure TForm1.lbClick1(Sender: TObject);
begin
 ShowMessage('Button 1');
end;

procedure TForm1.lbClick2(Sender: TObject);
begin
 ShowMessage('Button 2');
end;

procedure TForm1.lbClick3(Sender: TObject);
begin
 ShowMessage('Button 3');
end;

procedure TForm1.FormCreate(Sender: TObject);
var
 lb1,lb2,lb3: TMySpeedButton;
begin
 // create three buttons
 lb1 := TMySpeedButton.Create(Form1);
 with lb1 do begin
   Parent := Form1;
   Left := 50;
   Top := 20;
   Flat := true;
   Caption := '1';
   OnClick := lbClick1;
   LinkedBevel := true;
 end;
 lb2 := TMySpeedButton.Create(Form1);
 with lb2 do begin
   Parent := Form1;
   Left := 100;
   Top := 20;
   Flat := true;
   Caption := '2';
   OnClick := lbClick2;
   LinkedBevel := true;
   LinkedButton := lb1; // First button lb1 is linked to the second one
 end;
 lb3 := TMySpeedButton.Create(Form1);
 with lb3 do begin
   Parent := Form1;
   Left := 150;
   Top := 20;
   Flat := true;
   Caption := '3';
   OnClick := lbClick3;
   LinkedBevel := true;
   LinkedButton := lb2; // First button lb1 is linked to the second one
 end;
end;

end.
Hello!

the Tspeedbutton component has a Flat property,so if put this property to true and go over with the mouse the bevel will raise



geo, looks good

freshman, reread the question

let say i have for buttons
if i click on the third button, i will have
button1-onclick-event fired
button2-onclick-event fired
button3-onclick-event fired

(initial question)

if i move with the mouse on the third button i will have
button1-bevel raised
button2-bevel raised
button3-bevel raised
(addon question)

well, this should also work,
if i leave the third-button->all bevels should disappear

and this all handled in one component,
derived from tspeedbutton

easy enough?

meikl ;-)
let say i have for buttons
should be
let say i have four buttons
Sometimes i have to work ;-)
hi all,
hi meikl ;-)

following this QOM....

Good question, good idea about control's behaviour. I have an idea how this component can be used in real application. Something like selector of cumulative parameters settings.

>> - sponsoring, each one can sponsor this quest,
>> by supplying the seperate q's for differnet solutions rather than me

meikl, let me know if you are going to grade additional points for somebody.

-------
Igor

PS: it seems too easy, or you keep underwater rock? :-)


hi igor,
i let you know about sponsoring next week.

about my eMail-account you asked in another q,
its the same as provided in my profile.

to robert,
of course your work is more important
than this q.

meikl ;-)

Hello all!

Here is what I done so far:
bevel raises when you go over with mouse and more..

Here is how its going to work,there will be a property where you type all the speed buttons you want this button to control  

I already making it as a component :-)
oh and I frogot to say the code is in delphi,But I develop with c++builder becuase it can compile c++ and delphi code ,but my main(the one I know best) language is c++ but I know delphi to ;-)
thats ok freshman,
don't hurry, you've time until next monday,
or on demand longer

yes, it should be a component,
but written with delphi source,
how you implement the component doesn't matter,
if u use a container or a collection or just
a derivement from tspeedbutton or any other

you are free with this, but at least there should be buttons with the bahaviour on a click-event as described
above (intial q)

and the beveling feature
(addon q, not a must, but gets additional 100 pts, for the first and 50 pts for each different solution)

don't forget to post the source, freshman

to all, good news,
after kpro did not properly work and my question points are not rounded up to 500, the moderator comTech pushed my question-points up to 5000, so that i'm able to grade each solution.

about sponsoring,
during finishing this thread next week,
i will post a list, who becomes how much pts in additional for ... q's. sponsors may pick up one or more from the list
and leave a comment which one was taken.
sponsors will then grade the taken expert(s)
with sponsors own q-points.

so far about sponsoring oragnisation

just a last word,
the component should be stable and recognize
run/designtime freed objects, which may linked to it

hint: notification-method

happy coding

meikl ;-)
Hello!

I'am still working on it :-)
I think I will finish in about 30mins, so ill send you the exe sample to your email when I finish ,so you see how it works
well, freshman,
you can send it to me
at my mailadress shown in my profile
(just click on my name)

but you have to post the source
in this thread for getting points,
just because its a knowledge-sharing community
and others than me may also interested on your solution

meikl ;-)
HI, Meikl,
Here is my code:

unit PSISpeedButton;

{--------------------------------------------------------------------------}
{--------------------------------------------------------------------------}
INTERFACE
{--------------------------------------------------------------------------}
{--------------------------------------------------------------------------}

uses
  Windows, Messages, SysUtils, Classes, Controls, Buttons, Dialogs;

type
  TPSISpeedButton = class(TSpeedButton)
  private
   FSB: TSpeedButton;
    procedure SetSB(const Value: TSpeedButton);
    { Private declarations }
  protected
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
    { Protected declarations }
  public
    procedure Click; override;
    function CheckOutTheChain(const Value: TSpeedButton): boolean;
    { Public declarations }
  published
   property SB : TSpeedButton read  FSB
                              write SetSB;
    { Published declarations }
  end;

procedure Register;

{--------------------------------------------------------------------------}
{--------------------------------------------------------------------------}
IMPLEMENTATION
{--------------------------------------------------------------------------}
{--------------------------------------------------------------------------}

{--------------------------------------------------------------------------}
procedure Register;
begin
  RegisterComponents('Samples', [TPSISpeedButton]);
end;
{--------------------------------------------------------------------------}
{ TPSISpeedButton }
{--------------------------------------------------------------------------}
function TPSISpeedButton.CheckOutTheChain(const Value: TSpeedButton): boolean;
var psisb: TSpeedButton;
begin
 Result:=True;
//
 if ((Value=NIL) or not (Value is TPSISpeedButton))
  then EXIT;
//
 psisb:=Value;
//
  while ((psisb<>NIL) and (psisb is TPSISpeedButton)) do
   begin
     if psisb=Self
      then
       begin
         Result:=False;
         BREAK;
       end;
//
    psisb:=TPSISpeedButton(psisb).SB;
   end;
end;
{--------------------------------------------------------------------------}
procedure TPSISpeedButton.Click;
begin
 if FSB<>NIL
  then FSB.Click;
//
  INHERITED Click;
end;
{--------------------------------------------------------------------------}
procedure TPSISpeedButton.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  INHERITED Notification(AComponent, Operation);
//
  if Operation=opRemove then
    if AComponent=FSB then FSB:=NIL;
end;
{--------------------------------------------------------------------------}
procedure TPSISpeedButton.SetSB(const Value: TSpeedButton);
begin
  if CheckOutTheChain(Value)
   then FSB:=Value
   else ShowMessage('You are not allowed to !');
end;
{--------------------------------------------------------------------------}
{--------------------------------------------------------------------------}
END.
Sincerely,
Nestorua.
I think I will finish in about 30mins, so ill send you the exe sample to your email when I finish ,so you see how it works
a long half hour, freshman :-))

well nestorua, checking this weekend

meikl ;-)
Hello!

I have little problems ,maybe i'll finish today
no problem, freshman, take your time
hi meikl,

you'v got  a lot of points :-) Seems now it is possible to continue QOW (Quest Of Week)?

----
Igor.
yep,

thought also about of this,
with the same conditions as in this qom (100+50).
(sponsoring may required in this case in some months)

meikl ;-)
Hello!

meikl ,I'am almost finished, i'll finish today or tommorow for sure ;-)
Hello!

It's complete and  
Here are things that are done:

1)you can link unlimited number of SpeedButtons together
2)Bevel raises on all buttons when go over with mouse
2)Bevel disappears on all buttons when leave button with mouse
3)OnClick event triggered on all buttons when click on button

meikl, I will send sample exe so you can see :-)
well, freshman,
exact what is wanted :-))

now you have only to post your source here
(even if it is written in c, exeptionally)

meikl ;-)
Hello meikl ,did you try the sample?
Hello!

meikl ,as I said before I wrote it in delphi as a component :-)

Ok,I'll post the full source(2 pas files) here so can you paste the code into pas file and install it instantly
freshman, missung already your source here ;-)
ASKER CERTIFIED SOLUTION
Avatar of freshman3k
freshman3k

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Please do not claim this as your own source and do not post it anywhere!
>Please do not claim this as your own source and do not
>post it anywhere!

is ok, freshman

starting now evaluting,
results and gradinglist comes tomorrow

meikl ;-)
meikl , Should I tell how to use the component? :-)
would be nice, freshman,
then it would be not to hard for me
to evaluate,
but in your case i have the exe and
i trust you that your exe is based on your source,
so that it is not a must for you to explain it for me
but others may know this

in some hours,
the results are posted
(first i must be a little bit for my family,
because i'm a short time at home todays evening)

meikl ;-)
>i trust you that your exe is based on your source
yes, exe I gave you is already using the component

>first i must be a little bit for my family,because i'm a
>short time at home todays evening
of course,after all your family is far more important then this q

>i trust you that your exe is based on your source
yes, exe I gave you is already using the component

>first i must be a little bit for my family,because i'm a
>short time at home todays evening
of course,after all your family is far more important then this q

Here is how to use the component.

for example I have four of these buttons placed on the form and I want that all of these buttons to control each other, I would set there linkwith property as follows:

SuperSpeedBtn1's linkwith property would be:
SuperSpeedBtn2
SuperSpeedBtn3
SuperSpeedBtn4


SuperSpeedBtn2's linkwith property would be:
SuperSpeedBtn1
SuperSpeedBtn3
SuperSpeedBtn4


SuperSpeedBtn3's linkwith property would be:
SuperSpeedBtn1
SuperSpeedBtn2
SuperSpeedBtn4


SuperSpeedBtn4's linkwith property would be:
SuperSpeedBtn1
SuperSpeedBtn2
SuperSpeedBtn3

Hope thats clear enought

P.S: if you want ,I can change the component so you dont have to type into each button separately but instead type everything into just one button
the results

geobul:
100 pts for first on basic question
100 pts for first addon question
(i will raise this q up to 200 and grade you, geo)

robert:
failed the goal of this question,
but for providing an interest component,
which shows how to handle messages for the addon q
50 pts in a separat question

nestorua:
50 pts for solving basic question (but not first)
25 pts for qow17, which i have not gave you yet

freshmen:
50 pts for solving basic question (but not first)
50 pts for solving addon question (but not first)
50 pts for best implementation (bonus)

summary:
geobul : 200 pts with this q
robert : 50 pts in a separate q
nestorua : 75 pts in a separate q
freshmen : 150 pts in a separate q

if all agree, then i will close this thread in two days
from now, otherwise just tell me

sponsors may pick within this two days one or more
experts, which are get its points in a separate q

freshmen,
>meikl , Should I tell how to use the component? :-)
yes

meikl ;-)
meikl,

No offense but all of Geobul's solutions are hard coded so you cannot link multiple buttons together and that dosent answer the basic question and addon question


>freshmen,
>>meikl , Should I tell how to use the component? :-)
>yes

I already posted how to use the component in my last post


meikl,

No offense but all of Geobul's solutions are hard coded so you cannot link multiple buttons together and that dosent answer the basic question and addon question


>freshmen,
>>meikl , Should I tell how to use the component? :-)
>yes

I already posted how to use the component in my last post


:-))
sorry, freshman, as i wrote my last comment,
i didn't saw your last comment ;-)

about geobuls solution,
i guessed it would be not too hard
to extract the TMySpeedButton-Class parts
into a unit and add a register-procedure,
but well, your criticism is correct

to all,
suggestions welcome

meikl ;-)
meikl,

Here is what I think about Geobul's solutions:

1)hard coded so you cannot link multiple buttons together.
and this by itself automatically dosent answer the basic question and the addon question

2)
>if i press the third
>-button1 going down and fires its onclick event
>-button2 going down and fires its onclick event
>-button3 going down and fires its onclick event....

As you asked as an addon question the button to go down ,Geobul's solution doesnt make the button go down,
and this itself dosent answer the addon question either

and Here is what I think about nestorua's solutions:
1)same as Geobul's

and Here is what I think about robert's solutions:
1)robert failed the goal of this question

P.S: to everyone: No hard fellings,I'am just being fair
:-)
waiting for comments from the others participants

the grading discussion is opened

to 1.
as stated

i guessed it would be not too hard
to extract the TMySpeedButton-Class parts
into a unit and add a register-procedure

like

unit MySpeedButton;
uses someunits;

type
TMySpeedButton = class(TSpeedButton)
private
  FLinkedButton: TMySpeedButton;
  FLinkedBevel: Boolean;
  procedure SetLinkedButton(Value: TMySpeedButton);
protected
  procedure WMMouseEnter(var Msg: TWMMouse); message CM_MOUSEENTER;
  procedure WMMouseLeave(var Msg: TWMMouse); message CM_MOUSELEAVE;
public
  procedure Click; override;
published
  property LinkedButton: TMySpeedButton read FLinkedButton write SetLinkedButton default nil;
  property LinkedBevel: Boolean read FLinkedBevel write FLinkedBevel;
end;

procedure register;

implementation

{$R *.DFM}

// TMySpeedButton

RegisterComponents ('Samples',[TMySpeedButton]);



procedure TMySpeedButton.Click;
begin
if Assigned(LinkedButton) then LinkedButton.Click;
inherited Click;
end;

procedure TMySpeedButton.SetLinkedButton(Value: TMySpeedButton);
begin
FLinkedButton := Value;
end;

procedure TMySpeedButton.WMMouseEnter(var Msg: TWMMouse);
begin
 if Assigned(LinkedButton) and LinkedBevel then LinkedButton.WMMouseEnter(Msg);
 inherited;
end;

procedure TMySpeedButton.WMMouseLeave(var Msg: TWMMouse);
begin
 if Assigned(LinkedButton) and LinkedBevel then LinkedButton.WMMouseLeave(Msg);
 inherited;
end;

end.

now you've a component, where you can link at designtime
buttons with the same class

to 2.
good point, missed this myself
(sometimes i should reread my own questions) :-))

to 3(1). nestoruas is near exact to geobuls, but provides the notification-procedure and implements a check for avoiding circular links

to 4(1). as stated robert failed the goal

well,
what is the meaning of the others,
as freshman is correct about his objectives as it is

geo solves the question not in all cases
robert failed
nestorua just "expands" geos solution
freshman matches the question exact and a bit more

freshman,
how should the gradings shown,
from your point of view?

meikl ;-)
hello meikl,

>freshman,
>how should the gradings shown,
>from your point of view?

Here is what I think,

geobul:
almost solved the basic question(but not all the way) : 85
almost solved the addon question(but not all the way) : 65

nestorua:
almost solved the basic question(but not all the way) : 85

robert : failed the goal of this question and.... = 30

Conclusion,

geobul: 150
nestorua: 85
robert: 30
well,
your suggestion seems to be ok for me,
except for geobul 2x 75 pts (was both first, but results is the same)
except for nestorua (was not first) i would give 45 pts,
what about yourself,
atleast you solved all,
i would keep the 150 pts grade for you, freshman

after discussion following gradings

geobul 150
nestorua 45 +(25 from qow17) = 70
robert 30
freshman 150 (or 200 for complete genius solution?)

others, what's your meaning

meikl ;-)
Hi,
>1)hard coded so you cannot link multiple buttons together.

Yes, you can. You build a chain of linked buttons. Btn2 controls Btn1. Btn3 controls Btn2 and that way controls Btn1 indirectly.

>and this by itself automatically dosent answer the basic question and the addon question

I don't understand.

>2)

I agree. Linked buttons don't go down.

>almost solved the addon question(but not all the way) : 65

I can't agree. The addon question was about bevels (mouse over/leave) not about pressing the buttons.

And finally: freshman's component is not derived from TSpeedButton.

Regards, Geo
Meikl,
>geobul 150
is correct (and sounds well :-)

Regards, Geo
Hello geobul,

>Yes, you can. You build a chain of linked buttons. Btn2 >controls Btn1. Btn3 controls Btn2 and that way
>controls Btn1 indirectly.

How about, if you have 4 of these buttons on the form and want them to function as follows:

if i press Button1,
button1 fires its onclick event
button2 fires its onclick event
button3 fires its onclick event
button4 fires its onclick event

if i press Button2,
button1 fires its onclick event
button2 fires its onclick event
button3 fires its onclick event
button4 fires its onclick event

if i press Button3,
button1 fires its onclick event
button2 fires its onclick event
button3 fires its onclick event
button4 fires its onclick event

if i press Button4,
button1 fires its onclick event
button2 fires its onclick event
button3 fires its onclick event
button4 fires its onclick event

Can your button do that ? :)
Sorry geobul, I made a mistake in my previous post

Here is the corrected one:

How about, if you have 4 of these buttons on the form and want them to function as follows:

if i press Button1,
button1 fires its onclick event
button2 fires its onclick event
button3 fires its onclick event

if i press Button2,
button1 fires its onclick event
button2 fires its onclick event

if i press Button3,
button1 fires its onclick event
button2 fires its onclick event
button3 fires its onclick event

if i press Button4,
button1 fires its onclick event
button2 fires its onclick event
button4 fires its onclick event

geobul,Can your button do that ? :)

freshman,
that was not part of this q,
only the "previous" linked button(s)
and the clicked should fire

i know, that your component
can assign different
combinations for each button
(thats why the bonus)

nestorua, robert,
your agreements or objectives are needed

meikl ;-)
HI, Meikl,
I agree. Thanks.
Sincerely,
Nestorua.
Meikl, Whatever you say, I will agree ;-)
well, if robert will not comment anything, then
the gradings would be

geobul 150 pts
robert 30 pts
nestorua 70 pts
freshman 150 pts

i will geobul grade with this q,
others get the points in separate for... qs

sponsors may have 24 hours from now for picking
one or more experts for grading from the sponsor's
points-account.

after 24 for hours i will grade the rest or all, if no sponsor found

meikl ;-)
Thanks alot, meikl :-)
hi meikl,
oww, long thread....

I will grade geobul

-----
Igor
well, ok,
igor and thanks for sponsoring,

then i will grade freshman
with this q this evening,
and the rest with separat questions

meikl ;-)
meikl, whats next?
the grading of course, freshman
(sorry that i'm late for this) ;-)

nestorua go
https://www.experts-exchange.com/questions/20312100/for-nestorua-qom-1-and-qow-17.html 
to collect your points

robert go
https://www.experts-exchange.com/questions/20312101/for-richard-marquardt-qom-1.html 
to collect your points

thanks to all for participating on this quest,
specially to sponsor igor :-)

meikl ;-)