NSIS nsDialogs 插件

介绍

nsDialogs nsDialogs 允许在安装程序中创建自定义页面。居于内置的页面之上,nsDialogs 能够创建包含任何类型的以任意形式排列的控件的页面。它能够创建简至仅一个控件的页面,也能创建满足用户需求的版面。例如,Modern UI 2 使用 nsDialogs 来创建欢迎完成页面。

nsDialogs 是一个新的 NSIS 插件,自版本 NSIS 2.29 作为InstallOptions 的替代品被引入。nsDialogs 不使用 INI 文件,因此执行速度要比 InstallOptions 快得多。与脚本的整合度更紧密也更自然了棗创建控件是通过使用插件的功能实现的,而通告则是直接在脚本中调用一个函数来实现的。不象 InstallOptions 那样,它没有预先定义的可能用到的控件类型并实现较低层次的 Windows API 访问,每一种类型的控件均能被创建并且页面的定制具有更高的自由度。

使用 nsDialogs 越灵活的同时,没有 Win32 API 知识的用户就会觉得越复杂。这可通过创建预定义函数库解决。函数库在脚本中定义,可允许进行控件的创建和处理。这样,新手可以简易地体会其易用性,而高级用户仍可通过修改函数库来体会其核心功能的强大。

脚本指南,从零开始

在使用之初,让我们先创建一个基本的脚本作为我们的骨架。

Name nsDialogs
OutFile nsDialogs.exe
XPStyle on
Page instfiles
Section
DetailPrint "hello world"
SectionEnd

其次,我们将要添加一个自定义页面,在此我们可以使用 nsDialogs。nsDialogs 不能用于区段或自定义页面函数之外的任何函数中。

Name nsDialogs
OutFile nsDialogs.exe
XPStyle on
Page custom nsDialogsPage
Page instfiles
Function nsDialogsPage
FunctionEnd
Section
DetailPrint "hello world"
SectionEnd

现在轮廓已基本搞定,该让我们的 nsDialogs 上场了!第一个调用必须总是 nsDialogs::Create。它将在该页面中创建一个对话框,并在堆栈中返回其 HWND 值。其结果必须从堆栈中被弹出以免堆栈出错。若结果为 error,对话框将不会被创建。

nsDialogs::Create 类似 nsDialogs::Show 之外的其它函数,必须带 /NOUNLOAD 调用。

nsDialogs::Create 接受一个参数。它有一个特殊的功能,但为了保持此教程的简易性,参数值总是规定为 1018。

HWND 是一个标识当前对话框唯一性的数字,可用于 SendMessage、SetCtlColors 和 Win32 API。

!include LogicLib.nsh
Name nsDialogs
OutFile nsDialogs.exe
XPStyle on
Var Dialog
Page custom nsDialogsPage
Page instfiles
Function nsDialogsPage

nsDialogs::Create /NOUNLOAD 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}

FunctionEnd
Section
DetailPrint "hello world"
SectionEnd

现在页面已经创建,该让她露脸了!这次使用的是 nsDialogs::Show。此函数直至用户点击下一步上一步取消按钮后才会返回。

!include LogicLib.nsh
Name nsDialogs
OutFile nsDialogs.exe
XPStyle on
Var Dialog
Page custom nsDialogsPage
Page instfiles
Function nsDialogsPage
nsDialogs::Create /NOUNLOAD 1018
Pop $Dialog
${If} $Dialog == error
Abort
${EndIf}
nsDialogs::Show

FunctionEnd
Section
DetailPrint "hello world"
SectionEnd
HLine
VLine
Label
Icon
Bitmap
BrowseButton
Link
Button
GroupBox
CheckBox
RadioButton
Text
Password
FileRequest
DirRequest
ComboBox
DropList
ListBox
      • HLine
      • VLine
      • Label
      • Icon
      • Bitmap
      • BrowseButton
      • Link
      • Button
      • GroupBox
      • CheckBox
      • RadioButton
      • Text
      • Password
      • FileRequest
      • DirRequest
      • ComboBox
      • DropList
      • ListBox

