DetailUpdate
Author: Afrow UK (talk, contrib) |
Description
A small function/macro combo to update the text of the last item printed in the install files page list view control. It also updates the status label above the progress bar with the same text.
The Function
Function DetailUpdate Exch $R0 Push $R1 Push $R2 Push $R3 FindWindow $R2 `#32770` `` $HWNDPARENT GetDlgItem $R1 $R2 1006 SendMessage $R1 ${WM_SETTEXT} 0 `STR:$R0` GetDlgItem $R1 $R2 1016 System::Call *(&t${NSIS_MAX_STRLEN}R0)i.R2 System::Call *(i0,i0,i0,i0,i0,iR2,i${NSIS_MAX_STRLEN},i0,i0)i.R3 !define LVM_GETITEMCOUNT 0x1004 !define LVM_SETITEMTEXT 0x102E SendMessage $R1 ${LVM_GETITEMCOUNT} 0 0 $R0 IntOp $R0 $R0 - 1 System::Call user32::SendMessage(iR1,i${LVM_SETITEMTEXT},iR0,iR3) System::Free $R3 System::Free $R2 Pop $R3 Pop $R2 Pop $R1 Pop $R0 FunctionEnd !macro DetailUpdate Text Push `${Text}` Call DetailUpdate !macroend !define DetailUpdate `!insertmacro DetailUpdate`
I've decided to use the System plug-in to call SendMessage for setting the list view item text. This probably isn't necessary (the built in SendMessage did work as well) but as System has allocated the memory I'd rather be on the safe side and use that instead.
Usage
Function SomeProcess DetailPrint `Processing: 0% done...` ${For} $R0 1 5 Sleep 2000 IntOp $R1 $R0 * 20 ${DetailUpdate} `Processing: $R1% done...` ${Next} ${DetailUpdate} `Processing complete!` FunctionEnd Section `Some process` Call SomeProcess SectionEnd
Note that I've placed the loop inside a function and called that function from the section otherwise the progress bar will move back and forth.
Background
The install files page window is just a standard Windows SysListView32 control which means you can send any of the LVM_* messages to it. Some messages however such as LVM_SETITEMTEXT require a LVITEM struct as well as a buffer containing the text to set. The first System::Call allocates that buffer and initialises it with the new text and the second System::Call allocates the LVITEM struct containing a pointer to that buffer. At the end we have to free these two chunks of allocated memory using System::Free. Using this code it should be straight forward to work with other list view controls such as with nsDialogs.