Jump to content
Arik

ComboBox with INI - data wrong

Recommended Posts

Arik

Hi everyone,

I have a long script with a big INI file, that has a small problem. So I wrote a new small script with a small INI file just to represent the problem in the big one.

Global Const $GUI_EVENT_CLOSE = -3
$IniFile = @ScriptDir & "\Test.ini"
$Sections = IniReadSectionNames($IniFile)
$Entries = ""

GUICreate("Test Program", 190, 40)

$ComboBox = GUICtrlCreateCombo("Please select an application...", 10, 10, 170)

For $i = 1 To $Sections[0]
   $Section = IniReadSection($IniFile, $Sections[$i])
   $AppName = $Section[1][1]
   If $Entries = "" Then
      $Entries &= $AppName
   Else
      $Entries &= "|" & $AppName
   EndIf
Next
GUICtrlSetData($ComboBox, $Entries)

GUISetState()

While 1
   Switch GUIGetMsg()
      Case $ComboBox
         If GUICtrlRead($ComboBox) <> "Please select an application..." Then
            For $i = 1 To $Sections[0]
               $Section = IniReadSection($IniFile, $Sections[$i])
               $AppName = $Section[1][1]
               If GUICtrlRead($ComboBox) = $AppName Then
                  $AppName = $Section[1][1]
                  $TargetFolder = $Section[2][1]
                  $AppID = $Sections[$i]
                  $Version = $Section[3][1]
               EndIf
            Next
            MsgBox(0,$AppID, "Appliaction: " & $AppName & @CRLF & "Target Folder: " & $TargetFolder & @CRLF & "Version: " & $Version)
         EndIf
      Case $GUI_EVENT_CLOSE
         Exit
   EndSwitch
WEnd

And here is the INI file:

[AppID1]
AppName=Mozilla Firefox
TargetFolder=C:\Browsers\Firefox
Version=35.0.1

[AppID2]
AppName=Driver Genius
TargetFolder=C:\Utilities\Driver Genius
Version=11.0.0.1128

[AppID3]
AppName=Icon Viewer
TargetFolder=C:\Utilities\Icon Viewer
Version=3.02

[AppID4]
AppName=Symantec Endpoint Protection
TargetFolder=C:\AntiVirus\Endpoint Protection
Version=12.1

The problem is that no matter what item I choose from the combobox, the AppName variable always contains the last AppName in the INI file. The other variables are fine.

Please can someone explain what's wrong here?

Note: In my old script the data in AppName was the section name, but it eventually posed a problem. Therefore, I must keep the section names as they are at the new script.

Thanks.

Edited by Arik

Share this post


Link to post
Share on other sites
Melba23

Arik,

This amended version seems to work quite well:

#include <GUIConstantsEx.au3>
#include <GuiComboBox.au3>

$IniFile = @ScriptDir & "\Test.ini"
$Sections = IniReadSectionNames($IniFile)
$Entries = ""
For $i = 1 To $Sections[0]
    $Entries &= "|" & IniRead($IniFile, $Sections[$i], "AppName", "Error") ; A leading "|" just replaces the current content so no need to exclude it from the first entry
Next

GUICreate("Test Program", 190, 40)

$ComboBox = GUICtrlCreateCombo("", 10, 10, 170, 20, $CBS_DROPDOWNLIST)
GUICtrlSetData($ComboBox, $Entries)
_GUICtrlComboBox_SetCueBanner($ComboBox, "Please select an application...") ; This way you do not get the text as an item in the combo

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $ComboBox
            $AppName = GUICtrlRead($ComboBox)
            For $i = 1 To $Sections[0]
                If $AppName = IniRead($IniFile, $Sections[$i], "AppName", "Error") Then
                    $TargetFolder = IniRead($IniFile, $Sections[$i], "TargetFolder", "Error")
                    $Version = IniRead($IniFile, $Sections[$i], "Version", "Error")
                    $AppID = $i
                    ; No point in looking any further
                    ExitLoop
                EndIf
            Next
            MsgBox(0, $AppID, "Appliaction: " & $AppName & @CRLF & "Target Folder: " & $TargetFolder & @CRLF & "Version: " & $Version)
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

I made one or two other changes as well - see the comments to understand why. Please ask if you have any questions.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
Melba23

Arik,

This amended version seems to work quite well:

#include <GUIConstantsEx.au3>
#include <GuiComboBox.au3>

$IniFile = @ScriptDir & "\Test.ini"
$Sections = IniReadSectionNames($IniFile)
$Entries = ""
For $i = 1 To $Sections[0]
    $Entries &= "|" & IniRead($IniFile, $Sections[$i], "AppName", "Error") ; A leading "|" just replaces the current content so no need to exclude it from the first entry
Next

GUICreate("Test Program", 190, 40)

