• 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

        此时编译并运行最后修改的脚本得到的将只是一个没有用处的空白页面。因此我们也应当在该页面上添加一些控件。要实现此目的,我们可使用头文件 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 到文本框中时通知用户。

        !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
                                    ${NSD_OnChange} $Text nsDialogsPageTextChange
                                    nsDialogs::Show
                                    FunctionEnd
                                    Function nsDialogsPageLeave
                                    ${NSD_GetText} $Text $0
                                    MessageBox MB_OK "You typed:$/n$/n$0"
                                    FunctionEnd
                                    Function nsDialogsPageTextChange
                                    Pop $1 # $1 == $ Text
                                    ${NSD_GetText} $Text $0
                                    ${If} $0 == "hello"
                                    MessageBox MB_OK "right back at ya!"
                                    ${EndIf}
                                    FunctionEnd
                                    Section
                                    DetailPrint "hello world"
                                    SectionEnd

        到目前为止,我们有了一个具备一些基本输入控件的页面。但是,当用户进入下一个页面后而又返回到前一页面时会发生什么情况呢?按照现有的代码,用户的输入将不会被储存下来。要储存它们,我们可以使用已有的离开回调函数来储存用户对的选择到变量并在下一次创建该控件时传递这些变量。更好的一个例子,我们也可以添加一个 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 显现了此函数的使用方法。

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

  • 相关阅读:
    (21)tar打包命令详解
    (19)ln命令:在文件之间建立链接(硬链接和软链接)
    (20)打包(归档)和压缩概念
    (18)文件和目录管理类的常用命令3
    SSH 登录警告:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
    (17)文件和目录管理类的常用命令2
    (16)文件和目录管理类的常用命令1
    (15)Linux命令基本格式
    (14)Linux绝对路径和相对路径
    (13)Linux文件系统的优缺点
  • 原文地址:https://www.cnblogs.com/gq0324/p/12097704.html
Copyright © 2020-2023  润新知