解决方法
您可以通过以下方式实现:
>使用InnoCallback DLL调度非常频繁的计时器(比如50 ms)
>触发计时器时,找到光标所在的控件并检查更改.
[Files] Source: InnoCallback.dll; Flags: dontcopy [Code] var HoverLabel:TLabel; LastMouse: TPoint; LastHoverControl: TControl; type TTimerProc = procedure(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord); 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 WrapTimerProc(Callback: TTimerProc; ParamCount: Integer): LongWord; external 'wrapcallback@files:innocallback.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(); var HoverTimerCallback: LongWord; begin HoverTimerCallback := WrapTimerProc(@HoverTimerProc,4); SetTimer(0,50,HoverTimerCallback); HoverLabel := TLabel.Create(WizardForm); HoverLabel.Left := ScaleX(8); HoverLabel.Top := WizardForm.ClientHeight - ScaleY(32); HoverLabel.Parent := WizardForm; HoverLabel.Caption := 'starting'; end;