Inno Setup: OnHover event

旧巷老猫 提交于 2019-12-29 08:20:11

问题


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?


回答1:


You can implement it by:

  • scheduling a very frequent timer (say 50 ms)
  • when the timer is triggered, find a control over which the cursor is positioned and check for changes.

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.




回答2:


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;


来源:https://stackoverflow.com/questions/37347427/inno-setup-onhover-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!