Link to home
Start Free TrialLog in
Avatar of SaLz
SaLz

asked on

Hover Over Function

hi, I need a sample/code on how, when you hover your mouse over a button or image or anything it will do something like popup some text, change an image, show a message.

lets say we have 3 Buttons, when I hover over button 1 with my mouse it would change the button caption to Hovered, then when you move your mouse away from button 1 it will change the button 1 caption back to normal, and when you hover over button 2 and 3 it will do the same.

could anyone help?

thanks, Sal.
Avatar of kretzschmar
kretzschmar
Flag of Germany image

Avatar of SaLz
SaLz

ASKER

you know how to do this with out creating a new button? the hover has to be universal, so it can fit onto anything, like tickboxs or anything.

you got any code/samples for that?
in this case you can only use the onmousemove-event,
sample follows

meikl ;-)
the one that posted kretzshmar is universal, because you cna make those properties to every TWinControl type. also if you don't wan't to create new descenats or typecast do them you have to react on mouse position... i think tham mousemove event is good, because we can get what control is at poit tahat mouse points, so if we got some control under mouse cursor, mouse cursor don't moves for periird of time then pop up somethink like hintwindow... hey, you can use your own hint window, with it you can do anything you want!
Avatar of SaLz

ASKER

I was afreid of that, I was hoping that there was another way.
SOLUTION
Avatar of kretzschmar
kretzschmar
Flag of Germany image

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
Just an FYI, The following could cause an exception when used with 3rd party controls.

else if (AControl is TCustomEdit) then
      TEdit(AControl).BorderStyle := bsNone  //of CustomEdit then traet as Edit

Regards,
Rob
why did you think that, rob?
SOLUTION
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
atleast,

the borderstyle is just a protected property of TCustomEdit,
the interface is already there, there is no movement anymore

i know this trick
>type
>  TFriendEdit = class(TCustomEdit);

but atleast above is just a sample

meikl ;-)


Good enough for me :)
SOLUTION
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
Just thought of this:

It would probably be better to add a OnHover event and call that instead of HoverControl.SetText. This way you can do pretty much anything instead of simply showing the control...
I'm wondering...

If we were to write a simple mechanism that can take in any TWinControl as parameter, and in turn, we insert our own OnMouseOver into that control's event chain before calling the real one.

Gimme a moment while I hack one out...
OK, here goes:


unit uHoverHook;

interface

uses
  Classes, Controls;

type
  THookedItem = class
  public
    Control: TControl;
    OldMouseMove: TMouseMoveEvent;
  end;

  THoverHook = class
  private
    FOnMouseMove: TMouseMoveEvent;
    FHookList: TStringList;
    FHookStarted: Boolean;

    function GetHookedItem(AControl: TControl): Integer;
    function GetHookedItemAt(AIndex: Integer): THookedItem;
    function GetHookCount: Integer;
  protected
    property HookedItem[AIndex: Integer]: THookedItem
      read GetHookedItemAt;

    procedure NewMouseMove(Sender: TObject;
      Shift: TShiftState; X, Y: Integer);
  public
    constructor Create; virtual;
    destructor Destroy; override;

    function AddToHook(AObject: TControl): Boolean; virtual;
    function RemoveFromHook(AObject: TControl): Boolean; virtual;

    procedure StartHook; virtual;
    procedure StopHook; virtual;
  published
    property OnMouseMove: TMouseMoveEvent
      read FOnMouseMove write FOnMouseMove;
    property HookCount: Integer
      read GetHookCount;
  end;

implementation

uses
  SysUtils;

type
  TControlHack = class(TControl);

{ THoverHook }

function THoverHook.AddToHook(AObject: TControl): Boolean;
var
  i: Integer;
  NewHookedItem: THookedItem;
begin
  Result := False;
  i := GetHookedItem(AObject);
  if i > -1 then
  // already exists
    Exit;

  NewHookedItem := THookedItem.Create;
  NewHookedItem.Control := AObject;
  NewHookedItem.OldMouseMove := TControlHack(AObject).OnMouseMove;
  TControlHack(AObject).OnMouseMove := NewMouseMove;
  FHookList.AddObject(AObject.Name, NewHookedItem);
  Result := True;
end;

constructor THoverHook.Create;
begin
  inherited;
  FHookList := TStringList.Create;
  FHookStarted := False;
end;

destructor THoverHook.Destroy;
var
  i: Integer;
begin
  for i := FHookList.Count - 1 downto 0 do
  begin
    THookedItem(FHookList.Objects[i]).Free;
    FHookList.Delete(i);
  end;
  FHookList.Free;
  inherited;
end;

function THoverHook.GetHookCount: Integer;
begin
  Result := FHookList.Count;
end;

function THoverHook.GetHookedItem(AControl: TControl): Integer;
var
  i: Integer;
begin
  Result := -1;
  for i := 0 to FHookList.Count - 1 do
    if HookedItem[i].Control = AControl then
    begin
      Result := i;
      Break;
    end;
end;

function THoverHook.GetHookedItemAt(AIndex: Integer): THookedItem;
begin
  Result := THookedItem(FHookList.Objects[AIndex]);
end;

procedure THoverHook.NewMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  i: Integer;
  HookedItem: THookedItem;