此时编译并运行最后修改的脚本得到的将只是一个没有用处的空白页面。因此我们也应当在该页面上添加一些控件。要实现此目的,我们可使用头文件 nsDialogs.nsh 中的宏 ${NSD_Create*}。这些宏,每个都带有 5 个参数 – x, y, width, height 和 text. 每个宏也都会返回一个值到堆栈,那就是新控件的 HWND。如同对话框的 HWND,它必须从堆栈中被弹出并保存下来。

宏使用的所有尺寸单位均可使用以下三种单位类型中的任一种棗像素、对话框单位 或 对话框尺寸的百分比。你可以指定负值,这表示距离是从右端或底部算起。要使用对话框单位,数值后面必须加上后缀符 u。要使用百分比单位,数值后面必须加上百分符 – %。此外,有无其它的后缀符均表示像素。

使用对话框单位作为尺寸单位,能够保证在用户不同的字体或 DPI 设置下均能完美地显示对话框。

!include nsDialogs.nsh
!include LogicLib.nsh
 Name nsDialogs
 OutFile nsDialogs.exe
 XPStyle on
 Var Dialog
 Var Label
 Var Text
 Page custom nsDialogsPage
 Page instfiles
 Function nsDialogsPage
 nsDialogs::Create /NOUNLOAD 1018
 Pop $Dialog
 ${If} $Dialog == error
 Abort
 ${EndIf}
 
 ${NSD_CreateLabel} 0 0 100% 12u "Hello, welcome to nsDialogs!"
 Pop $Label
 ${NSD_CreateText} 0 13u 100% -13u "Type something here..."
 Pop $Text
 
 nsDialogs::Show
 FunctionEnd
 Section
 DetailPrint "hello world"
SectionEnd

有效的能用 ${NSD_Create*} 来创建的控件类型为:

现在我们有了一些用户可以参与互动的控件,那么让我们看看用户到底对她们都干了些什么吧。要实现此目的,我们首先要添加一个离开回调 (leave callback) 函数到我们的页面。在该函数中,我们需要知道我们所创建并显现在用户面前的 Text 控件的状态。要实现此目的,我们要使用宏 ${NSD_GetText}。对于 RadioButton 和 CheckBox 控件则要使用宏${NSD_GetState}。

注意并非所有的控件都支持 ${NSD_GetText},一些控件需要使用特定讯息(在 WinMessages.nsh 中定义)来进行特殊的处理。例如 ListBox 控件需要使用 LB_GETCURSELLB_GETTEXT。nsDialogs.nsh 中的宏集将会及时地补充许许多多的宏来处理更多的此类事情。

!include nsDialogs.nsh
!include LogicLib.nsh
 Name nsDialogs
 OutFile nsDialogs.exe
 XPStyle on
 Var Dialog
 Var Label
 Var Text
 Page custom nsDialogsPage nsDialogsPageLeave
 Page instfiles
Function nsDialogsPage
 nsDialogs::Create /NOUNLOAD 1018
 Pop $Dialog
 ${If} $Dialog == error
 Abort
 ${EndIf}
 ${NSD_CreateLabel} 0 0 100% 12u "Hello, welcome to nsDialogs!"
 Pop $Label
 ${NSD_CreateText} 0 13u 100% -13u "Type something here..."
 Pop $Text
 nsDialogs::Show
FunctionEnd

Function nsDialogsPageLeave
 ${NSD_GetText} $Text $0
 MessageBox MB_OK "You typed:$/n$/n$0"
FunctionEnd

Section
 DetailPrint "hello world"
SectionEnd

nsDialogs 让人兴奋的新功能之一就是对话框状态改变时的回调函数通告。nsDialogs 能够调用脚本中定义的一个函数以响应诸如文本区段的改变和某按钮的点击等用户行为。需求。要使得 nsDialogs 通告我们事件的发生,我们可以使用${NSD_OnClick} 和 ${NSD_OnChange}。并非所有的控件都支持事件通告。例如 label 控件没有任何的通告。

当回调函数被调用时,将在堆栈中返回控件的 HWND 值,其结果必须从堆栈中被弹出以免堆栈出错。在这个简易的脚本中似乎看不出有多大用处。但是在一个大型的脚本中几个控件关联到相同的回调函数,HWND 值能够区分出哪个控件触发了该事件。

