for what it's worth - I think the actual problem is that callback1 rolls over to callback2 the next time your page is generated.
I'm not sure if there's an appropriate method to prevent that, but you can always make the "callback1" check more dynamic by Pop'ing it into a var first, then Push'ing it back onto the stack, and then compare against that var.
Here's a function + macro + define (I'll post to wiki after review from smarter people):
code:
/* Check if LoadRTFincluded is defined so that LoadRTF can't be included twice */
!ifndef LoadRTFincluded
/*
Defines used by LoadRTF
*/
!ifndef SF_RTF
!define SF_RTF 2
!endif
!ifndef EM_STREAMIN
!define EM_STREAMIN 1097
!endif
!ifndef EM_EXLIMITTEXT
!define EM_EXLIMITTEXT 1077
!endif
/*
LoadRTF Main Function
Inserted via macro for Installer vs Uninstaller
Loads an RTF file into a RichEdit20a control
Thanks to Anders for all the heavy work
Define/Macro/Functionfication and a CallbackN tweak by Animaether
Usage:
Push Path-to-RTF-file
Push HWND-of-RichEdit20A-control
Call LoadRTF
-or for uninstallers-
Call un.LoadRTF
*/
!macro LoadRTFfunc Un
Function ${Un}LoadRTF
; RichEdit20A.hwnd RTFilePath.string
Exch $0 ; $0 RTFilePath.string ; $0 = RichEdit20A.hwnd
Exch ; RTFilePath.string $0
Exch $1 ; $1 $0 ; $1 = RTFilePath.string
Push $2 ; $2 $1 $0 ; $2 : Callback address
Push $3 ; $3 $2 $1 $0 ; $3 : EDITSTREAM structure
Push $4 ; $4 $3 $2 $1 $0 ; $4 : callbackN identifier from System plugin to check against
Push $R0 ; $R0 $4 $3 $2 $1 $0 ; $R0 : Buffer that receives data from ReadFile()
Push $R1 ; $R1 $R0 $4 $3 $@ $1 $0 ; $R1 : Maximum number of bytes to read using ReadFile()
Push $R2 ; $R2 $R1 $R0 $4 $3 $@ $1 $0 ; $R2 : Number of bytes actually read using ReadFile()
SendMessage $0 ${EM_EXLIMITTEXT} 0 0x7fffffff
System::Get "(i, i .R0, i .R1, i .R2) iss"
Pop $2
System::Call "*(i 0, i 0, k r2) i .r3"
System::Call "user32::SendMessage(i r0, i ${EM_STREAMIN}, i ${SF_RTF}, i r3) i.s"
Pop $4
Push $4
ClearErrors
FileOpen $1 "$1" r ; $1 = RTFile.handle
_loop:
Pop $0 ; $0 = callbackN identifier from System plugin.
StrCmp $0 "$4" 0 _done ; check if System plugin's callbackN matches the stored callbackN
System::Call "kernel32::ReadFile(i $1, i $R0, i $R1, i $R2, i 0)"
Push 0 # callback's return value
System::Call "$2"
goto _loop
_done:
FileClose $1
System::Free $3
System::Free $2
; $R2 $R1 $R0 $4 $3 $2 $1 $0
Pop $R2 ; $R1 $R0 $4 $3 $2 $1 $0
Pop $R1 ; $R0 $4 $3 $2 $1 $0
Pop $R0 ; $4 $3 $2 $1 $0
Pop $4 ; $3 $2 $1 $0
Pop $3 ; $2 $1 $0
Pop $2 ; $1 $0
Pop $1 ; $0
Pop $0 ; -empty-
FunctionEnd
!macroend
!insertmacro LoadRTFfunc ""
!insertmacro LoadRTFfunc "un."
/*
LoadRTF Ease of use functions.
Simplifies usage of LoadRTF.
Usage:
${LoadRTF} "Path-to-RTF-file" HWND-of-RichEdit20A-control
-or for uninstallers-
${un.LoadRTF} "Path-to-RTF-file" HWND-of-RichEdit20A-control
*/
!macro LoadRTF file hwnd
Push "${file}"
Push ${hwnd}
Call LoadRTF
!macroend
!define LoadRTF `!insertmacro LoadRTF`
!macro un.LoadRTF file hwnd
Push "${file}"
Push ${hwnd}
Call un.LoadRTF
!macroend
!define un.LoadRTF `!insertmacro LoadRTF.un`
/* define LoadRTFincluded so that LoadRTF can't be included twice */
!define LoadRTFincluded
!endif
Usage is pretty simple. Presuming you have the above saved in "LoadRTF.nsh":
code:
!addplugindir "."
!addincludedir "."
!include "nsDialogs.nsh"
!include "winmessages.nsh"
!include "logiclib.nsh"
!include "MUI2.nsh"
!include "LoadRTF.nsh"
OutFile "test.exe"
var dialog
var hwnd
var null
Page custom null ; just for testing
Page custom test
Page custom null ; just for testing
Function .onInit
InitPluginsDir
FunctionEnd
var RichEditControl
Function test
nsDialogs::Create 1018
Pop $dialog
nsDialogs::CreateControl "RichEdit20A" \
"${DEFAULT_STYLES}|${WS_TABSTOP}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_READONLY}" \
"${WS_EX_WINDOWEDGE}|${WS_EX_CLIENTEDGE}" \
0 0 100% 100% ""
Pop $RichEditControl
SetOutPath "$PLUGINSDIR"
File "helloworld.rtf"
${LoadRTF} "$PLUGINSDIR\helloworld.rtf" $RichEditControl
nsDialogs::Show
FunctionEnd
Function null
nsDialogs::Create 1018
Pop $dialog
${NSD_CreateLabel} 0 0 100% 8% "Dummy page."
Pop $null
nsDialogs::Show
FunctionEnd
Section
SectionEnd
*crosses fingers*