Reputation: 379
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?
Upvotes: 1
Views: 1262
Reputation: 202642
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 '[email protected] stdcall';
function SetTimer(
hWnd: longword; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord):
LongWord; external '[email protected] stdcall';
function ScreenToClient(hWnd: HWND; var lpPoint: TPoint): BOOL;
external '[email protected] stdcall';
function ClientToScreen(hWnd: HWND; var lpPoint: TPoint): BOOL;
external '[email protected] 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.
Upvotes: 3
Reputation: 73
The following code is from the documentation of Inno Unicode Enhanced Ver. As you can see the OnMouseEnter & OnMouseLeave functions, you can use them to implement your OnHover function.
TButton = class(TButtonControl)
procedure Click;
property OnMouseEnter: TNotifyEvent; read write;
property OnMouseLeave: TNotifyEvent; read write;
end;
Upvotes: 0