holley 发表于 2024-2-7 19:59:06

【求助】二维数组的索引关联问题

本帖最后由 holley 于 2024-2-8 08:40 编辑

最近写一个小工具,卡在这了{:2_72:}
早上又回顾了一下,感觉我脑子一片浆糊的原因,在于自己对于数组、索引与函数调用的关系理解不深,导致越试越迷糊。
函数调用的是标签控件的ID
Func _CheckAndUpdateStatus($nLabelID, $sStatus, $nColor)
      GUICtrlSetData($nLabelID, $sStatus)
      GUICtrlSetColor($nLabelID, $nColor)
EndFunc   ;==>_CheckAndUpdateStatus
现在就是要对应刷新不同分组框内标签控件的ID,而这个ID在未使用分组框之前是通过顺序遍历数组得到的对应关系。
为什么现在分组框添加以后,我也分别做了必选和可选的索引数组,但函数却没有实时获取到标签的刷新了呢?
我到底是需要更新函数或参数还是要重新优化分组框内的数组遍历方式?
目前界面布局基本已经处理好了。

现在遇到的主要问题是:
未做分组框之前,采用遍历数组的方式,$aCheckboxes与$gLabel_Status是可以同步刷新状态的。
For $i = 0 To UBound($aSoftwareList) - 1
      $aCheckboxes[$i] = GUICtrlCreateCheckbox($aSoftwareList[$i], 10, 10 + ($i * 28), 100, 20)
      $gLabel_Status[$i] = GUICtrlCreateLabel("检测中...", 138, 13 + ($i * 28), 300, 20)
Next现在分组框添加后,反复折腾了几次,,索引状态同步不起来,函数刷新的$gLabel_Status不生效了{:2_80:}


可直接下载附件,看现成的脚本和ini配置。


脚本如下:
Global Const $sProductName = "常用插件安装器"
Global Const $sProductVersion = "xxx"
Global Const $sIniPath = @ScriptDir & "\runtime.ini"

$softwareCount = IniRead($sIniPath, "SoftwareList", "Count", "NotFound")
$MandatoryCount = IniRead($sIniPath, "SoftwareList", "MandatoryCount", "NotFound")
$OptionalCount = IniRead($sIniPath, "SoftwareList", "OptionalCount", "NotFound")

If $softwareCount = "NotFound" Or $softwareCount = 0 Or $MandatoryCount = "NotFound" Or $MandatoryCount = 0 Or $OptionalCount = "NotFound" Or $OptionalCount = 0 Then
      MsgBox(0, "Error", "INI配置文件中未找到软件数量,请修改!")
      Exit
EndIf

Global $aSoftwareList[$softwareCount]

For $i = 1 To $softwareCount
      $sSection = "Software" & $i
      $softwareName = IniRead($sIniPath, $sSection, "Name", "")
      $softwareURL = IniRead($sIniPath, $sSection, "URL", "")
      $softwareSaveAs = IniRead($sIniPath, $sSection, "SaveAs", "")
      $softwareParameters = IniRead($sIniPath, $sSection, "Parameters", "")
      $softwareOption = IniRead($sIniPath, $sSection, "Option", "")

      $aSoftwareList[$i - 1] = $softwareName
      $aSoftwareList[$i - 1] = $softwareURL
      $aSoftwareList[$i - 1] = @TempDir & "\" & $softwareSaveAs
      $aSoftwareList[$i - 1] = $softwareParameters
      $aSoftwareList[$i - 1] = $softwareOption
Next

Global $aMandatorySoftwareList[$MandatoryCount], $MandatoryIndex = 0
Global $aOptionalSoftwareList[$OptionalCount], $OptionalIndex = 0

For $i = 0 To $softwareCount - 1
      If $aSoftwareList[$i] = "0" Or $aSoftwareList[$i] = "" Then
                For $j = 0 To 4
                        $aMandatorySoftwareList[$MandatoryIndex][$j] = $aSoftwareList[$i][$j]
                Next
                $MandatoryIndex += 1
      Else
                For $j = 0 To 4
                        $aOptionalSoftwareList[$OptionalIndex][$j] = $aSoftwareList[$i][$j]
                Next
                $OptionalIndex += 1
      EndIf
