Mega Code Archive

 
Categories / Delphi / Graphic
 

TImage And Mouse Wheel Handling OnMouseWheel For The TImage Delphi Control (And Other TGraphicControl Descendants)

Title: TImage And Mouse Wheel - Handling OnMouseWheel For The TImage Delphi Control (And Other TGraphicControl Descendants) 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.