?
Solved

Why my controls don't  offer the onMouseWheel event to be handled ?

Posted on 2003-03-15
4
Medium Priority
?
1,180 Views
Last Modified: 2007-11-27
I need to handle MouseWheel movements over Labels and other controls but the onMouseWheel event is only shown for the Form and not for the controls in my Delphi 7 IDE.
Do I need to handle them in the Form and figure out over witch controls the mouse is each time ?
If the onMouseWheel (and onMouseWheelUp/onMouseWheelDown) event is shown in the hierarchy for the Controls, why is it not shown in their event tabs ?
Thank's for the help !
0
Comment
Question by:dadosutter
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
4 Comments
 
LVL 3

Accepted Solution

by:
BTecho earned 200 total points
ID: 8145643
Hello.

Very simply , yes you can use only the Forms OnMouseWheel events.

To know over which component the mouse is currently hovering above you can use this , but it will not work with TLabels only with TWinControls

Place a TApplicationEvents component on the Form, on the OnMessage events use this snippet:


  if Msg.message:=WM_MOUSEWHEEL then begin

//Just for test you can see how easy is it to then access
//the controls properties by just knowing the component
//handle.

 Edit1.Text := FindControl(Msg.hwnd).Name;
   end;


For Labels and other non TWinControls descandents you have to use this on each of the OnMouseEnter events

MouseOverControl: TControl; //Global Variable

Then assign this code to the components OnMouseEnter events:
MouseOverControl := TControl(Sender);

Then on the Form's OnMouseWheel event:
Edit1.Text := MouseOverControl.Name;

I havent tested the code but it should all work :-)

Also of couse you could've created a descadant for each of the control you needed and each have its own MouseWheel events but the above method seems to be less of a hassle.




0
 

Author Comment

by:dadosutter
ID: 8147952
Thank's BEcho,
   I had figured out these options by the time I got your msg and they work just fine.
   My problem is a bit harder though :(
   The thing is that I have some FRAMES, with several (numeric) labels in each of them. These frames are like independend developed mini-aplications and are integrated in the Main Form in diferent tabs of a Page Control.
   What I'm trying to do is to implement a MouseWheel setting of the label values and I want it to be sufficient just take the mouse cursor over a label and then use the wheel.
   Playing with your suggestions, I found out that a frame will only handle the onMouseWheel events if the focus is in one of it's controls and labels are NOT controls. Even if I use a dummy/hidden control (or other trick to keep the focus there), when the label caption is being altered, the focus is lost again and the onMouseWheel event will only be handled by the Main Form handle (if there's one....).
   I also thought about using a global var to save the label we're over and handle the onMouseWheel in the Main Form but I would loose all the Frame independency and encapsulation.
   I just don't understand why the onMouseWheel event is not available for all the controls (and labels are in the StdControls unit, even if they don't "control" anything) just like any other mouse event (onEnter, onClick, etc..)
   What I need then is a way to handle the onMouseWheel INSIDE A FRAME, treating the problem of the focus getting out of the frame when we update a label's caption.
   Yes, I'm setting a "lMouseCurrentlyOver" on the onEnter event of each label and setting it to nil on the onLeave but when I try to update the label's caption, the focus goes away from the frame and my onMouseWheel handler stops receiving wheelDeltas...

Thank's again you all !
Dado
0
 

Author Comment

by:dadosutter
ID: 8155253
Hello there,
   Following BTecho sugestions, I ended up in a simple and not very ugly (like handling frame onMouseWheel events on it's host Form) solution and I'm pasting it downhere for those who can be interested in.
   Please be free to ask for the source & dfm code if it'll be of any help for you.
   I'll still work on a "Spinnable Control" class that implements the behavior already achieved here. Thank's BTecho for the help and inspiration :)
   The example shows two 4 digit numbers that can have each digit set just moving the mouse cursor over it and spinning the mouse wheel. Please note that it's NOT necessary to click over any label and this function is still free for any other behavior (ex: reseting the digit to zero).
   I still did NOT understand why the onMouseWheel event was not allowed to be treated directly in each control, just like any other mouse event (onClick, on Enter, etc...).