Next

Global $aSoftwareNames[$softwareCount]
Global $aCheckboxes[$softwareCount]
Global $gLabel_Status[$softwareCount]

; 创建GUI
Local $iGUIWidth = 800
Local $iGroupWidth = ($iGUIWidth / 2) - 30
Local $iGroupStartY = 20
Local $iHeightPerItem = 30
Local $iSpacing = 10
Local $iGroupPadding = 40

Local $iButtonHeight = 35
Local $iButtonWidth = 155
Local $iButtonSpacing = -45
Local $iButtonPadding = 20

Local $iGroupHeightMandatory = $iHeightPerItem * $MandatoryCount + ($MandatoryCount - 1) * $iSpacing + $iGroupPadding
Local $iGroupHeightOptional = $iHeightPerItem * $OptionalCount + ($OptionalCount - 1) * $iSpacing + $iGroupPadding
Local $iGroupStartY_Optional = $iGroupStartY + $iGroupHeightMandatory + $iSpacing
Local $iMaxGroupHeight = ($iGroupHeightMandatory > $iGroupHeightOptional) ? $iGroupHeightMandatory : $iGroupHeightOptional
Local $iGUIHeight = $iGroupStartY + $iGroupHeightMandatory + $iGroupHeightOptional + $iButtonHeight + $iButtonSpacing + $iButtonPadding

$hGUI = GUICreate($sProductName & " - " & $sProductVersion, $iGUIWidth, $iGUIHeight, -1, -1, $WS_SYSMENU)

Local $iCheckboxWidth = $iGroupWidth - 248
Local $iCheckboxHeight = 20
Local $iLabelWidth = $iCheckboxWidth + 60
Local $iLabelHeight = 20
Global $aMandatoryCheckboxes[$MandatoryCount]
Global $gMandatoryLabel_Status[$MandatoryCount]
Global $aOptionalCheckboxes[$OptionalCount]
Global $gOptionalLabel_Status[$OptionalCount]


$gGroup_Mandatory = GUICtrlCreateGroup("必选组件", 20, $iGroupStartY, $iGroupWidth, $iGroupHeightMandatory)
For $i = 0 To $MandatoryCount - 1
      Local $iCheckboxTop = $iGroupStartY + 20 + $i * ($iHeightPerItem + $iSpacing)
      Local $softwareName = $aMandatorySoftwareList[$i]
      $aMandatoryCheckboxes[$i] = GUICtrlCreateCheckbox($softwareName, 40, $iCheckboxTop, $iCheckboxWidth, $iCheckboxHeight)
      $gMandatoryLabel_Status[$i] = GUICtrlCreateLabel("检测中...", 180, $iCheckboxTop + 3, $iLabelWidth, $iLabelHeight)
Next

GUICtrlCreateGroup("", -99, -99, 1, 1)

$gGroup_Optional = GUICtrlCreateGroup("可选组件", 20 + $iGroupWidth + 20, $iGroupStartY, $iGroupWidth, $iGroupHeightOptional)
For $i = 0 To $OptionalCount - 1
      Local $iCheckboxTop = $iGroupStartY + 20 + $i * ($iHeightPerItem + $iSpacing)
      Local $softwareName = $aOptionalSoftwareList[$i]
      $aOptionalCheckboxes[$i] = GUICtrlCreateCheckbox($softwareName, 40 + $iGroupWidth + 20, $iCheckboxTop, $iCheckboxWidth, $iCheckboxHeight)
      $gOptionalLabel_Status[$i] = GUICtrlCreateLabel("检测中...", 180 + $iGroupWidth + 20, $iCheckboxTop + 3, $iLabelWidth, $iLabelHeight)
Next

GUICtrlCreateGroup("", -99, -99, 1, 1)

