Archive: Remember selections on second install


Remember selections on second install
I would like for my installer to store all the sections the user selected and have those be selected/unselected by default the next time the user runs the installer.

I've tried many different ways of doing this, from functions to macros, but I can't seem to get it to work.

Here is my approach so far: I read in the stored values from the registry (if they are there) in the .onInit function. Then I do a !define MUI_PAGE_CUSTOMFUNCTION_PRE right before the components page. There I (unsuccessfully) try to select or unselect sections based on the values I read in. Then in the .onInstSuccess function, I want to save off to the registry all the things the user selected on this install.

I also want to do the same thing for checking off a program to run on the MUI finish page (MUI_FINISHPAGE_RUN). I got good ideas from the dynamic finish page thread. http://forums.winamp.com/showthread....hreadid=177448
I can read in from the registry and set it, but I don't know how to detect what was selected and save it off.

Here is how I am currently trying to unselect sections:


!include "MUI.nsh"
!include "Sections.nsh"

...
!define MUI_PAGE_CUSTOMFUNCTION_PRE PreComponentsPage
!insertmacro MUI_PAGE_COMPONENTS
...

Function .onInit
ReadRegStr $A HKCU "Software\myprogram" "stringA"
ReadRegStr $B HKCU "Software\myprogram" "stringB"
...
FunctionEnd

Function PreComponentsPage
StrCmp $A "false" 0 +2
!insertmacro UnselectSection ${section1}
StrCmp $B "false" 0 +2
!insertmacro UnselectSection ${section2}
...
FunctionEnd


Can anyone give me some hints on how to do all this? I appreciate any help you can give.

According to the example, it seems ${section1} and ${section2} are not defined in the place you're using them. Put the PreComponentsPage function after the section definitions and it should work.


I already had those defined by the time PreComponentsPage comes along. I had the sections defined just after the pages and right before the functions. For brevity, I left that part out of my example.

I got it working now. I read in the nsis help file that "Compiler flag commands and SectionIn aren't instructions so jumping over them has no effect." I tried jumping to a label instead of an instruction. I changed my PreComponentsPage to:


Function PreComponentsPage
StrCmp $A "false" 0 a_done
!insertmacro UnselectSection ${section1}
a_done:
StrCmp $B "false" 0 b_done
!insertmacro UnselectSection ${section2}
b_done:


That got it :)

What exactly are macros? How are they different than functions? How come !insetmacro isn't an instruction?

Next part of the problem is how to detect what programs a user selected to run in the finish page - I use the MUI_FINISHPAGE_RUN macro and have 2 check boxes where the user select to run a program and/or a readme. Any ideas here?


"Remember selections on second install"

http://forums.winamp.com/attachment....postid=1553252

Compile: "WordFuncExample.nsi"


"Remember selections on second install"

http://forums.winamp.com/attachment...;postid=1553252

Compile: "WordFuncExample.nsi"
Thank you. Some cool functions in there :). I looked it over and I don't think I can use any of it since I have that part done now.

I'm able to set the checked status of items on the finish page using this stuff I borrowed from http://forums.winamp.com/showthread....hreadid=177448 I call this as the pre function of the finish page.

Function SetFinishPageOptions
StrCmp $Y "true" show_y hide_y
hide_y:
GetDlgItem $2 $MUI_HWND "1203" ;$MUI_HWND is defined for us by the MUI macros as the inner dialog hwnd
SendMessage $2 ${WM_LBUTTONDOWN} 0 0 ;uncheck it
SendMessage $2 ${WM_LBUTTONUP} 0 0 ;
ShowWindow $2 ${SW_HIDE}
show_y:
StrCmp $INS_README "true" show_readme hide_readme
hide_readme:
GetDlgItem $2 $MUI_HWND "1204" ;control id gathered from Spy++. (1200 + Field number - 1)
SendMessage $2 ${WM_LBUTTONDOWN} 0 0 ;uncheck it
SendMessage $2 ${WM_LBUTTONUP} 0 0 ;
ShowWindow $2 ${SW_HIDE}
show_readme:
FunctionEnd

Now I just need to find a way to get the checked status of these at the end of installation. In .onInstSuccess I tried
GetDlgItem $2 $MUI_HWND "1203"
GetDlgItem $3 $MUI_HWND "1204"
with no luck.

You need to use SendMessage:
GetDlgItem $2 $MUI_HWND "1203"
SendMessage $2 0x00F2 0 0 $R0

$R0 will be either 0 or 1

-Stu


Edit: Double post


I can't seem to get it to work. This code gives a 0 for $R0 whether the checkboxes are checked or not. What am I doing wrong?


Function .onInstSuccess
...
GetDlgItem $2 $MUI_HWND "1203"
SendMessage $2 0x00F2 0 0 $R0
MessageBox MB_ICONEXCLAMATION|MB_OK "$R0"
GetDlgItem $2 $MUI_HWND "1204"
SendMessage $2 0x00F2 0 0 $R0
MessageBox MB_ICONEXCLAMATION|MB_OK "$R0"
...


Is there any documentation or code on GetDlgItem or SendMessage? The info in the NSIS help file is pretty sparse.

MSDN has all the information you need about GetDlgItem and SendMessage.


Thanks, kichik. I looked over the info on MSDN and I have a better understanding of these now. I still can't figure out why it isn't working, however. Is SendMessage $2 0x00F2 0 0 $R0 the correct command to use? I have no idea what message 0x00F2 is and why we send it. Sorry if I'm being dense.


ah ha! The code afro uk posted was correct. I just needed to call it from the post finish page function (!define MUI_PAGE_CUSTOMFUNCTION_LEAVE function) instead of .onInstSuccess. I guess because by that time the window is gone and you can't send messages to it anymore :)

Thank you guys for your help :)


0xF2 is the id of the BM_GETSTATE message.


My define used is
!define BM_GETSTATE 0x00F2
but I simply put 0x00F2 (same as Kichick posted).

Use
!define BM_SETCHECK 0x00F1
to check a check-box.

-Stu