禁止一个组件组的父项的点击事件

优质
小牛编辑
136浏览
2023-12-01
当我们需要别人只能点选“原始英文版”或“简体中文版”中的其中一项时,我们通常会用到 !insertmacro StartRadioButtons 这类的宏来控制单选,但是在 NSIS 的例子中,它们的操控都是在父项的情况下实行的,当我们在子项的环境中实现时,问题出现了,当我们为用户设想时,如果用户点选了父项“界面语言”,会造成子项选择丢失或者反选,这就跟我们原来设想的单选意图完全背道而驰了,那么我们究竟要怎么做才能禁止用户的这种错误操作呢。如图:



而在整个 NSIS 文档中,我们并不能找到任何一个命令或参数来禁止一个 SectionGroup 的项目的可选性,也就是无论如何也没办法禁止用户错误操作了吗?

大家不要忘记了 NSIS 曾经给我们的提示:

SectionSetFlags

区段索引 区段标记设置区段标记。标记为 32 位整数。第一位(低位)代表该区段当前是否选中,第二位代表该区段是否是一个区段组(请不要修改这里除非你真的很了解),第三位代表该区段是否是一个区段组的结尾(同样,请不要修改),第四位代表该区段文字是否描黑显示,第五位代表该区段是否是只读,第六位代表区段组是否自动展开,第七位代表区段组是部分选定的,第八位是部分选定区段组切换内部使用,第九位是用来反映区段名称更改。如果指定了超出范围的区段则会放置一个错误的标记。

虽然 NSIS 一再强调,不要修改除非你真的很了解,不过既然我已经了解了,当然就会随便乱动了。

!include "MUI.nsh"
!include "UsefulLib.nsh"

OutFile "Setup.exe"

; 组件选择页面
!define MUI_COMPONENTSPAGE_NODESC
!define MUI_COMPONENTSPAGE_TEXT_TOP " "
ComponentText "" "选择游戏安装的版本:" "----------------------"
!insertmacro MUI_PAGE_COMPONENTS

Section "!主要程序" SEC01
SectionEnd

SubSection "界面语言" SEC0A
Section /o "原始英文版" SEC11
SectionEnd
Section "简体中文版" SEC12
SectionEnd
SubSectionEnd

SubSection "存档文件" SEC0B
Section /o "全英文球员名(锁定)" SEC21
SectionEnd
Section /o "全英文球员名(解锁)" SEC22
SectionEnd
Section "中日韩球员中文名(锁定)" SEC23
SectionEnd
Section /o "中日韩球员中文名(解锁)" SEC24
SectionEnd
SubSectionEnd

SubSection "解说版本" SEC0C
Section /o "英语解说" SEC31
SectionEnd
Section "中文解说" SEC32
SectionEnd
Section /o "日语解说" SEC33
SectionEnd
SubSectionEnd
; ------ 游戏组件选择界面结束 ------

; 区段组件描述

Function .onInit
SectionGetFlags "${SEC0A}" $R0 # <======= 添加,取原父项的标志值
IntOp $R0 $R0 + 15 # <======= 添加,加上 15,就会令父项变成只读
SectionSetFlags "${SEC0A}" $R0 # <======= 添加
SectionGetFlags "${SEC0B}" $R0 # <======= 添加
IntOp $R0 $R0 + 15 # <======= 添加
SectionSetFlags "${SEC0B}" $R0 # <======= 添加
SectionGetFlags "${SEC0C}" $R0 # <======= 添加
IntOp $R0 $R0 + 15 # <======= 添加
SectionSetFlags "${SEC0C}" $R0 # <======= 添加
SectionSetFlags ${SEC12} ${SF_SelectED} # <======= 添加,设置选中状态
SectionSetFlags ${SEC23} ${SF_SelectED} # <======= 添加
SectionSetFlags ${SEC32} ${SF_SelectED} # <======= 添加
StrCpy $1 ${SEC12} ; SEC12默认选中 # <======= 添加,
#####必须在 $1 中写入当前选中的项,因为在 .onSelChange 中是用来记录第一组的选中项目
StrCpy $2 ${SEC23} ; SEC23默认选中 # <======= 添加
StrCpy $3 ${SEC32} ; SEC32默认选中 # <======= 添加
FunctionEnd

;单选
Function .onSelChange
!insertmacro StartRadioButtons $1
!insertmacro RadioButton ${SEC11}
!insertmacro RadioButton ${SEC12}
!insertmacro EndRadioButtons
!insertmacro StartRadioButtons $2
!insertmacro RadioButton ${SEC21}
!insertmacro RadioButton ${SEC22}
!insertmacro RadioButton ${SEC23}
!insertmacro RadioButton ${SEC24}
!insertmacro EndRadioButtons
!insertmacro StartRadioButtons $3
!insertmacro RadioButton ${SEC31}
!insertmacro RadioButton ${SEC32}
!insertmacro RadioButton ${SEC33}
!insertmacro EndRadioButtons
FunctionEnd