Local $iButtonY = $iGUIHeight - $iButtonHeight * 2 - $iButtonPadding * 2
$gButton_Install = GUICtrlCreateButton("开始安装", ($iGUIWidth / 2) - 180, $iButtonY, $iButtonWidth, $iButtonHeight)
$gButton_Cancel = GUICtrlCreateButton("取消", ($iGUIWidth / 2) + 32, $iButtonY, $iButtonWidth, $iButtonHeight)
Global $gCancelled = False

GUISetState(@SW_SHOW)
Sleep(500)

If _CheckOAPlugin() Then
      _CheckAndUpdateStatus($gLabel_Status, "新OA插件已安装", 0x008000)
      GUICtrlSetState($aCheckboxes, $GUI_UNCHECKED)
Else
      _CheckAndUpdateStatus($gLabel_Status, "新OA插件未安装", 0xFF0000)
      GUICtrlSetState($aCheckboxes, $GUI_CHECKED)
EndIf
Sleep(500)
_CheckOFD()
Sleep(500)

Global $aPIDs =
; 处理GUI消息
While 1
      Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                        ExitLoop
                Case $gButton_Install
                        GUICtrlSetData($gButton_Install, "正在安装请稍候...")
                        GUICtrlSetState($gButton_Install, $GUI_DISABLE)
                        For $i = 0 To UBound($aSoftwareList) - 1
                              If GUICtrlRead($aCheckboxes[$i]) = $GUI_CHECKED Then
                                        _DownloadAndInstall($i)
                                        Sleep(100)
                              EndIf
                        Next
                Case $gButton_Cancel
                        For $i = 0 To UBound($aPIDs) - 1
                              If $aPIDs[$i] <> 0 And ProcessExists($aPIDs[$i]) Then
                                        ProcessClose($aPIDs[$i])
                              EndIf
                        Next
                        Exit
      EndSwitch
      Sleep(100)
WEnd
GUIDelete()
Exit
Func _DownloadAndInstall($nSoftwareIndex)
      Local $sSoftwareName = $aSoftwareList[$nSoftwareIndex]
      Local $sDownloadURL = $aSoftwareList[$nSoftwareIndex]
      Local $sSavePath = $aSoftwareList[$nSoftwareIndex]
      Local $sInstallParams = $aSoftwareList[$nSoftwareIndex]

      _CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "下载中,请稍候...", 0x000000)

      Local $hDownload = InetGet($sDownloadURL, $sSavePath, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
      If @error Then
                _CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "下载失败", 0x000000)
                GUICtrlSetData($gButton_Install, "请重试!")
                GUICtrlSetState($gButton_Install, $GUI_ENABLE)
                Return
      EndIf

      Do
                Sleep(250)
                _CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "下载 " & $aSoftwareList[$i] & "... " & Round(InetGetInfo($hDownload, 0) / 1024) & " KB 已下载", 0x000000)
                If GUIGetMsg() = $gButton_Cancel Then
                        $gCancelled = True
                        InetClose($hDownload)
                        _CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "下载已取消", 0xFF0000)
                        Return
                EndIf
                Sleep(100)
      Until InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE) Or $gCancelled
      If $gCancelled Then Return
      _CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "安装中,请勿操作键鼠...", 0x0000FF)

      Local $sInstallCmd = '"' & $sSavePath & '" ' & $sInstallParams
      $aPIDs[$nSoftwareIndex] = Run(@ComSpec & " /c " & $sInstallCmd, "", @SW_HIDE)

      If $aPIDs[$nSoftwareIndex] = 0 Then
                _CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "安装启动失败", 0xFF0000)
                Return
      EndIf

      While ProcessExists($aPIDs[$nSoftwareIndex])
                Sleep(100)
                If GUIGetMsg() = $gButton_Cancel Then
                        ProcessClose($aPIDs[$nSoftwareIndex])
                        _CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "安装已取消", 0xFF0000)
                        Return
                EndIf
      WEnd

      If @error Then
                _CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "安装失败", 0xFF0000)
      Else
                _CheckAndUpdateStatus($gLabel_Status[$nSoftwareIndex], "安装完成", 0x008000)
                GUICtrlSetState($aCheckboxes[$nSoftwareIndex], $GUI_UNCHECKED)
                If FileExists($sSavePath) Then
                        FileDelete($sSavePath)
                EndIf
      EndIf

      Local $bAllDone = True
      For $i = 0 To UBound($aSoftwareList) - 1
                If ProcessExists($aPIDs[$i]) Then
                        $bAllDone = False
                        ExitLoop
                EndIf
      Next
      If $bAllDone Then
                GUICtrlSetData($gButton_Install, "开始安装")
                GUICtrlSetState($gButton_Install, $GUI_ENABLE)
      EndIf

