1. Technology

Handling Mouse Wheel Messages For The TImage Delphi Control

Add Mouse Wheel Processing For TControl Descendants

By

TGraphicControl descendant controls do not receive mouse wheel messages in Delphi. TImage is one such control. Here's how to expose the OnMouseWheel event handler for the TImage Delphi control. What's more: how to handle mouse wheel messages for any TControl descendant.

When the mouse wheel is rotated the OnMouseWheel event will be fired for TControl descendants. If there is no OnMouseWheel event handler, or if the mouse wheel message is not handled in the OnMouseWheel event handler, then an OnMouseWheelUp or OnMouseWheelDown event occurs, depending on the direction the mouse wheel was rotated.

In one of my recent projects, I had a need to handle mouse wheel for a TImage control. Was displaying pages of a PDF document (using Quick PDF Library) and wanted to move to the next / previous page when the user rotates the mouse wheel. Since TImage does not expose mouse wheel message, had to find a solution.

OnMouseWheel for TImage

There are two steps in exposing the OnMouseWheel event (and OnMouseWheelUp, OnMouseWheelDown) for a Timage control. Firstly, using the protected hack you access the OnMouseWheel event. Secondly, you grab the mouse wheel action from the form and send the message to the control under the mouse.

When you scroll the mouse wheel, Windows sends the message to the currently active/focused window. The message is then sent up the parent chain until it reaches the form.

The TForm will be the first control to have the ability to handle mouse wheel actions (before any child controls can react in their OnMouseWheel event handlers).

Therefore, to have TGraphicControl descendants handle mouse wheel messages, grab mouse wheel message in Form's OnMouseWheel event handler then pass it on to the TControl under the mouse.

Here's the code:

type
  TImage = class(ExtCtrls.TImage);

  TImageForm = class(TForm)
    Image1: TImage;
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    procedure ImageMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  ImageForm: TImageForm;

implementation
{$R *.dfm}

procedure TImageForm.FormCreate(Sender: TObject);
begin
  Image1.OnMouseWheel := ImageMouseWheel;
end;

//handles Form OnMouseWheel
procedure TImageForm.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
const
  {$J+}
  performing : boolean = false;
  {$J-}
var
  ctrl : TControl;
  wc : TWinControl;
begin
  Handled := false;

  if NOT performing then
  begin
    wc := FindVCLWindow(MousePos);
    if Assigned(wc) then
    begin
      ctrl := wc.ControlAtPos(wc.ScreenToClient((MousePos)), false, false);
      if Assigned(ctrl) then
      begin
        performing := true;
        try
          ctrl.Perform(CM_MOUSEWHEEL, WheelDelta, MakeLParam(MousePos.X, MousePos.Y));
        finally
          performing := false;
        end;
        Handled := true;
      end;
    end;
  end;
end;

//handles Image OnMouseWheel
procedure TImageForm.ImageMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
  //handle Image1 OnMouseWheel here
  Caption := IntToStr(WheelDelta);
end;
The above is the code in the TImageForm unit hosting one TImage control (named "Image1").

The

TImage = class(ExtCtrls.TImage);
is a protected hack to be able to get to the OnMouseWheel event handler for Image1.

Using form's OnCreate event you assign the event handing procedure for Image1's OnMouseWheel event.

Finally, in the OnMouseWheel event handler for the form, the mouse wheel message is passed to any TControl under the mouse when the form catches the mouse wheel rotation.

Delphi tips navigator:
» MSXML 6 Prohibit DTD
« Is Some (Delphi) TControl Under the Mouse?

  1. About.com
  2. Technology
  3. Delphi
  4. Coding Delphi Applications
  5. Delphi Tips and Tricks
  6. Delphi Tips 2010
  7. TImage And Mouse Wheel - Handling OnMouseWheel For The TImage Delphi Control (And Other TGraphicControl Descendants)

©2014 About.com. All rights reserved.