Re: Change appearance
- From: "alanglloyd@xxxxxxx" <alanglloyd@xxxxxxx>
- Date: Wed, 2 May 2012 14:29:48 -0700 (PDT)
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
.
- Next by Date: Re: Change appearance
- Next by thread: Re: Change appearance
- Index(es):
Relevant Pages
|