下面的例子将在用户输入 hello 到文本框中时通知用户。

到目前为止,我们有了一个具备一些基本输入控件的页面。但是,当用户进入下一个页面后而又返回到前一页面时会发生什么情况呢?按照现有的代码,用户的输入将不会被储存下来。要储存它们,我们可以使用已有的离开回调函数来储存用户对的选择到变量并在下一次创建该控件时传递这些变量。更好的一个例子,我们也可以添加一个 Checkbox 控件到页面,并使用 ${NSD_GetState} 和 ${NSD_SetState} 来获取和设置其状态。

为了更直观一些,我们将要删除先前步骤中的一些通告。

!include nsDialogs.nsh
!include LogicLib.nsh
 Name nsDialogs
 OutFile nsDialogs.exe
 XPStyle on
 Var Dialog
 Var Label
 Var Text
 Var Text_State
 Var Checkbox
 Var Checkbox_State
 Page custom nsDialogsPage nsDialogsPageLeave
 Page license
 Page instfiles
 
Function .onInit
 StrCpy $Text_State "Type something here..."
 FunctionEnd
 Function nsDialogsPage
 nsDialogs::Create /NOUNLOAD 1018
 Pop $Dialog
 ${If} $Dialog == error
 Abort
 ${EndIf}
 ${NSD_CreateLabel} 0 0 100% 12u "Hello, welcome to nsDialogs!"
 Pop $Label
 ${NSD_CreateText} 0 13u 100% 12u $Text_State
 Pop $Text
 ${NSD_CreateCheckbox} 0 30u 100% 10u "&Something"
 Pop $Checkbox
 ${If} $Checkbox_State == ${BST_CHECKED}
 ${NSD_Check} $Checkbox
 ${EndIf}
 # alternative for the above ${If}:
 #${NSD_SetState} $Checkbox_State
 nsDialogs::Show
FunctionEnd

Function nsDialogsPageLeave
 ${NSD_GetText} $Text $Text_State
 ${NSD_GetState} $Checkbox $Checkbox_State
FunctionEnd

Section
 DetailPrint "hello world"
SectionEnd

基本脚本

自定义页面

创建页面

显示页面

添加控件

控件状态

实时通告

储存数据

函数参考

Create

nsDialogs::Create /NOUNLOAD rect

新建一个对话框。rect 指定了位置将被模仿的控件的标识符。此处通常使用 1018,用其模仿内建页面的创建。Modern UI 也用 1040 来控制欢迎完成页面。

返回新对话框的 HWND 值到堆栈或 error

CreateControl

nsDialogs::CreateControl /NOUNLOAD class style extended_style x y width height text

在当前对话框中新建一个控件。此函数正常工作的前提条件是对话框必须存在,故 nsDialogs::Create 必须在此函数之前调用。

返回新控件的 HWND 值到堆栈或 error

Show

nsDialogs::Show

显示页面。一旦调用它将结束 nsDialogs::Create、nsDialogs::CreateControl 及其它 nsDialogs 函数。

无返回值。

SelectFileDialog

nsDialogs::SelectFileDialog /NOUNLOAD mode initial_selection filter

显示一个文件选择对话框。若 mode 设置为 save,将显示一个保存文件对话框,若 mode 设置为 open,将显示一个打开文件对话框。filter 为有效的文件过滤器列表,用 | 分隔。如果没有指定,则使用默认的 所有文件|*.*

返回所选中的文件到堆栈,或当用户取消操作时返回空字串。

SelectFolderDialog

nsDialogs::SelectFolderDialog /NOUNLOAD title initial_selection

显示一个文件夹选择对话框。

返回所选中的文件夹到堆栈,或当用户取消操作时返回空字串。

SetRTL

nsDialogs::SetRTL /NOUNLOAD rtl_setting

打开/关闭 从右到左 模式。若 rtl_setting = 0,关闭。若 rtl_setting = 1,打开。此函数必须在任何的 nsDialogs::CreateControl 之前调用。

