Inno Setup:OnHover事件 [英] Inno Setup: OnHover event

查看:167
本文介绍了Inno Setup:OnHover事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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:

  • 安排一个非常频繁的计时器(例如50毫秒)
  • 触发计时器后,找到一个控件,将光标定位在该控件上并检查更改.

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

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;

对于 CreateCallback函数,您需要Inno设置6.如果您对Inno Setup 5感到困惑,可以使用 InnoTools中的WrapCallback函数InnoCallback 库.

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.

在没有计时器的情况下实现此目的的另一种方法是在使用GWL_WNDPROC的处理程序集中处理相关的Windows消息.有关如何设置处理程序的示例,请参见向Inno Setup页面添加上下文菜单 中的WM_CONTEXTMENU处理.

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.

这篇关于Inno Setup:OnHover事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