Good programming out there ! :)
Dado

////////////////////////////////////////////////////////////////////////////////
//
// Simple test of the spinnable digits.
// The funcionality of a mouse wheel is used to "spin" the value of digit labels
//
////////////////////////////////////////////////////////////////////////////////
unit TestingOrbitLabels;

interface

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

type
  TOrbitLabels = class(TFrame)
    lbv1d1: TLabel;
    lbv1d4: TLabel;
    lbv1d3: TLabel;
    lbv1d2: TLabel;
    lbv2d1: TLabel;
    lbv2d4: TLabel;
    lbv2d3: TLabel;
    lbv2d2: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label1: TLabel;
    Label2: TLabel;
    lbResult: TLabel;
    procedure MouseEnteraDigit(Sender: TObject);
    procedure MouseLeaveaDigit(Sender: TObject);
    procedure FrameMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);

  private
    { Private declarations }
    lbMouseCurrentlyOver: TLabel;
    procedure RecalcAll;

  public
    { Public declarations }
  end;

implementation


{$R *.dfm}


////////////////////////////////////////////////////////////////////////////////
//
// onMouseEnter event Handler for ALL single digit labels to be WheelSpinned.
//
////////////////////////////////////////////////////////////////////////////////
procedure TOrbitLabels.MouseEnteraDigit(Sender: TObject);
begin
  lbMouseCurrentlyOver := (Sender as TLabel);
  Self.SetFocus;                        // Keep MouseWheel events in the Frame !
end;

////////////////////////////////////////////////////////////////////////////////
//
// onMouseLeave event Handler for ALL single digit labels to be WheelSpinned.
//
////////////////////////////////////////////////////////////////////////////////
procedure TOrbitLabels.MouseLeaveaDigit(Sender: TObject);
begin
  lbMouseCurrentlyOver := nil;
end;


////////////////////////////////////////////////////////////////////////////////
//
// onMouseWheel event handler
//    This routine handles the mouse wheel spinning over ANY of the "spinnable"
// digits. It doesn't care for the final value of each variable, only for the
// digit value and it's kept between 0 and 9.
//    Once the labels do NOT have an onChange event, a general recalculation
// routine is called at the end to update the variables and the redo the calcs.  
//
////////////////////////////////////////////////////////////////////////////////
procedure TOrbitLabels.FrameMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
  iVal: integer;
begin
  if lbMouseCurrentlyOver <> nil then
    begin                                // Inc & Dec digits between 0 & 9
    iVal := StrToInt(lbMouseCurrentlyOver.Caption);

    iVal := iVal + Sign(WheelDelta);
    if iVal > 9 then
      iVal := 0
    else if iVal < 0
      then iVal := 9;

    lbMouseCurrentlyOver.Caption := IntToStr(iVal);
    RecalcAll;
    Handled := True;
    end;

end;


////////////////////////////////////////////////////////////////////////////////
//
// Called each time a "spinnable" digit change it's value.
//    Here is where the validation (range, sign, etc...) of each variable has to
// be done and where the whole calculations take place.
//    Actual code is just a simple example of 2 vars (v1 & v2) and the
// calculation of it's sum.
//
////////////////////////////////////////////////////////////////////////////////
procedure TOrbitLabels.RecalcAll;
var
  i,
  iV1, iV2: integer;
begin
  iV1 := StrToInt(lbv1d1.Caption);
  iV1 := iV1 + StrToInt(lbv1d2.Caption) * 10;
  iV1 := iV1 + StrToInt(lbv1d3.Caption) * 100;
  iV1 := iV1 + StrToInt(lbv1d4.Caption) * 1000;

  iV2 := StrToInt(lbv2d1.Caption);
  iV2 := iV2 + StrToInt(lbv2d2.Caption) * 10;
  iV2 := iV2 + StrToInt(lbv2d3.Caption) * 100;
  iV2 := iV2 + StrToInt(lbv2d4.Caption) * 1000;

  lbResult.Caption := IntToStr(iV1 + iV2);

