Fit Dev
Fit Dev

Reputation: 3685

NSIS How to modify MUI_PAGE_INSTFILES during installtion?

I am wondering if it will be possible to perform the following UI modifications / tweaks (programmatically in the nsi script) WHILE the installation is running on the MUI_PAGE_INSTFILES page:

  1. Set the style of the progress bar to marque (continuous "scrolling")

  2. Hide the details text field (where the progress text is displayed) and show a predefined picture instead (that was included with the setup)

[EDIT] Alternatively for number 2: maybe shrink the details field, and display the picture as a banner like label just below it (so that the details field would occupy only half the space vertically, and the other half below it would be used by the picture - that way a user can see both the progress and the "banner").

[EDIT] Even better still would be to have some sort of basic slide show: define several pictures and rotate them every 10 seconds

Sample graphic of what I want

The idea behind this is that during parts of the installation that may take some time (say over 10 seconds) to display something more informative / valuable to the user, such as how to get started graphic, a sales promotion or something else.

How can this be done?

Thanks.

Upvotes: 0

Views: 1231

Answers (1)

Anders
Anders

Reputation: 101569

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

If you want to show multiple images then you need multiple calls to ${NSD_SetImage} but if you want to go down this route it is probably much better to write a NSIS plugin that does all this on a secondary thread...

Upvotes: 1

Related Questions