Inno Setup 组件的详细描述

2023-11-22

我正在使用 Inno Setup 构建安装,并使用组件部分来允许最终用户选择要安装的可选项目。

其中一些项目需要更长的描述,以便用户有足够的信息来智能地选择它们。

有没有办法在某处添加更深入的描述?


此解决方案仅使用正确的 Inno Setup(而不是来源可疑的 Inno Setup 的过时的第 3 方版本)。

该解决方案部分基于我的回答Inno Setup:OnHover 事件.

调整HoverComponentChanged程序以满足您的需要。

[Code]

var
  LastMouse: TPoint;
  CompLabel: TLabel;

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 ListBox_GetItemRect(
  const hWnd: HWND; const Msg: Integer; Index: LongInt; var Rect: TRect): LongInt;
  external '[email protected] stdcall';  

const
  LB_GETITEMRECT = $0198;
  LB_GETTOPINDEX = $018E;

function FindControl(Parent: TWinControl; P: TPoint): TControl;
var
  Control: TControl;
  WinControl: TWinControl;
  I: Integer;
  P2: TPoint;
begin
  for I := 0 to Parent.ControlCount - 1 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;

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;

function ListBoxItemAtPos(ListBox: TCustomListBox; Pos: TPoint): Integer;
var
  Count: Integer;
  ItemRect: TRect;
begin
  Result := SendMessage(ListBox.Handle, LB_GETTOPINDEX, 0, 0);
  Count := ListBox.Items.Count;
  while Result < Count do
  begin
    ListBox_GetItemRect(ListBox.Handle, LB_GETITEMRECT, Result, ItemRect);
    if PointInRect(ItemRect, Pos) then Exit;
    Inc(Result);
  end;
  Result := -1;
end;

procedure HoverComponentChanged(Index: Integer);
var 
  Description: string;
begin
  case Index of
    0: Description := 'This is the description of Main Files';
    1: Description := 'This is the description of Additional Files';
    2: Description := 'This is the description of Help Files';
  else
    Description := 'Move your mouse over a component to see its description.';
  end;
  CompLabel.Caption := Description;
end;

