Is it possible to simulate OnMouseHover
event (to call a function when mouse is over some Inno Setup control) for Inno Setup controls, or is there any DLL library which can help?
You can implement it by:
The following example displays name of the control with cursor over it on a label, like:
[Code]
var
HoverLabel:TLabel;
LastMouse: TPoint;
LastHoverControl: TControl;
function GetCursorPos(var lpPoint: TPoint): BOOL;
external 'GetCursorPos@user32.dll stdcall';
function SetTimer(
hWnd: longword; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord):
LongWord; external 'SetTimer@user32.dll stdcall';
function ScreenToClient(hWnd: HWND; var lpPoint: TPoint): BOOL;
external 'ScreenToClient@user32.dll stdcall';
function ClientToScreen(hWnd: HWND; var lpPoint: TPoint): BOOL;
external 'ClientToScreen@user32.dll stdcall';
function FindControl(Parent: TWinControl; P: TPoint): TControl;
var
Control: TControl;
WinControl: TWinControl;
I: Integer;
P2: TPoint;
begin
// Top-most controls are the last. We want to start with those.
for I := Parent.ControlCount - 1 downto 0 do
begin
Control := Parent.Controls[I];
if Control.Visible and
(Control.Left <= P.X) and (P.X < Control.Left + Control.Width) and
(Control.Top <= P.Y) and (P.Y < Control.Top + Control.Height) then
begin
if Control is TWinControl then
begin
P2 := P;
ClientToScreen(Parent.Handle, P2);
WinControl := TWinControl(Control);
ScreenToClient(WinControl.Handle, P2);
Result := FindControl(WinControl, P2);
if Result <> nil then Exit;
end;
Result := Control;
Exit;
end;
end;
Result := nil;
end;
procedure HoverControlChanged(Control: TControl);
begin
if Control = nil then
begin
HoverLabel.Caption := 'no control';
end
else
begin
HoverLabel.Caption := Control.Name;
end;
end;
procedure HoverTimerProc(
H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
var
P: TPoint;
Control: TControl;
begin
GetCursorPos(P);
if P <> LastMouse then // just optimization
begin
LastMouse := P;
ScreenToClient(WizardForm.Handle, P);
if (P.X < 0) or (P.Y < 0) or
(P.X > WizardForm.ClientWidth) or (P.Y > WizardForm.ClientHeight) then
begin
Control := nil;
end
else
begin
Control := FindControl(WizardForm, P);
end;
if Control <> LastHoverControl then
begin
HoverControlChanged(Control);
LastHoverControl := Control;
end;
end;
end;
procedure InitializeWizard();
begin
SetTimer(0, 0, 50, CreateCallback(@HoverTimerProc));
HoverLabel := TLabel.Create(WizardForm);
HoverLabel.Left := ScaleX(8);
HoverLabel.Top := WizardForm.ClientHeight - ScaleY(32);
HoverLabel.Parent := WizardForm;
HoverLabel.Caption := 'starting';
end;
For CreateCallback
function, you need Inno Setup 6. If you are stuck with Inno Setup 5, you can use WrapCallback
function from InnoTools InnoCallback library.
An alternative way to implement this without a timer is to handle relevant windows messages in a handler set using GWL_WNDPROC
. For an example how to set the handler, see WM_CONTEXTMENU
handling in Adding context menu to Inno Setup page.