NSIS-如何在一个小节中实现三个相互排斥的部分

NSIS-如何在一个小节中实现三个相互排斥的部分,nsis,Nsis,我有一个简单的NSIS脚本,它基于我在上找到的以下源代码:。我面临的问题是,我无法实现三个相互排斥的部分,而不是一个 第0节是独立的 对于第1、2和3节,我需要使它们相互排斥。能够不选择任何一个或同时只选择一个 如果您测试该示例,则选择以下选项时,该示例似乎运行良好: 第1、2和3节未选中 第2节1和第3节未选中 第3节1和2未选中 选择第3节后,如果继续选择选项,然后转到选择第2节和第1节,则会出现问题。或者,如果你试图做随机选择的选择是混乱的 我无法在一个小节的三个部分之间实现这一相互排斥的

我有一个简单的NSIS脚本,它基于我在上找到的以下源代码:。我面临的问题是,我无法实现三个相互排斥的部分,而不是一个

第0节是独立的

对于第1、2和3节,我需要使它们相互排斥。能够不选择任何一个或同时只选择一个

如果您测试该示例,则选择以下选项时,该示例似乎运行良好:

第1、2和3节未选中 第2节1和第3节未选中 第3节1和2未选中 选择第3节后,如果继续选择选项,然后转到选择第2节和第1节,则会出现问题。或者,如果你试图做随机选择的选择是混乱的

我无法在一个小节的三个部分之间实现这一相互排斥的功能。有人能告诉我这件事吗

非常感谢

谢谢

以下是我迄今为止修改过的脚本:

# Example to control section selection.
# It allows only one of three sections to be selected at any
# given time, but unlike one-section, it allows non of them 
# to be selected as well.
#

!include Sections.nsh
!include LogicLib.nsh

Name example
OutFile "mutually exclusive.exe"

ComponentText "please choose zero or one but the default"

SubSection /e "Test" SSEC00
    Section /o "Test Sec 0" sec0
    SectionEnd

    Section /o "#2 and #3 unselected" sec1
    SectionEnd

    Section /o "#1 and #3 unselected" sec2
    SectionEnd

    Section /o "#1 and #2 unselected" sec3
    SectionEnd
SubSectionEnd

Function .onInit
  Push $0

  SectionGetFlags ${sec1} $0
  IntOp $0 $0 & ${SECTION_OFF}
  SectionSetFlags ${sec1} $0

  SectionGetFlags ${sec2} $0
  IntOp $0 $0 & ${SECTION_OFF}
  SectionSetFlags ${sec2} $0

  SectionGetFlags ${sec3} $0
  IntOp $0 $0 & ${SECTION_OFF}
  SectionSetFlags ${sec3} $0

  Pop $0
FunctionEnd

Function .onSelChange
    Push $0

    ${If} ${SectionIsSelected} ${sec1}
    ${OrIf} ${SectionIsSelected} ${sec2}
    ${OrIf} ${SectionIsSelected} ${sec3}

        StrCmp $R9 ${sec1} check_sec2  # If last selection was sec1 goto check_sec2
        StrCmp $R9 ${sec2} check_sec3  # If last selection was sec2 goto check_sec3
        StrCmp $R9 ${sec3} check_sec1

        check_sec1:

        SectionGetFlags ${sec1} $0
        IntOp $0 $0 & ${SF_SELECTED}
        IntCmp $0 ${SF_SELECTED} 0 Seldone Seldone

        StrCpy $R9 ${sec1}
        SectionGetFlags ${sec2} $0
        IntOp $0 $0 & ${SECTION_OFF}
        SectionSetFlags ${sec2} $0

        SectionGetFlags ${sec3} $0
        IntOp $0 $0 & ${SECTION_OFF}
        SectionSetFlags ${sec3} $0
        Goto Seldone

        check_sec2:

        SectionGetFlags ${sec2} $0
        IntOp $0 $0 & ${SF_SELECTED}
        IntCmp $0 ${SF_SELECTED} 0 Seldone Seldone

        StrCpy $R9 ${sec2}
        SectionGetFlags ${sec1} $0
        IntOp $0 $0 & ${SECTION_OFF}
        SectionSetFlags ${sec1} $0

        SectionGetFlags ${sec3} $0
        IntOp $0 $0 & ${SECTION_OFF}
        SectionSetFlags ${sec3} $0

        check_sec3:

        SectionGetFlags ${sec3} $0
        IntOp $0 $0 & ${SF_SELECTED}
        IntCmp $0 ${SF_SELECTED} 0 Seldone Seldone

        StrCpy $R9 ${sec3}
          SectionGetFlags ${sec1} $0
          IntOp $0 $0 & ${SECTION_OFF}
          SectionSetFlags ${sec2} $0

          SectionGetFlags ${sec2} $0
          IntOp $0 $0 & ${SECTION_OFF}
          SectionSetFlags ${sec2} $0

        Goto check_sec1

        Seldone:

    ${EndIf}

    Pop $0
FunctionEnd

在NSIS v3+中,当调用.onSelChange时,已更改节的节id存储在$0中,这使得更容易获得正确的逻辑:

!include Sections.nsh
!include LogicLib.nsh

ComponentText "please choose zero or one but the default"

SubSection /e "Test" SSEC00
    Section /o "Test Sec 0" sec0
    SectionEnd

    Section /o "#2 and #3 unselected" sec1
    SectionEnd

    Section /o "#1 and #3 unselected" sec2
    SectionEnd

    Section /o "#1 and #2 unselected" sec3
    SectionEnd
SubSectionEnd

Page Components
Page InstFiles

Function .onSelChange
${IfThen} $0 = -1 ${|} Return ${|} ; I don't care about InstType changes
${If} $0 < ${sec1}
${OrIf} $0 > ${sec3}
    Return ; I don't care about other sections
${EndIf}

!macro SelectOnlyMe sid
${IfThen} $0 <> ${sid} ${|} !insertmacro UnselectSection ${sid} ${|}
!macroend

!insertmacro SelectOnlyMe ${sec1}
!insertmacro SelectOnlyMe ${sec2}
!insertmacro SelectOnlyMe ${sec3}
FunctionEnd

如果您需要多组互斥部分,您可以将If/orif范围检查改为helper宏的一部分

我建议您使用sections.nsh中的helper宏,而不是直接调用SectionSetFlags。谢谢。它就像一个符咒!我不知道更改分区的$0存储分区id。我被这种简单的行为困住了。再次感谢。测试完这段代码后,我发现了一个小错误。选择子部分时,所有复选框均显示为选中。我已经能够修复这个问题,添加以下代码来取消选择最后2个部分,并且只选择第0部分和第1部分:${If}$0==${SSEC00}!insertmacro取消选择节${sec2}!insertmacro UnselectSection${sec3}${EndIf}对不起,我忘记了组。