procedure HoverTimerProc(
  H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
var
  P: TPoint;
  Control: TControl; 
  Index: Integer;
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;

    Index := -1;
    if (Control = WizardForm.ComponentsList) and
       (not WizardForm.TypesCombo.DroppedDown) then
    begin
      P := LastMouse;
      ScreenToClient(WizardForm.ComponentsList.Handle, P);
      Index := ListBoxItemAtPos(WizardForm.ComponentsList, P);
    end;

    HoverComponentChanged(Index);
  end;
end;

procedure InitializeWizard();
begin
  SetTimer(0, 0, 50, CreateCallback(@HoverTimerProc));

  CompLabel := TLabel.Create(WizardForm);
  CompLabel.Parent := WizardForm.SelectComponentsPage;
  CompLabel.Left := WizardForm.ComponentsList.Left;
  CompLabel.Width := WizardForm.ComponentsList.Width;
  CompLabel.Height := ScaleY(32);
  CompLabel.Top :=
    WizardForm.ComponentsList.Top + WizardForm.ComponentsList.Height -
    CompLabel.Height;
  CompLabel.AutoSize := False;
  CompLabel.WordWrap := True;

  WizardForm.ComponentsList.Height :=
    WizardForm.ComponentsList.Height - CompLabel.Height - ScaleY(8);
end;

enter image description here

For CreateCallback功能,您需要 Inno Setup 6。如果您无法使用 Inno Setup 5,您可以使用WrapCallback函数来自InnoTools InnoCallback图书馆。使用 Inno Setup 5 的 Unicode 版本。

为了使其在调整大小/调整大小/现代向导中正常工作,您将需要进行一些调整。看Inno Setup - 如何在调整大小向导中将动画 gif 居中 and 放大的 Inno Setup 向导中的长组件描述.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Inno Setup 组件的详细描述 的相关文章

随机推荐

  • jQuery UI 可调整大小:单独使用东手柄时自动高度

    我有一个 jqueryui 可调整大小的 div 我只希望宽度可以调整大小 高度保持自动 以便 div 随内容而增大或缩小 如果我将其设置为仅显示东手柄并使用 cssheight auto 调整大小后 即使仅更改了宽度 高度也会被设置 每次
  • 使用 Xcode 4.5 本地化 Localizable.strings [重复]

    这个问题在这里已经有答案了 可能的重复 本地化 将其他语言添加到 localized strings 文件 使用 Xcode 4 5 SDK iOS 6 0 我无法将本地化添加到 Localizes strings 文件 在 Xcode 4
  • 启动进程:访问被拒绝(即使我已经提供了凭据

    尝试执行一行代码时出现以下错误 Start Process This command cannot be executed due to the error Access is denied 这是正在执行的代码 username domai
  • Django 1.8:为现有模式创建初始迁移

    我启动了一个 django 1 8 项目 它使用迁移系统 不知何故 事情变得一团糟 所以我从数据库中删除了迁移文件夹和表 现在我试图重建它们 但没有成功 我有三个应用程序 3models py文件 并且模型完全反映了表格 到目前为止我发现的
  • 无效 BFG 使用后的 Git 合并重复

    我对整个存储库 仅由我使用 深感厌烦 并且可以使用一些帮助来整理它 这就是我所做的 我意识到在我的提交历史记录中 有一些包含我不想随意放置的凭据的文件 因此 我决定合法地尝试使用 BFG Repo Cleaner 来解决这些问题 我将所有凭
  • 在 Go 中,如何在不使用 for 循环的情况下初始化数组?

    我有一个数组A布尔值 按整数索引0 to n 全部初始设置为true 我当前的实现是 for i 0 i lt n i A i true Using a for循环是最简单的解决方案 创建数组或切片将始终返回一个归零的值 哪种情况下bool
  • Python sys.path 修改不起作用

    我正在尝试修改我的 Python 文件之一中的 sys path 以获得一些 模块搜索路径中的特定库目录 这可能不是最好的方法 但 如果我在 sys path 前面插入多个路径 我的脚本不会考虑将来导入的这些路径 如果我创建一个包含我需要的
  • 如何获取 Oracle SQL 查询中错误的位置?

    如何获取查询中错误的位置 我需要获取导致错误的查询字符串中的位置 例如sqlplus可以 SQL gt insert into tbl data values 12345 2 insert into tbl data values 1234
  • ASP.Net - 从包含数据绑定的标记调用方法

    我在 ASP NET 中有一个用 C 编写的用户控件 该用户控件在代码隐藏中有一个方法 定义如下 protected string GetGreeting string name if String IsNullOrEmpty name r
  • 如何查找数组中的重复值?

    我正在 SQLite 上工作 我编写了一个查询 它返回两个数组 ItemsArray 和 CustomersIDArray 如下所示 ItemsArray Element at Index 0 Off White Element at In
  • iOS - 更新到新版本时保留旧的 sqlite 数据库

    我发现了一些其他问题 但我没有清楚地知道如何在 ios 中更新应用程序时保留旧数据库中的数据 情况1 我可以保留旧数据库吗 如果情况 1 为 是 我可以插入新列或在旧数据库中进行任何更改吗 这安全吗 如果情况 1 为 否 我可以在新数据库中
  • 在 asp.net mvc 3 中预填充 Html.TextBoxFor

    我对此很陌生 所以如果这还不够解释的话 我很抱歉 我想在 asp net mvc 3 的表单中预填充一个字段 这可行 Html TextBox CompName null new value ViewBag CompName 但是当我想用一
  • Spring boot - 如何获取运行端口和IP地址[重复]

    这个问题在这里已经有答案了 我在启动 Spring Boot 应用程序时通过 shell 脚本传递端口 想知道如何获取应用程序中的运行端口和系统IP地址以打印在日志文件中 脚本 Dcom sun management jmxremote D
  • 免费的java 3d引擎[关闭]

    Closed 这个问题是无关 目前不接受答案 适用于 java 的最佳 3D 游戏引擎是什么 我正在寻找具有良好的视觉开发工具集的东西 我已经查看了维基百科上的可用列表 http en wikipedia org wiki List of
  • ggplot 增加箱线图之间的距离

    如何避免附加箱线图 谢谢 ggplot df aes x factor time y val fill ID geom boxplot scale fill manual values c WT goldenrod3 KO steelblu
  • 设置 char* 缓冲区并中间转换为 int*

    我无法完全理解我在这里读到的内容的后果 将 int 指针转换为 char ptr 反之亦然 简而言之 这行得通吗 set4Bytes unsigned char buffer const uint32 t MASK 0xffffffff i
  • 无法在 D3 JavaScript 库中获取点击事件

    我正在使用 D3 JavaScript 库将数据显示为力定向标记 效果很好 但我无法将点击事件添加到圈子中 因此 当我单击圆圈时 我会获得对该圆圈的详细分析并将其显示在模式框中 var links source x target y typ
  • 将生成的 PIL 图像保存到 django 中的 ImageField 中

    我在用qrcode生成二维码 当购买门票或购买真实时 我想生成一个二维码图像并使用 PIL 进行一些更改 最后将修改后的画布保存到模型的Image字段中 class Ticket models Model booked at models
  • Angular ui 模式与控制器位于单独的 js 文件中

    我正在尝试制作一个可以从应用程序中的多个位置实例化的模式 从这里给出的例子 Bootstrap 的 Angular 指令模态控制器与实例化模态的控制器位于同一文件中 我想将模态控制器与 应用程序 控制器分开 索引 html
  • Inno Setup 组件的详细描述

    我正在使用 Inno Setup 构建安装 并使用组件部分来允许最终用户选择要安装的可选项目 其中一些项目需要更长的描述 以便用户有足够的信息来智能地选择它们 有没有办法在某处添加更深入的描述 此解决方案仅使用正确的 Inno Setup