Archive: Components page and modern.bmp


Components page and modern.bmp
Hello,

I was wondering when each icon (for checkbox, see modern.bmp) are used.

I know that if you put a section to RO (with SectionIn). It will used the last icon in the modern.bmp.

Yet when using ButtonEvent plugin and changing the EnableWindow (to disable it), the icon of other section (not ROed in their section) does not change to a *disabled* state.

Is this normal?

Here is the problem:
http://img123.imageshack.us/my.php?image=testya6.jpg


Please attach the code that you are using to change the section flag.

Stu



;-------------------------------------
; Component page, shows all sections
!define MUI_PAGE_CUSTOMFUNCTION_Show Component_Show

#needed to reinitialize variable!
!define MUI_PAGE_CUSTOMFUNCTION_Pre Component_Leave

!define MUI_PAGE_CUSTOMFUNCTION_Leave Component_Leave
!insertmacro MUI_PAGE_COMPONENTS

var SectionSECDotNetFlags
var SectionSECMatlabFlags

Function Component_Leave

# Unload the plugin.
# If we don't do this, the DLL file remains
# locked and cannot be deleted.
ButtonEvent::Unload

FunctionEnd

Function Component_Show
MessageBox MB_ICONINFORMATION|MB_OK "SHOW"

# Create event handler for our Components page button.
GetFunctionAddress $R0 Component_Modification
ButtonEvent::AddEventHandler /NOUNLOAD 1200 $R0
StrCpy $DefaultCheckBox "1"

# Set Text
FindWindow $R0 "#32770" "" $HWNDPARENT
GetDlgItem $R1 $R0 1200

SendMessage $R1 ${WM_SETTEXT} 0 'STR:$(COMPONENT_OVERRIDE_DEFAULT)'
SendMessage $R1 ${BM_SETCHECK} $DefaultCheckBox 0

Call UpdateSectionBox

FunctionEnd

Function Component_Modification

MessageBox MB_ICONINFORMATION|MB_OK "Modification..."


# Swap Values of Checkbox
${If} $DefaultCheckBox == 1
Strcpy $DefaultCheckBox "0"
${Else}
StrCpy $DefaultCheckBox "1"
${EndIf}

# Has user checked the check box ?
FindWindow $R0 "#32770" "" $HWNDPARENT
GetDlgItem $R1 $R0 1200

SendMessage $R1 ${BM_SETCHECK} $DefaultCheckBox 0


Call UpdateSectionBox



FunctionEnd


Function UpdateSectionBox
var /GLOBAL SectionTempDotNet
var /GLOBAL SectionTempMatlab

FindWindow $R0 "#32770" "" $HWNDPARENT

SectionGetFlags ${SECDotNet} $SectionTempDotNet
SectionGetFlags ${SECMatlab} $SectionTempMatlab

SectionSetFlags ${SECDotNet} $SectionSECDotNetFlags
SectionSetFlags ${SECMatlab} $SectionSECMatlabFlags

${If} $DefaultCheckBox == 1
GetDlgItem $R1 $R0 1032 #1032 = TreeBox
EnableWindow $R1 0
${else}

GetDlgItem $R1 $R0 1032 #1032 = TreeBox
EnableWindow $R1 1
${EndIf}

MessageBox MB_ICONINFORMATION|MB_OK "Temp Flags (.Net\Matlab) = $SectionTempDotNet $SectionTempMatlab \n Real Flags (.Net\Matlab) = $SectionSECDotNetFlags $SectionSECMatlabFlags\n"



StrCpy $SectionSECDotNetFlags $SectionTempDotNet
StrCpy $SectionSECMatlabFlags $SectionTempMatlab


FunctionEnd

Forgot a piece of it... In the UpdateSectionBox


${If} $DefaultCheckBox == 1
IntOp $R4 ${SECTION_OFF} - ${SF_BOLD}
SectionSetFlags ${SECDotNet} $R4
SectionSetFlags ${SECMatlab} $R4
GetDlgItem $R1 $R0 1032 #1032 = TreeBox
EnableWindow $R1 0
${else}

