Inno Setup:OnHover事件 [英] Inno Setup: OnHover event
问题描述
是否可以为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屋!