【问题标题】:NSIS How to modify MUI_PAGE_INSTFILES during installtion?NSIS如何在安装过程中修改MUI_PAGE_INSTFILES?
【发布时间】:2014-12-19 23:25:59
【问题描述】:

我想知道在 MUI_PAGE_INSTFILES 页面上运行安装时是否可以执行以下 UI 修改/调整(在 nsi 脚本中以编程方式):

  1. 将进度条的样式设置为marque(连续“滚动”)

  2. 隐藏详细信息文本字段(显示进度文本的位置)并改为显示预定义图片(包含在设置中)

[编辑] 或者对于数字 2:可能会缩小详细信息字段,并将图片显示为标签下方的横幅(这样详细信息字段将仅占垂直空间的一半,而其下方的另一半将被图片使用 - 这样用户可以看到进度和“横幅”)。

[编辑] 最好还有一些基本的幻灯片放映:定义几张图片并每 10 秒旋转一次

这背后的想法是,在安装过程中可能需要一些时间(比如超过 10 秒)来显示对用户来说更具信息性/价值的内容,例如如何开始使用图形、促销或其他内容.

如何做到这一点?

谢谢。

【问题讨论】:

    标签: user-interface nsis


    【解决方案1】:
    XPStyle on ; This must be on for the Marquee to show
    !include nsDialogs.nsh ; For WS_* and NSD_SetImage
    !include WinMessages.nsh
    !ifndef PBS_MARQUEE
    !define PBS_MARQUEE 8
    !endif
    !ifndef PBM_SETMARQUEE
    !define PBM_SETMARQUEE 0x40A
    !endif
    
    !macro ProgressMarquee_Begin
    FindWindow $0 "#32770" "" $HWNDPARENT ; Find inner dialog
    GetDlgItem $0 $0 1004 ; Find progress-bar
    System::Call USER32::GetWindowLong(ir0,i-16)i.r1
    IntOp $1 $1 | ${PBS_MARQUEE}
    System::Call USER32::SetWindowLong(ir0s,i-16,ir1s) ; This also saves the handle and style on the stack, we need those to turn it off again.
    SendMessage $0 ${PBM_SETMARQUEE} 1 0 ; The last parameter is the speed or 0 for the default
    !macroend
    !macro ProgressMarquee_Remove
    Exch
    Pop $1
    IntOp $0 ${PBS_MARQUEE} ~
    IntOp $1 $1 & $0
    System::Call USER32::SetWindowLong(is,i-16,ir1)
    !macroend
    
    Function DoLongOperation
    DetailPrint "Starting long operation"
    Sleep 4444
    DetailPrint "Long operation ended..."
    FunctionEnd
    
    Section
    DetailPrint "Simulating other install tasks..."
    Sleep 222
    Sleep 222
    Sleep 222
    Sleep 222
    Sleep 222
    Sleep 222
    
    ; Add a image and hide the log
    FindWindow $2 "#32770" "" $HWNDPARENT ; Find inner dialog
    GetDlgItem $0 $2 0x3F8 ; Find log window
    System::Call *(i,i,i,i)i.r1 ; Allocate a RECT
    System::Call 'USER32::GetWindowRect(ir0s,ir1)' ; Also saves log HWND on stack
    ShowWindow $0 0 ; Hide log window
    System::Call '*$1(i.r4,i.r5,i.r6,i.r7)'
    IntOp $6 $6 - $4
    IntOp $7 $7 - $5
    System::Call 'USER32::ScreenToClient(ir2,ir1)'
    System::Call '*$1(i.r4,i.r5)'
    System::Free $1
    System::Call 'USER32::CreateWindowEx(i0,t"STATIC",i0,i${WS_CHILD}|${WS_CLIPSIBLINGS}|${WS_VISIBLE}|${SS_BITMAP},ir4,ir5,ir6,ir7,ir2,i0,i0,i0)i.r2'
    Push $2 ; Save HWND
    SetDetailsPrint none
    File "/oname=$pluginsdir\img.bmp" "${NSISDIR}\Contrib\Graphics\Header\orange.bmp"
    SetDetailsPrint lastused
    ${NSD_SetImage} $2 "$pluginsdir\img.bmp" $9
    Push $9 ; Save HBITMAP
    
    
    !insertmacro ProgressMarquee_Begin
    Call DoLongOperation
    !insertmacro ProgressMarquee_Remove
    
    
    ; Remove and cleanup image
    Pop $0
    ${NSD_FreeBitmap} $0
    Pop $0
    ShowWindow $0 0
    Pop $0 ; Log window handle we saved
    ShowWindow $0 1
    SectionEnd
    

    如果你想显示多个图像,那么你需要多次调用 ${NSD_SetImage} 但如果你想沿着这条路线走,最好写一个 NSIS 插件,在辅助线程上完成所有这些......

    【讨论】:

    • 哇!你回答问题比我问他们快!非常感谢!
    • 关于选框进度条的问题:它可以工作,但由于某种原因动画速度不是恒定的 - 有时是正常的,但有时它真的很快导致闪烁。所以它会在正常速度和超快速度之间循环几次,并闪烁。在 Windows 8.1 和 Windows 7 上都尝试过 - 结果相同。我在您在上一个答案中提供的例程之前插入了 ProgressMarquee_Begin 宏。可能与等待循环中的睡眠指令有关?
    • 可能,您可以将等待分成多个较短的睡眠来找出答案。
    • 减少睡眠时间没有帮助。我现在决定让它保持连续。我对“删除和清理图像”部分有疑问。理想情况下,我希望这两个部分都作为宏(如进度条),这样我就可以从不同的代码路径调用它们而不必担心堆栈。有没有办法重写图像例程的显示和隐藏,以便可以从不保证堆栈完整性的任何地方调用它们?原因是显示图像后可能有一些关键的东西(例如缺少必需的组件)需要再次显示细节。
    • 唯一的“隐藏”堆栈使用是“ir0s”,它推送 $0,您可以将其替换为“ir0”,然后手动将 $0 保存在您自己的全局变量中,对其他两个 Push 执行相同操作'es 并将 "Pop $0" + usage of $0 替换为您保存的全局变量。理想情况下,您应该在代码中的某些点保持堆栈处于正常状态,因此这不是问题。 ProgressMarquee 宏也使用堆栈。
    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 2022-08-18
    相关资源
    最近更新 更多