NSIS - 如何在一个子节中实现三个相互排斥的部分
NSIS - How to implement three Mutually Exclusive Sections within a SubSection
我有一个简单的 NSIS 脚本,它基于我在 NSIS Mutually Exclusive Sections 上找到的以下源代码。我面临的问题是我无法实现三个相互排斥的部分而不是一个。
第 0 节是独立的。
对于第 1、2 和 3 部分,我需要让它们相互排斥。能够同时 select none 个或一个 selected。
如果您测试该示例,当您 select:
时它似乎运行良好
- 第 1 部分(#2 和 #3 未select编辑)
- 第 2 节(#1 和 #3 未select编辑)
- 第 3 节(#1 和 #2 未select编辑)
当您在完成第 3 部分 select 之后继续 select 选项然后转到 select 第 2 部分和第 1 部分时,问题就开始了。或者如果您尝试这样做随机 select 离子 select 离子被弄乱了。
我无法在 SubSection 中的三个部分之间实现这种互斥。谁能给我一些启发?
非常感谢。
谢谢,
这是我到目前为止修改的脚本:
# 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 [=10=]
SectionGetFlags ${sec1} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec1} [=10=]
SectionGetFlags ${sec2} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec2} [=10=]
SectionGetFlags ${sec3} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec3} [=10=]
Pop [=10=]
FunctionEnd
Function .onSelChange
Push [=10=]
${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} [=10=]
IntOp [=10=] [=10=] & ${SF_SELECTED}
IntCmp [=10=] ${SF_SELECTED} 0 Seldone Seldone
StrCpy $R9 ${sec1}
SectionGetFlags ${sec2} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec2} [=10=]
SectionGetFlags ${sec3} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec3} [=10=]
Goto Seldone
check_sec2:
SectionGetFlags ${sec2} [=10=]
IntOp [=10=] [=10=] & ${SF_SELECTED}
IntCmp [=10=] ${SF_SELECTED} 0 Seldone Seldone
StrCpy $R9 ${sec2}
SectionGetFlags ${sec1} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec1} [=10=]
SectionGetFlags ${sec3} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec3} [=10=]
check_sec3:
SectionGetFlags ${sec3} [=10=]
IntOp [=10=] [=10=] & ${SF_SELECTED}
IntCmp [=10=] ${SF_SELECTED} 0 Seldone Seldone
StrCpy $R9 ${sec3}
SectionGetFlags ${sec1} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec2} [=10=]
SectionGetFlags ${sec2} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec2} [=10=]
Goto check_sec1
Seldone:
${EndIf}
Pop [=10=]
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} [=10=] = -1 ${|} Return ${|} ; I don't care about InstType changes
${If} [=10=] < ${sec1}
${OrIf} [=10=] > ${sec3}
Return ; I don't care about other sections
${EndIf}
!macro SelectOnlyMe sid
${IfThen} [=10=] <> ${sid} ${|} !insertmacro UnselectSection ${sid} ${|}
!macroend
!insertmacro SelectOnlyMe ${sec1}
!insertmacro SelectOnlyMe ${sec2}
!insertmacro SelectOnlyMe ${sec3}
FunctionEnd
(如果您需要多组相互排斥的部分,您可以将 "if/orif" 范围检查作为辅助宏的一部分)
我有一个简单的 NSIS 脚本,它基于我在 NSIS Mutually Exclusive Sections 上找到的以下源代码。我面临的问题是我无法实现三个相互排斥的部分而不是一个。
第 0 节是独立的。
对于第 1、2 和 3 部分,我需要让它们相互排斥。能够同时 select none 个或一个 selected。
如果您测试该示例,当您 select:
时它似乎运行良好- 第 1 部分(#2 和 #3 未select编辑)
- 第 2 节(#1 和 #3 未select编辑)
- 第 3 节(#1 和 #2 未select编辑)
当您在完成第 3 部分 select 之后继续 select 选项然后转到 select 第 2 部分和第 1 部分时,问题就开始了。或者如果您尝试这样做随机 select 离子 select 离子被弄乱了。
我无法在 SubSection 中的三个部分之间实现这种互斥。谁能给我一些启发?
非常感谢。
谢谢,
这是我到目前为止修改的脚本:
# 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 [=10=]
SectionGetFlags ${sec1} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec1} [=10=]
SectionGetFlags ${sec2} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec2} [=10=]
SectionGetFlags ${sec3} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec3} [=10=]
Pop [=10=]
FunctionEnd
Function .onSelChange
Push [=10=]
${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} [=10=]
IntOp [=10=] [=10=] & ${SF_SELECTED}
IntCmp [=10=] ${SF_SELECTED} 0 Seldone Seldone
StrCpy $R9 ${sec1}
SectionGetFlags ${sec2} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec2} [=10=]
SectionGetFlags ${sec3} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec3} [=10=]
Goto Seldone
check_sec2:
SectionGetFlags ${sec2} [=10=]
IntOp [=10=] [=10=] & ${SF_SELECTED}
IntCmp [=10=] ${SF_SELECTED} 0 Seldone Seldone
StrCpy $R9 ${sec2}
SectionGetFlags ${sec1} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec1} [=10=]
SectionGetFlags ${sec3} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec3} [=10=]
check_sec3:
SectionGetFlags ${sec3} [=10=]
IntOp [=10=] [=10=] & ${SF_SELECTED}
IntCmp [=10=] ${SF_SELECTED} 0 Seldone Seldone
StrCpy $R9 ${sec3}
SectionGetFlags ${sec1} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec2} [=10=]
SectionGetFlags ${sec2} [=10=]
IntOp [=10=] [=10=] & ${SECTION_OFF}
SectionSetFlags ${sec2} [=10=]
Goto check_sec1
Seldone:
${EndIf}
Pop [=10=]
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} [=10=] = -1 ${|} Return ${|} ; I don't care about InstType changes
${If} [=10=] < ${sec1}
${OrIf} [=10=] > ${sec3}
Return ; I don't care about other sections
${EndIf}
!macro SelectOnlyMe sid
${IfThen} [=10=] <> ${sid} ${|} !insertmacro UnselectSection ${sid} ${|}
!macroend
!insertmacro SelectOnlyMe ${sec1}
!insertmacro SelectOnlyMe ${sec2}
!insertmacro SelectOnlyMe ${sec3}
FunctionEnd
(如果您需要多组相互排斥的部分,您可以将 "if/orif" 范围检查作为辅助宏的一部分)