$ComboBox = GUICtrlCreateCombo("", 10, 10, 170, 20, $CBS_DROPDOWNLIST)
GUICtrlSetData($ComboBox, $Entries)
_GUICtrlComboBox_SetCueBanner($ComboBox, "Please select an application...") ; This way you do not get the text as an item in the combo

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $ComboBox
            $AppName = GUICtrlRead($ComboBox)
            For $i = 1 To $Sections[0]
                If $AppName = IniRead($IniFile, $Sections[$i], "AppName", "Error") Then
                    $TargetFolder = IniRead($IniFile, $Sections[$i], "TargetFolder", "Error")
                    $Version = IniRead($IniFile, $Sections[$i], "Version", "Error")
                    $AppID = $i
                    ; No point in looking any further
                    ExitLoop
                EndIf
            Next
            MsgBox(0, $AppID, "Appliaction: " & $AppName & @CRLF & "Target Folder: " & $TargetFolder & @CRLF & "Version: " & $Version)
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

I made one or two other changes as well - see the comments to understand why. Please ask if you have any questions.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
Arik

Thanks M23.

Didn't test it yet, but as I can see in order to get each variable in the loop you re-read the INI file. If so, this will lead to a big slowdown when doing it with a big INI, especially when selecting the last item in the combobox. My big INI has over a 1500 sections (instead of 4) and 15 inside variables (instead of 3). Am I right?

Edited by Arik

Share this post


Link to post
Share on other sites
Melba23

Arik,

I have no idea if it would be slower or faster - although I suspect that the difference would be minor. I suggest you run some comparisons between the code I posted above and this new version:

#include <GUIConstantsEx.au3>
#include <GuiComboBox.au3>
#include <Array.au3>

$sIniFile = @ScriptDir & "\Test.ini"
$aSections = IniReadSectionNames($sIniFile)
_ArrayColInsert($aSections, 1) ; Make into 2D array
$sEntries = ""
For $i = 1 To $aSections[0][0]
    ; Add app name alongside section name
    $aSections[$i][1] = IniRead($sIniFile, $aSections[$i][0], "AppName", "Error")
    $sEntries &= "|" & $aSections[$i][1] ; A leading "|" just replaces the current content so no need to exclude it from the first entry
Next

GUICreate("Test Program", 190, 40)

$cComboBox = GUICtrlCreateCombo("", 10, 10, 170, 20, $CBS_DROPDOWNLIST)
GUICtrlSetData($cComboBox, $sEntries)
_GUICtrlComboBox_SetCueBanner($cComboBox, "Please select an application...") ; This way you do not get the text as an item in the combo

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $cComboBox
            $sAppName = GUICtrlRead($cComboBox)
            For $i = 1 To $aSections[0][0]
                If $sAppName = $aSections[$i][1] Then
                    $aSectionRead = IniReadSection($sIniFile, $aSections[$i][0]) ; Read whole section in one go
                    $sTargetFolder = $aSectionRead[_ArraySearch($aSectionRead, "TargetFolder")][1] ; Could replace _ArraySearch with hardcoded index if always in same order
                    $sVersion = $aSectionRead[_ArraySearch($aSectionRead, "Version")][1]
                    $iAppID = $i
                    ; No point in looking any further
                    ExitLoop
                EndIf
            Next
            MsgBox(0, $iAppID, "Application: " & $sAppName & @CRLF & "Target Folder: " & $sTargetFolder & @CRLF & "Version: " & $sVersion)
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

To speed up the above, if you always have the items inside each section in the same order, you could skip the _ArraySearch and just hardcode the index value.

Please let me know which version you find to be faster.

M23

  • Like 1

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
jchd

1500 * 15 = 22 500 pairs of {key, value} = a clear candidate to an SQLite DB.

From there, things are going pretty much smooth. (MHO)


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
Arik

Thanks M23.

I tested both of them with the 1505 sections INI.

First script: Item 1 - almost instantaneous until msgbox. Item 1505 - a few seconds.

Second script: Item 1 - almost instantaneous until msgbox. Item 1505 - almost instantaneous.

Share this post


Link to post
Share on other sites
Melba23

Arik,

Thanks for the feedback.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
Melba23

Hi,

In a PM exchange the OP admitted that he was using a seriously out-dated version of AutoIt and the above code would not run. For anyone else who likes living in the digital equivalent of the Victorian era, you need to make the following changes:

$aIniSections = IniReadSectionNames($sIniFile)

; Create a 2D array and fill it
Global $aSections[UBound($aIniSections)][2] = [[$aIniSections[0]]]
$sEntries = ""
For $i = 1 To $aIniSections[0]
    $aSections[$i][0] = $aIniSections[$i]
    $aSections[$i][1] = IniRead($sIniFile, $aSections[$i][0], "AppName", "Error")
    $sEntries &= "|" & $aSections[$i][1] ; A leading "|" just replaces the current content so no need to exclude it from the first entry
Next

GUICreate("Test Program", 190, 40)

$cComboBox = GUICtrlCreateCombo("", 10, 10, 170, 20, $CBS_DROPDOWNLIST)
GUICtrlSetData($cComboBox, $sEntries)

; Should set a cue banner - $CB_SETCUEBANNER = 0x1703
GUICtrlSendMsg($cComboBox, 0x1703, 0, "Please select an application...") ; This way you do not get the text as an item in the combo

GUISetState()

That should work in any version since I have been a member (mid-2008).

And could I remind everyone that if they are (for whatever reason) not using the latest AutoIt release that they say so when posting - it will allow anyone who deciders to help to produce code that will work rather then throw up errors. But beware, if the version is seriously outdated, you may not get a lot of takers....

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×