无返回值。

GetUserData

nsDialogs::GetUserData /NOUNLOAD control_HWND

返回与控件相关联的用户数据到堆栈。使用 nsDialogs::SetUserData 设置此数据。

SetUserData

nsDialogs::SetUserData /NOUNLOAD control_HWND data

关联数据到控件。使用 nsDialogs::GetUserData 获取此数据。

无返回值。

OnBack

nsDialogs::OnBack /NOUNLOAD function_address

设置上一步按钮的回调函数。此函数在用户点击上一步按钮时调用。在此函数中调用 Abort 能阻止用户回到前一个页面。

使用 GetFunctionAddress 获取期望的回调函数地址。

无返回值。

OnChange

nsDialogs::OnChange /NOUNLOAD control_HWND function_address

设置一个更改通告回调函数到所指定的控件。当控件状态被更改时,该函数将被调用,并返回控件的 HWND 值到堆栈。

使用 GetFunctionAddress 获取期望的回调函数地址。

无返回值。

OnClick

nsDialogs::OnClick /NOUNLOAD control_HWND function_address

设置一个点击通告回调函数到所指定的控件。当控件被点击时,该函数将被调用,并返回控件的 HWND 值到堆栈。

使用 GetFunctionAddress 获取期望的回调函数地址。

无返回值。

OnNotify

nsDialogs::OnNotify /NOUNLOAD control_HWND function_address

设置一个通告回调函数到所指定的控件。当控件接收到 WM_NOTIFY 讯息时,该函数将被调用,并返回控件的 HWND 值、通告代码和 MNHDR 结构指针到堆栈。

使用 GetFunctionAddress 获取期望的回调函数地址。

无返回值。

宏参考

      • ${NSD_CreateHLine}
      • ${NSD_CreateVLine}
      • ${NSD_CreateLabel}
      • ${NSD_CreateIcon}
      • ${NSD_CreateBitmap}
      • ${NSD_CreateBrowseButton}
      • ${NSD_CreateLink}
      • ${NSD_CreateButton}
      • ${NSD_CreateGroupBox}
      • ${NSD_CreateCheckBox}
      • ${NSD_CreateRadioButton}
      • ${NSD_CreateText}
      • ${NSD_CreatePassword}
      • ${NSD_CreateNumber}
      • ${NSD_CreateFileRequest}
      • ${NSD_CreateDirRequest}
      • ${NSD_CreateComboBox}
      • ${NSD_CreateDropList}
      • ${NSD_CreateListBox}

nsDialogs.nsh 包含了一系列的宏,这将使得 nsDialogs 的使用变得更简单一些。下面是有关这些宏的用途、语法、输入和输出的简要介绍。

NSD_Create*

${NSD_Create*} x y width height text

在当前对话框中新建一个控件。此函数正常工作的前提条件是对话框必须存在,故 nsDialogs::Create 必须在此函数之前调用。

有效的变量:

返回新对话框的 HWND 值到堆栈或 error。

NSD_OnBack

${NSD_OnBack} control_HWND function_address

参阅 OnBack 了解更多资料。

NSD_OnChange

${NSD_OnChange} control_HWND function_address

参阅 OnChange 了解更多资料。

参阅 Real-time Notification 了解使用实例。

NSD_OnClick

${NSD_OnClick} control_HWND function_address

参阅 OnClick 了解更多资料。

NSD_OnNotify

${NSD_OnNotify} control_HWND function_address

参阅 OnNotify 了解更多资料。

NSD_AddStyle

${NSD_AddStyle} control_HWND style

添加一个或多个窗口外观样式到控件。多个外观样式用分隔符 `|’ 隔开。

请到 MSDN 获取样式资料。

NSD_AddExStyle

${NSD_AddExStyle} control_HWND style

添加一个或多个窗口外观样式到控件。多个外观样式用分隔符 `|’ 隔开。

请到 MSDN 获取样式资料。

NSD_GetText

${NSD_GetText} control_HWND output_variable

返回某个控件的 text 状态并储存到 output_variable。尤其适用于 Text 控件。

参阅 Control State 了解使用实例。