GetDlgItem $R1 $R0 1032 #1032 = TreeBox
EnableWindow $R1 1
${EndIf}
}

Not quite sure what the problem is.
If I put this in the page leave function then call Abort, all works fine:

SectionGetFlags 0 $R0
IntOp $R0 $R0 | ${SF_SELECTED}
IntOp $R0 $R0 | ${SF_RO}
SectionSetFlags 0 $R0

To unset these flags, first check that they are set using the & operator and then use the ^ operator to unset them.

Stu


After much testing here are my conclusions:
===============
- The modifications in the PRE functions works fine.
- The modifications in the Show function work fine.

When using the ButtonEvent handler, I can modify the Flags (the setup program understands the flag modification) but no trigger to update the GUI (remove check) is called.

Is this a bug?


I wasn't quite sure what you wanted the check box to do, but see this script I made.

The trick is to modify the components on page leave.

Stu


It is exactly what I did after your reply. Works great..

Seems the Leave function calls an update of the GUI when we do abort.

I don't know if having a function to update the current GUI might become handy for futur installer development.


That would be handy indeed. Something that does exactly what we have used but without the use of a temporary boolean variable and the SendMessage.

Perhaps an addition to the ButtonEvent plug-in. I shall try this out.

Stu


I have uploaded a new version.

1. Use /NOTIFY instead of passing the function address.
2. In your page leave function use ButtonEvent::WhichButtonId /NOUNLOAD followed by Pop $Var which you then check the value of. $Var will equal 1200 or 0 otherwise.

ButtonEvent::WhichButtonId will also work in functions tied to buttons, in case one wants to use the same function for more than one button.

Finally, I have added ButtonEvent::UnsetEventHandler to free an event handler slot (although this isn't necessary unless you need >8 buttons.

Stu


I think the DLL in the .Zip at (http://nsis.sourceforge.net/File:ButtonEvent.zip) is not the correct version.

I tried your example NSI and even when putting a MessageBox command in the leave, it never gets triggered.

File Info of DLL:
=================
Size: 4,096 bytes
Date of Modification: August 1, 2007, 4:14:22 PM
=================


Sorry you were right. I fixed that exact issue about 30 minutes later but didn't copy the new DLL or source code into the Zip.

Uploaded again.

Stu


Works now...

Found a bug tought:
=========================
Take your Examples\ButtonEvent\ButtonEventNotify.nsi script.

Compile and Run
-> Click Next
-> Click I Agree
-> Click on your "I like cheese" button (it works).
-> click on Back
-> click on I Agree
-> Click on your "I like cheese" button (it doesn't work!).

I had this problem and thw workaround is to create a Pre function and unload the plugin. Funny part is if I try to unset the handler for ID 1200, it crashes...


Function Component_Pre
ButtonEvent::Unload
#ButtonEvent::UnsetEventHandler 1200
Strcpy $DefaultCheckBox "0"
Call DefaultCheckBox_Modification
FunctionEnd


Also, it would be good to put in a readme to not do the following:

Function Component_Leave
var /GLOBAL CheckBoxChanged

# If CheckboxDefault Event
ButtonEvent::WhichButtonId /NOUNLOAD
Pop $CheckBoxChanged


${If} $CheckBoxChanged == 1200
Call DefaultCheckBox_Modification
Abort
${Else}

# Unloading the ButtonEvent plugin here
# makes the installer crash!
ButtonEvent::Unload

${EndIf}

FunctionEnd

In the readme for ::Unload
This must be called once in the .onGUIEnd function.

It will crash anywhere else because the plug-in effectively takes control of the dialogs so if you unload the plug-in while the dialogs are visible it is going to crash.

I shall look into the other problem now.

Stu


This works but it is not finalised. I shall post here when it is complete (have some questions for kichik).

Stu


I have now uploaded the new version.
http://nsis.sourceforge.net/File:ButtonEvent.zip

Stu