Component descriptions with rtf formatting

From NSIS Wiki
Jump to navigationJump to search
Author: Anders (talk, contrib)


Code Info

  • Version: 20091115
  • Type: Code example
  • Character encoding: Ansi & Unicode
  • Minimum OS: Win95/NT4?
  • Minimum NSIS Version: 2.0?
  • License: zlib/libpng


Cmpntdescrtf.png


The Code

!include MUI2.nsh
!define APPNAME "COMPONENTS; RTF Desc"
name "${APPNAME}"
caption "$(^Name)"
outfile "$%temp%\${APPNAME}.exe"
ShowInstDetails show
RequestExecutionLevel user
installdir "$Temp"
!include WinMessages.nsh
!include nsDialogs.nsh
 
var RichDesc
 
Function cmpnt_Show
!ifndef NSIS_CONFIG_LICENSEPAGE
	System::Call 'kernel32::LoadLibrary(t "RichEd20")'
	System::Call 'kernel32::LoadLibrary(t "RichEd32")'
!endif
 
FindWindow $0 "#32770" "" $HWNDPARENT
GetDlgItem $2 $0 1043
ShowWindow $2 0 ;hide the "real" description label (we still use it to get the text)
System::Call *(&i4,&i4,&i4,&i4).ir1
System::Call 'user32::GetWindowRect(ir2,ir1)'
IntOp $3 $1 + 8 
System::Call 'user32::MapWindowPoints(i0,i$2,i$3,i1)'
System::Call '*$1(&i4i,&i4i,&i4i.r5,&i4i.r6)' ;w&h
System::Call 'user32::MapWindowPoints(i0,i$0,i$1,i1)'
System::Call '*$1(&i4i.r3,&i4i.r4)' ;l&t
System::Free $1
 
;Try both richedit classes
StrCpy $1 "RichEdit20A"
createRich:
System::Call 'user32::CreateWindowEx(i ${WS_EX_TRANSPARENT},tr1,i0,\
	i ${WS_VISIBLE}|${WS_CHILD}|${WS_CLIPSIBLINGS}|${ES_READONLY}|${ES_MULTILINE}|${ES_WANTRETURN},\
	i $3,i $4,i $5,i $6,i $0,i0,i0,i0)i.s'
pop $RichDesc
${If} $RichDesc = 0
${AndIf} $1 == "RichEdit20A"
	StrCpy $1 "RichEdit"
	goto createRich
${EndIf}
 
SendMessage $2 ${WM_GETFONT} 0 0 $1
SendMessage $RichDesc ${WM_SETFONT} $1 1
System::Call user32::BringWindowToTop(i$RichDesc) ;stupid window seems to be stuck behind the groupbox
call cmpnt_onmouseover ;fake a update to set the initial text
FunctionEnd
 
!define MUI_CUSTOMFUNCTION_ONMOUSEOVERSECTION cmpnt_onmouseover
!define MUI_PAGE_CUSTOMFUNCTION_SHOW cmpnt_Show
 
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE "English"
 
Section aaa s1 
SectionEnd
Section /o bbb s2
SectionEnd
Section ccc s3
SectionEnd
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
  !insertmacro MUI_DESCRIPTION_TEXT ${s1} "aaaaaaa"
  !insertmacro MUI_DESCRIPTION_TEXT ${s2} "{\rtf1{{\colortbl ;\red255\green0\blue0;}foo \cf1\b bar \cf0\b0 baz!}"
  !insertmacro MUI_DESCRIPTION_TEXT ${s3} "{\rtf1{cc \b cccccc \b0 ccc}" 
!insertmacro MUI_FUNCTION_DESCRIPTION_END
 
Function cmpnt_onmouseover
FindWindow $1 "#32770" "" $HWNDPARENT
GetDlgItem $1 $1 1043
System::Call 'user32::SendMessage(i$1,i${WM_GETTEXT},i${NSIS_MAX_STRLEN},t.r2)'
SendMessage $RichDesc ${WM_SETTEXT} 0 STR:$2
System::Call "user32::GetWindowLong(i$1,i${GWL_STYLE})i.r1"
IntOp $1 $1 & ${WS_DISABLED}
EnableWindow $RichDesc $1 ;always force a state toggle, this is our "InvalidateRect" (since we have WS_EX_TRANSPARENT)
IntOp $1 $1 !
EnableWindow $RichDesc $1
!if 0
/*
Using EnableWindow to toggle the disabled state seems to do all the refreshing we need,
but just in case there is a problem, use this code to do proper InvalidateRect...
*/
System::Call '*(&i4,&i4,&i4,&i4).ir1'
FindWindow $0 "#32770" "" $HWNDPARENT
System::Call 'user32::GetWindowRect(i$RichDesc,ir1)'
System::Call 'user32::MapWindowPoints(i0,i$0,i$1,i2)'
System::Call 'user32::InvalidateRect(i$0,i$1,i1)'
System::Free $1
!endif
FunctionEnd


Credits

Written by Anders (For fun and profit?)