NSD_SetText

${NSD_SetText} control_HWND text

设置某个控件的 text 状态。

NSD_SetTextLimit

${NSD_SetTextLimit} control_HWND limit

设置 Text 控件的输入长度限制。

NSD_GetState

${NSD_GetState} control_HWND output_variable

返回 CheckBox 和 RadioButton 控件的状态。可能的输出值为 ${BST_CHECKED} 和 ${BST_UNCHECKED}。

参阅 Memory 了解使用实例。

NSD_SetState

${NSD_SetState} control_HWND state

设置 CheckBox 和 RadioButton 控件的状态。可能的 state 参数数据为 ${BST_CHECKED} 和 ${BST_UNCHECKED}。

参阅 Memory 了解使用实例。

NSD_Check

${NSD_Check} control_HWND

勾选一个 CheckBox 和 RadioButton 控件。等同于带 ${BST_CHECKED} 参数调用 ${NSD_SetState}。

NSD_Uncheck

${NSD_Uncheck} control_HWND

取消勾选一个 CheckBox 和 RadioButton 控件。等同于带 ${BST_UNCHECKED} 参数调用 ${NSD_SetState}。

参阅 Memory 了解使用实例。

NSD_CB_AddString

${NSD_CB_AddString} combo_HWND string

添加一个字符串到组合框。

NSD_CB_SelectString

${NSD_CB_SelectString} combo_HWND string

选择组合框中的一个字符串。

NSD_LB_AddString

${NSD_LB_AddString} combo_HWND string

添加一个字符串到列表框。

NSD_LB_SelectString

${NSD_LB_SelectString} combo_HWND string

选择列表框中的一个字符串。

NSD_SetFocus

${NSD_SetFocus} control_HWND

将控件设置为焦点。

NSD_SetImage

${NSD_SetImage} control_HWND image_path output_variable

image_path 载入一个图像并显示在已使用 ${NSD_CreateBitmap} 创建的 control_HWND 位置上。图像句柄储存在output_variable 中,一旦不需要时可使用 ${NSD_FreeImage} 释放。

必须在图像被释放到用户系统之后才能调用此宏。推荐释放图像到 $PLUGINSDIR 。

!include nsDialogs.nsh
 Name nsDialogs
 OutFile nsDialogs.exe
 XPStyle on
 Page custom nsDialogsImage
 Page instfiles
 Var Dialog
 Var Image
 Var ImageHandle
 
Function .onInit
 InitPluginsDir
 File /oname=$PLUGINSDIR/image.bmp "${NSISDIR}/Contrib/Graphics/Header/nsis-r.bmp"
FunctionEnd

Function nsDialogsImage
 nsDialogs::Create /NOUNLOAD 1018
 Pop $Dialog
 ${If} $Dialog == error
 Abort
 ${EndIf}
 ${NSD_CreateBitmap} 0 0 100% 100% ""
 Pop $Image
 ${NSD_SetImage} $Image $PLUGINSDIR/image.bmp $ImageHandle
 nsDialogs::Show
 ${NSD_FreeImage} $ImageHandle
FunctionEnd

Section
SectionEnd

NSD_SetStretchedImage

${NSD_SetStretchedImage} control_HWND image_path output_variable

载入并显示一个图像,有点类似 ${NSD_SetImage},但它能拉伸图像以填充控件的位置范围。

NSD_ClearImage

${NSD_ClearImage} control_HWND

清除控件图像。

NSD_FreeImage

${NSD_FreeImage} image_handle

释放一个先前使用 ${NSD_SetImage} 或 ${NSD_SetStretchedImage} 加载的图像句柄。

常见问题

  • Q: nsDialogs 能否处理 InstallOptions INI 文件?

    A: nsDialogs.nsh 中包含的一个名为 CreateDialogFromINI 的函数能够根据 INI 文件创建 nsDialogs 对话框。它能处理 InstallOptions 支持的各种控件类型,但暂不会处理 flags 标记或通告。Examples/nsDialogs/InstallOptions.nsi 显现了此函数的使用方法。

    未来将也会有一个函数来创建脚本自身。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容