inno-setup-TLabel或TNewStaticText-更改.字体.焦点上的样式(如光标)随而变化.光标



是否可以像使用.Cursor时使用光标那样更改Focus TLabelTNewStaticText上的.Font.Style

目前没有内置支持在Inno设置中跟踪鼠标悬停。不过,通过截取控件的窗口过程,您可以自己跟踪它。对于以下示例,您将需要InnoCallback库:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}My Program
OutputDir=userdocs:Inno Setup Examples Output
[Files]
Source: "InnoCallback.dll"; DestDir: "{tmp}"; Flags: dontcopy
[Code]
#ifdef UNICODE
  #define AW "W"
#else
  #define AW "A"
#endif
const
  GWL_WNDPROC = -4;
  WM_MOUSEMOVE = $0200;
type
  WPARAM = UINT_PTR;
  LPARAM = LongInt;
  LRESULT = LongInt;
  TWindowProc = function(hwnd: HWND; uMsg: UINT; wParam: WPARAM; 
    lParam: LPARAM): LRESULT;
function SetCapture(hWnd: HWND): HWND;
  external 'SetCapture@user32.dll stdcall';
function ReleaseCapture: BOOL;
  external 'ReleaseCapture@user32.dll stdcall';
function GetMessagePos: DWORD;
  external 'GetMessagePos@user32.dll stdcall';
function GetWindowRect(hWnd: HWND; out lpRect: TRect): BOOL;
  external 'GetWindowRect@user32.dll stdcall';
function CallWindowProc(lpPrevWndFunc: LongInt; hWnd: HWND; Msg: UINT; 
  wParam: WPARAM; lParam: LPARAM): LRESULT;
  external 'CallWindowProc{#AW}@user32.dll stdcall';
function SetWindowLong(hWnd: HWND; nIndex: Integer; 
  dwNewLong: LongInt): LongInt;
  external 'SetWindowLong{#AW}@user32.dll stdcall';
function WrapWindowProc(Callback: TWindowProc; ParamCount: Integer): LongWord;
  external 'wrapcallback@files:InnoCallback.dll stdcall';
type
  TControlRec = record
    Hovered: Boolean;     // hovering state
    WndProc: LongInt;     // original window proc
    Control: TWinControl; // control instance
  end;
var
  StaticText1: TNewStaticText;
  StaticText2: TNewStaticText;
  ControlList: array of TControlRec;
// helper function for finding control by handle
function GetControlRec(Handle: HWND): TControlRec;
var
  I: Integer;
begin
  for I := 0 to High(ControlList) do
    if ControlList[I].Control.Handle = Handle then
    begin
      Result := ControlList[I];
      Exit;
    end;
end;
// function which attaches the intercepting window procedure to the control
// and creates and adds the control record to the control list
procedure AttachWndProc(Control: TWinControl; WindowProc: TWindowProc);
begin
  SetArrayLength(ControlList, GetArrayLength(ControlList) + 1);
  ControlList[High(ControlList)].Hovered := False;
  ControlList[High(ControlList)].Control := Control;
  ControlList[High(ControlList)].WndProc := SetWindowLong(Control.Handle,
    GWL_WNDPROC, WrapWindowProc(WindowProc, 4));
end;
// function to restore windows procedures to all controls in the list
procedure RestoreWndProcs;
var
  I: Integer;
begin
  for I := 0 to High(ControlList) do
    SetWindowLong(ControlList[I].Control.Handle, GWL_WNDPROC, ControlList[I].WndProc);
end;
// helper function to create a TPoint structure from the result of GetMessagePos
// function call
function MakePoint(Value: DWORD): TPoint;
begin
  Result.X := Value and $FFFF;
  Result.Y := Value shr 16;
end;
// helper function which substitutes PtInRect Windows API function which I wasn't
// able to import for some reason
function PointInRect(const Rect: TRect; const Point: TPoint): Boolean;
begin
  Result := (Point.X >= Rect.Left) and (Point.X <= Rect.Right) and
    (Point.Y >= Rect.Top) and (Point.Y <= Rect.Bottom);
end;
// interceptor window procedure
function StaticTextWndProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; 
  lParam: LPARAM): LRESULT;
var
  P: TPoint;
  R: TRect;
  ControlRec: TControlRec;
begin
  // get control record
  ControlRec := GetControlRec(hwnd);
  // if the cursor moves, then...
  if uMsg = WM_MOUSEMOVE then
  begin
    // set mouse capture for this control to be notified by the WM_MOUSEMOVE even if
    // we leave the control
    SetCapture(ControlRec.Control.Handle);
    // get the current cursor position and control rectangle (both screen relative)
    P := MakePoint(GetMessagePos);
    GetWindowRect(ControlRec.Control.Handle, R);
    // check if the cursor is inside the control; if yes, then...
    if PointInRect(R, P) then
    begin
      // if the hovering flag was not yet set, it means we just entered the control
      // with the mouse, so let's change the style and remember the hovering state
      if not ControlRec.Hovered then
      begin
        if ControlRec.Control is TNewStaticText then
          TNewStaticText(ControlRec.Control).Font.Style := [fsBold];
        ControlRec.Hovered := True;
      end;
    end
    else
    begin
      // the cursor is not over the control, so let's release the mouse capture, set
      // the style and remember the hovering state
      ReleaseCapture;
      if ControlRec.Control is TNewStaticText then
        TNewStaticText(ControlRec.Control).Font.Style := [];
      ControlRec.Hovered := False;
    end;
  end;
  // call the original window procedure
  Result := CallWindowProc(ControlRec.WndProc, hwnd, uMsg, wParam, lParam);
end;
procedure InitializeWizard;
begin
  StaticText1 := TNewStaticText.Create(WizardForm);
  StaticText1.Parent := WizardForm;
  StaticText1.Left := 12;
  StaticText1.Top := 336;
  StaticText1.Caption := 'Hello';
  StaticText2 := TNewStaticText.Create(WizardForm);
  StaticText2.Parent := WizardForm;
  StaticText2.Left := 43;
  StaticText2.Top := 336;
  StaticText2.Caption := 'world!';
  AttachWndProc(StaticText1, @StaticTextWndProc);
  AttachWndProc(StaticText2, @StaticTextWndProc);
end;
procedure DeinitializeSetup;
begin
  RestoreWndProcs;
end;

对我来说,以下命令:High(ControlList)给了我以下错误:未知标识符"High",我相信High它只适用于Unicode Inno??(如果我错了,请纠正我:-)

我用GetArrayLength(ControlList)-1替换了High(ControlList),使它发挥了作用。

相关内容

  • 没有找到相关文章

最新更新