Inno Setup OnHover 事件

问题描述 投票:0回答:2

是否可以为 Inno Setup 控件模拟

OnMouseHover
事件(当鼠标悬停在某些 Inno Setup 控件上时调用函数),或者是否有任何 DLL 库可以提供帮助?

inno-setup pascalscript
2个回答
3
投票

您可以通过以下方式实现:

  • 安排一个非常频繁的计时器(比如 50 毫秒)
  • 当计时器被触发时,找到光标所在的控件并检查是否有变化。

以下示例显示控件的名称,并将光标悬停在标签上,例如:

enter image description here

[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;

对于

CreateCallback
函数,您需要 Inno Setup 6。如果您无法使用 Inno Setup 5,您可以使用
InnoTools InnoCallback
库中的 WrapCallback 函数。


在没有计时器的情况下实现此目的的另一种方法是使用

GWL_WNDPROC
在处理程序集中处理相关的窗口消息。有关如何设置处理程序的示例,请参阅
向 Inno Setup 页面添加上下文菜单
中的WM_CONTEXTMENU
处理。


0
投票

以下代码来自Inno Unicode增强版的文档。正如您所看到的 OnMouseEnter 和 OnMouseLeave 函数,您可以使用它们来实现 OnHover 函数。

  TButton = class(TButtonControl)
    procedure Click;
    property OnMouseEnter: TNotifyEvent; read write;
    property OnMouseLeave: TNotifyEvent; read write;
  end;
© www.soinside.com 2019 - 2024. All rights reserved.