end;

end.

---------------------------
.DFM Code follows:
---------------------------

object OrbitLabels: TOrbitLabels
  Left = 0
  Top = 0
  Width = 286
  Height = 240
  TabOrder = 0
  OnMouseWheel = FrameMouseWheel
  object lbv1d1: TLabel
    Left = 240
    Top = 24
    Width = 16
    Height = 37
    Caption = '1'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
    OnMouseEnter = MouseEnteraDigit
    OnMouseLeave = MouseLeaveaDigit
  end
  object lbv1d4: TLabel
    Left = 160
    Top = 24
    Width = 18
    Height = 37
    Caption = '4'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
    OnMouseEnter = MouseEnteraDigit
    OnMouseLeave = MouseLeaveaDigit
  end
  object lbv1d3: TLabel
    Left = 188
    Top = 24
    Width = 18
    Height = 37
    Caption = '3'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
    OnMouseEnter = MouseEnteraDigit
    OnMouseLeave = MouseLeaveaDigit
  end
  object lbv1d2: TLabel
    Left = 216
    Top = 24
    Width = 18
    Height = 37
    Caption = '2'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
    OnMouseEnter = MouseEnteraDigit
    OnMouseLeave = MouseLeaveaDigit
  end
  object lbv2d1: TLabel
    Left = 240
    Top = 69
    Width = 16
    Height = 37
    Caption = '1'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
    OnMouseEnter = MouseEnteraDigit
    OnMouseLeave = MouseLeaveaDigit
  end
  object lbv2d4: TLabel
    Left = 160
    Top = 69
    Width = 18
    Height = 37
    Caption = '4'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
    OnMouseEnter = MouseEnteraDigit
    OnMouseLeave = MouseLeaveaDigit
  end
  object lbv2d3: TLabel
    Left = 188
    Top = 69
    Width = 18
    Height = 37
    Caption = '3'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
    OnMouseEnter = MouseEnteraDigit
    OnMouseLeave = MouseLeaveaDigit
  end
  object lbv2d2: TLabel
    Left = 216
    Top = 69
    Width = 18
    Height = 37
    Caption = '2'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
    OnMouseEnter = MouseEnteraDigit
    OnMouseLeave = MouseLeaveaDigit
  end
  object Label9: TLabel
    Left = 24
    Top = 29
    Width = 26
    Height = 24
    Caption = 'V1'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -19
    Font.Name = 'MS Sans Serif'
    Font.Style = [fsBold]
    ParentFont = False
  end
  object Label10: TLabel
    Left = 24
    Top = 74
    Width = 26
    Height = 24
    Caption = 'V2'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -19
    Font.Name = 'MS Sans Serif'
    Font.Style = [fsBold]
    ParentFont = False
  end
  object Label11: TLabel
    Left = 109
    Top = 24
    Width = 20
    Height = 37
    Caption = '='
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
  end
  object Label12: TLabel
    Left = 109
    Top = 69
    Width = 20
    Height = 37
    Caption = '='
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
  end
  object Label1: TLabel
    Left = 24
    Top = 152
    Width = 75
    Height = 24
    Caption = 'V1 + V2'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -19
    Font.Name = 'MS Sans Serif'
    Font.Style = [fsBold]
    ParentFont = False
  end
  object Label2: TLabel
    Left = 109
    Top = 144
    Width = 18
    Height = 37
    Caption = '='
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
  end
  object lbResult: TLabel
    Left = 157
    Top = 144
    Width = 72
    Height = 37
    Caption = '8642'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -35
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
  end
end
0
 

Author Comment

by:dadosutter
ID: 8155263
Thank's for the help !
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Suggested Courses
Course of the Month8 days, 10 hours left to enroll

764 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