EndFunc   ;==>_DownloadAndInstall

Func _CheckOAPlugin()
      Local $i, $sKey
      Local $sRegPath64 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
      Local $sRegPath32 = "HKLM32\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"

      For $i = 1 To 2
                Local $sRegPath = ($i == 1) ? $sRegPath64 : $sRegPath32
                Local $j = 1

                While 1
                        $sKey = RegEnumKey($sRegPath, $j)
                        If @error Then ExitLoop
                        If $sKey = "{6694F1FD-528D-49C5-BCE1-4B1CE14A8D36}_is1" Then
                              Return True
                        EndIf
                        $j += 1
                WEnd
      Next
      Return False
EndFunc   ;==>_CheckOAPlugin

Func _CheckOFD()
      Local $sKey
      Local $sRegPath64 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
      Local $sRegPath32 = "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"

      If _RegKeyExists($sRegPath64, "增值税电子发票阅读器") Then
                _CheckAndUpdateStatus($gLabel_Status, "OFD阅读器已安装", 0x008000)
                GUICtrlSetState($aCheckboxes, $GUI_UNCHECKED)
      ElseIf _RegKeyExists($sRegPath32, "增值税电子发票阅读器") Then

                _CheckAndUpdateStatus($gLabel_Status, "OFD阅读器已安装", 0x008000)
                GUICtrlSetState($aCheckboxes, $GUI_UNCHECKED)
      Else
                _CheckAndUpdateStatus($gLabel_Status, "OFD阅读器未安装", 0xFF0000)
                GUICtrlSetState($aCheckboxes, $GUI_CHECKED)
      EndIf

EndFunc   ;==>_CheckOFD


Func _RegKeyExists($sRegPath, $sKeyToCheck)
      Local $i = 1
      While 1
                Local $sKey = RegEnumKey($sRegPath, $i)
                If @error Then ExitLoop
                If $sKey = $sKeyToCheck Then
                        Return True
                EndIf
                $i += 1
      WEnd
      Return False
EndFunc   ;==>_RegKeyExists


Func _CheckAndUpdateStatus($nLabelID, $sStatus, $nColor)
      GUICtrlSetData($nLabelID, $sStatus)
      GUICtrlSetColor($nLabelID, $nColor)
EndFunc   ;==>_CheckAndUpdateStatusini配置文件:

Count=6
MandatoryCount=2
OptionalCount=4


Name=Flash插件
URL=http://xxx.exe
SaveAs=Flash.exe
Parameters=
Option=1


Name=新OA插件
URL=http://xxx.msi
SaveAs=OA.msi
Parameters=/qb /norestart
Option=0


Name=OFD阅读器
URL=http://xxx.exe
SaveAs=OFD.exe
Parameters=/NCRC /S
Option=1


Name=OFD阅读器4
URL=http://xxx.exe
SaveAs=OFD.exe
Parameters=/NCRC /S
Option=1


Name=OFD阅读器5
URL=http://xxx.exe
SaveAs=OFD.exe
Parameters=/NCRC /S
Option=0


Name=OFD阅读器6
URL=http://xxx.exe
SaveAs=OFD.exe
Parameters=/NCRC /S
Option=1






afan 发表于 2024-2-15 10:07:48

再次提醒:论 精简(可运行可复现)提问代码的重要性
页: [1]
查看完整版本: 【求助】二维数组的索引关联问题