begin
  if not Assigned(Sender) then
    Exit;
  if not (Sender is TControl) then
    Exit;

  i := GetHookedItem(Sender as TControl);
  if i = -1 then
    Exit;
  HookedItem := GetHookedItemAt(i);

  if FHookStarted then
    if Assigned(FOnMouseMove) then
      FOnMouseMove(Sender, Shift, X, Y);

  if Assigned(HookedItem.OldMouseMove) then
    HookedItem.OldMouseMove(Sender, Shift, X, Y);
end;

function THoverHook.RemoveFromHook(AObject: TControl): Boolean;
var
  i: Integer;
begin
  i := GetHookedItem(AObject);
  if i = -1 then
    raise Exception.Create('Unable to find control to unhook!');
  THookedItem(FHookList.Objects[i]).Free;
  FHookList.Delete(i);
end;

procedure THoverHook.StartHook;
begin
  FHookStarted := True;
end;

procedure THoverHook.StopHook;
begin
  FHookStarted := False;
end;

end.
SOLUTION
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
the Memo1MouseMove is the event handler for Memo1's OnMouseMove,... to demonstrate that the MouseMove chaining indeed works.

Of course, for more elaborate handling, e.g. specific redrawing upon hover, you can use what meikl used earlier in and replace in the above HoverMouseOver method:

so, instead of drawing text at statusbar, you can do stuff like

procedure TForm1.HoverMouseOver(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if Sender is TEdit then
    DoSomethingForTEdit
  else if Sender is TButton then
    DoSomethingForTButton;
end;

get my point?
Hmmm... nobody seems interested in this topic anymore :-(
Avatar of SaLz

ASKER

DragonSlayer, I've pasted your code in, but I can't get it to work, I've made the uHoverHook.pas and uMain.pas but for some reason, nothing is working on it, could you paste your dfm & code here?

Sal.
My addition: DragonSlayer: post here link to archive with working app+full source. Right SaLz?
The above is already the full code. If you give me your email address, I will send over the whole file (*exactly* the same as above) to your mailbox.



DragonSlayer.
Oh, and the DFM:

object Form1: TForm1
  Left = 192
  Top = 103
  Width = 408
  Height = 230
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 8
    Top = 160
    Width = 32
    Height = 13
    Caption = 'Label1'
  end
  object Button1: TButton
    Left = 16
    Top = 16
    Width = 75
    Height = 25
    Caption = 'Start Hook'
    TabOrder = 0
    OnClick = Button1Click
  end
  object StatusBar1: TStatusBar
    Left = 0
    Top = 184
    Width = 400
    Height = 19
    Panels = <>
    SimplePanel = True
  end
  object Button2: TButton
    Left = 112
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Button2'
    TabOrder = 2
  end
  object Button3: TButton
    Left = 112
    Top = 40
    Width = 75
    Height = 25
    Caption = 'Button3'
    TabOrder = 3
  end
  object Button4: TButton
    Left = 112
    Top = 72
    Width = 75
    Height = 25
    Caption = 'Button4'
    TabOrder = 4
  end
  object Memo1: TMemo
    Left = 200
    Top = 8
    Width = 185
    Height = 89
    Lines.Strings = (
      'Memo1')
    TabOrder = 5
    OnMouseMove = Memo1MouseMove
  end
  object CheckBox1: TCheckBox
    Left = 112
    Top = 112
    Width = 97
    Height = 17
    Caption = 'CheckBox1'
    TabOrder = 6
  end
  object RadioButton1: TRadioButton
    Left = 112
    Top = 136
    Width = 113
    Height = 17
    Caption = 'RadioButton1'
    TabOrder = 7
  end
end
Oh, and by the way, since I only activate the Hover class upon clicking of Button1, you have to click on Button1 first to see the effects :-)
Avatar of SaLz

ASKER

I tryed your Code, The HoverOver works, but the HoverOut doesn't and its only got 1 function area.
ASKER CERTIFIED SOLUTION
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
Avatar of SaLz

ASKER

Eolaz, you did a very good job, you did OnMouseOver,OnMouseOut,OnPushDown,OnClick and it looks so simple and effective.

You've done the question Eolaz, its so simple, but very effective, you used your initiative to come up with an effective way of doing it.

but since, allot of people have tryed and allot more of there time has gone into it, I will have to split the points between you, so you all have a fare share.

someone should talk to Borland about putting a OnMouseOut along side OnMouseMove.

thankyou again Eolas.

Sal.
just wondering about the graded answer

from my point of view, it didn't match the initial q,
nor does it any hovering

just my two cents

meikl ;-)
--> mine does hovering ;-)
i meant eolaz suggestion ;-)
Avatar of SaLz

ASKER

I was looking for a Hoverover and out, like you would find on most applications, web sites, winxp buttons.

Eolaz did do the 4 functions that is needed for a hoverover effect, it may be diffrent and simple, but its effective in its own way, it could get complicated if your adding more hoverover effects.


OnMouseOver,OnMouseOut,OnPushDown,OnClick

When you move your Mouse over the selected image it will change the image.
When you push the image down it would change the image to a pushdown image.
When you move your mouse away from the image, it would change the image back to how it was before you passed your mouse over it.


The Question is still open if you want to add some more.

it would have to be them 4 functions above as in a normal hover over just like a winxp button. it would have to be highly configable for anything from buttons to images, anything.  

I will give anyone 500 more points if you can make a simple hoverover effect that can hold them 4 functions that can be multi used.

Sal.