Re: Change appearance



On Apr 29, 2:43 pm, "Stark" <franco.jo...@xxxxxx> wrote:
I am creating a few buttons at runtime and I wanted to change appearance of
the button the user is hovering over with the mouse. I don't want to use the
font, which I already use for other purposes. I had the idea to surround the
button with a TBevel, which I could make visible when the mouse was over the
button.
The solution doesn't work. It looks like my code does not apply the property
(visible) to the Bevel, but rather to the Button. Here is my code:

I first create the components at Runtime (in the form OnShow):

  for i := 0 to 10 do
  begin
     aButton := TButton.Create(Self);
     aBevel := TBevel.Create(Self);

     with aButton do
     begin
       Name := Format('Button%d', [i]);
       Parent := Self;
       Left := 16;
       Top := 40 + i*25;
       Width := 145;
       Height := 20;
       Caption := Format('Button %d', [i]);
       OnMouseEnter := AnyBtnMouseEnter;
       OnMouseLeave := AnyBtnMouseLeave;
     end;

     with aBevel do
     begin
       Parent := Self;
       Left := aButton.Left-2;
       Top := aButton.Top-2;
       Width := aButton.Width+4;
       Height := aButton.Height+4;
       Shape:= bsFrame;
       Style:= bsRaised;
       visible:= false;
     end;
  end;

The following procedures fail their mission to show and hide the bevel when
the mouse is over the button: The OnMouseLeave proc makes the button not
visible !
procedure Tform1.AnyBtnMouseEnter(Sender: TObject);
begin
  If Sender is TButton then
     Tbevel(Sender).Visible := true;
end;

procedure Tform1.AnyBtnMouseLeave(Sender: TObject);
begin
  If Sender is TButton then
     Tbevel(Sender).Visible := false;
end;

The Sender will always be the button, so you have to get the bevel for
the particular button. For this we can use the Tag property of a
TComponent (and its descendants). Tag is a four-byte integer value
which can be used to store any four-byte value (ie a DWord). But we
must typecast any non-integer to an integer when we store the value.
And typecast the integer to the type of what we have stored when we
access it.

Then we must trigger "Mouse in button" and "Mouse not on a button"
events. For this you can use the MouseMove button event of the button,
and the MouseMove event of the form. We need only one ButtonMouseMove
event handler because we can use the Sender parameter to get the
particular button, then get its Tag, typecast to a TBevel, and set
Visible to false. ButtonMouseMove is called only when the mouse moves
over the button. It is not called when the mouse is off the button. So
we must use the FormMouseMove to set bevels to not visible, and we do
this for all the bevels,, because we don't know which button the mouse
has just come off. So we check all the entries in the form's
Components array, if it is a TButton, we check the Tag for a value >
0, if so we tyoe-cast it to a Bevel and set the Bevel.Visible to
false. A TComponent has a Tag property so we don't need to typecast
the Components[i] to a TButton.

To prevent a lot of unnecessary messages to set or clear Bevel.Visible
as the mouse moves, we check for the correct Bevel.Visible and only
change it if necessary.

procedure TForm1.FormCreate(Sender: TObject);
begin
{do this for all buttons with a bevel}
Button1.Tag := integer(Bevel1);
Bevel1.Visible := false;
end;

procedure TForm1.ButtonMouseMove(Sender: TObject; Shift: TShiftState;
X,
Y: Integer);
var
BtnBevel : TBevel;
begin
BtnBevel := TBevel(TButton(Sender).Tag);
BtnBevel.Visible := true;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
i : integer;
BtnBevel : TBevel;
begin
for i := 0 to Self.ComponentCount - 1 do
if (Self.Components[i] is TButton) then
if (Components[i].Tag > 0) then begin
BtnBevel := TBevel(Components[i].Tag);
if BtnBevel.Visible then
BtnBevel.Visible := false;
end; {if (Components[i].Tag > 0)}
{end; if (Components[i] is TButton)}
{end; for i := 0 to ComponentsCount - 1}
end;

You must select the ButtonMouseMove event handler yourself in each
button's events list. (after, of course changing the event handler's
name from the auto-entered Button??MouseMove to ButtonMouseMove as it
will be used for all appropriate buttons).

One Problem with using a TBevel is that (on my D3) the bevel width is
fixed. If you used a TPanel you could set the bevel width wider, &
hence more visible.

Storing object references in the Tag property is a powerful tool for
dealing with some issues of identity, or code reduction (ie only one
event handler for a number of controls instead of one for each
control).

Alan Lloyd
.



Relevant Pages

  • Re: Change appearance
    ... to the Bevel, ...   begin ... Firstly when the bevel (or panel) is shown set the form's OnMouseMove, ...
    (comp.lang.pascal.delphi.misc)
  • Re: TButton and Bevel
    ... > TWinControl has the Bevel, ... TButton is a wrapper around the standard Windows button control. ...
    (borland.public.delphi.language.objectpascal)
  • Re: WTB: TAF PF
    ... were issues with black boarders around the switches, ...   the green and some other minor issues. ... I've also been told that Gene is VERY picky about the quality control. ... The bevel is NOT an issue, unless you make it an issue! ...
    (rec.games.pinball)
  • Re: WTB: TAF PF
    ... were issues with black boarders around the switches, ...   the green and some other minor issues. ... The bevel is NOT an issue, unless you make it an issue! ...
    (rec.games.pinball)
  • Re: Black Hole - good replacement motor - $24.95
    ... and power requirements as the original, and all you have to do is bevel ... the wood a bit so it sits flush with the face. ...     ...
    (rec.games.pinball)