dynamic list , populated in droplist, asigned to varibles Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

dynamic list , populated in droplist, asigned to varibles

14 Aug 2023, 14:57

im tring to get each example of match to populate inthe dropdown list. curently i only get 1 result. i also need a varible for each.

any ideas?

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.


;RunWait %comspec% /c bcdedit /enum | findstr /C:"identifier" | clip,,hide
;Haystack := Clipboard

Haystack := "identifier              {bootmgr}identifier              {current}"

matches := MatchBetween(Haystack,"{","}")
for each, match in matches
msgbox, % match

MatchBetween(Haystack,char1,char2) {
    Matches := [] , pos := 1
    while (pos1 := InStr(Haystack, char1,, pos)) && (pos2 := InStr(Haystack, char2,, pos))
        Matches.push(SubStr(Haystack,pos1+1,pos2-pos1-1)) , pos := pos2 + 1
    return Matches
}
Start:
Gui, New
Gui, Font, s10
Gui, Add, DropDownList,           w195        vlist, %match%
Gui, Show, w220, Select
F3::Gosub, Start
User avatar
flyingDman
Posts: 2848
Joined: 29 Sep 2013, 19:01

Re: dynamic list , populated in droplist, asigned to varibles

14 Aug 2023, 15:20

Something like this maybe?:

Code: Select all

Runwait *RunAs %comspec% /c bcdedit /enum | clip,,hide
for x,y in strsplit(clipboard,"`n","`r")
	if (instr(y,"identifier"))
		lst .= substr(y,25) "|"
Gui, Font, s10
Gui, Add, DropDownList,w195 vlist, %lst%
Gui, Show, w220, Select
14.3 & 1.3.7
joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

Re: dynamic list , populated in droplist, asigned to varibles

14 Aug 2023, 17:31

@flyingDman

that works and very clean ! how do i get the varible for each selection?

i hoping to have it so when i select from drop down. it will auto populate few other fields like description. when it runs a query based off the {guid} varible.

this will give me a varible asigned for each one found, but now i cant get displayed in drop down box....

Code: Select all

Runwait *RunAs %comspec% /c bcdedit /enum firmware| clip,,hide

;for x,y in strsplit(clipboard,"`n","`r")
;	if (instr(y,"identifier"))
;		lst .= substr(y,25) "|"


for i, part in StrSplit(clipboard, "{"), var := []
	if (i > 1)
		var[i-1] := InStr(part, "}") ? StrSplit(part, "}").1 : "" 

msgbox % var[1] " - " var[2] " - "  var[3]

Gui, Font, s10
Gui, Add, DropDownList,w195 vlist, %var%
Gui, Show, w220, Select
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: dynamic list , populated in droplist, asigned to varibles

14 Aug 2023, 18:29

joekingcool wrote:
14 Aug 2023, 17:31
i hoping to have it so when i select from drop down. it will auto populate few other fields like description. when it runs a query based off the {guid} varible.
Something like this?

Code: Select all

#SingleInstance, Force

outputList := []
outputList[ 1 ] := { Edit1: "Blah" , Edit2: "Blah, blah" , ListDisplayValue: "I want to use the first output" }
outputList[ 2 ] := { Edit1: "Other" , Edit2: "Other, other" , ListDisplayValue: "I want to use the second output" }

MyDisplayList := ""
for k , v in outputList	{
	MyDisplayList .= outputList[ k ].ListDisplayValue "|"
}

Gui, New, +AlwaysOnTop
Gui, Margin, 20 , 20
Gui, Add, DDL, xm ym w200 r10 AltSubmit vMyDDL gChangeFeilds choose1 , % MyDisplayList
Gui, Add, Edit, xm w200 r1 vEdit1 , % outputList[ 1 ].Edit1
Gui, Add, Edit, xm w200 r1 vEdit2 , % outputList[ 1 ].Edit2
Gui, Show

return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

;%%%%%%%%%%%%%%%%%%%%%%%%
ChangeFeilds:
	GuiControlGet, out ,, MyDDL
	GuiControl,, Edit1 , % outputList[ out ].Edit1
	GuiControl,, Edit2 , % outputList[ out ].Edit2
	return
;%%%%%%%%%%%%%%%%%%%%%%%%	
joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

Re: dynamic list , populated in droplist, asigned to varibles

14 Aug 2023, 18:43

@flyingDman

your code worked i tested with msgbox, many thanks!!

Code: Select all

Runwait *RunAs %comspec% /c bcdedit /enum | clip,,hide
for x,y in strsplit(clipboard,"`n","`r")
	if (instr(y,"identifier"))
		lst .= substr(y,25) "|"
Gui, Font, s10
Gui, Add, DropDownList,w195 vlist, %lst%
gui, add, button, x5 y60 h20 w70 gdisplay, refresh

Gui, Show, w220, Select

display:
Gui, Submit, nohide
msgbox, %list%
return

joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

Re: dynamic list , populated in droplist, asigned to varibles

14 Aug 2023, 18:47

@Hellbent

i have to run few other cmds based off the selection from the dropdown box. the answers to those queries would fill the text boxes.

but i can use some of that when i start filling in text boxes..
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: dynamic list , populated in droplist, asigned to varibles  Topic is solved

14 Aug 2023, 19:27

joekingcool wrote:
14 Aug 2023, 18:47
@Hellbent

i have to run few other cmds based off the selection from the dropdown box. the answers to those queries would fill the text boxes.

but i can use some of that when i start filling in text boxes..
This is more of what I had in mind in terms of your use case.

TBH I don't know anything about %comspec% but it looks like that is either altering the contents of your clipboard or putting something in your clipboard that you then want to parse and populate a gui with.

Code: Select all

Runwait *RunAs %comspec% /c bcdedit /enum | clip,,hide


Index := 0
outputList := []

MyDisplayList := ""

for k , v in strsplit( clipboard , "`n" , "`r" ){
	
	if ( instr( v , "identifier" ) ){
		outputList[ ++Index ] := {}
		outputList[ Index ].ListDisplayValue := substr( v , 25 )
		MyDisplayList .= outputList[ Index ].ListDisplayValue "|" 
	}else if( somethingelse ){
		outputList[ Index ].Edit1 := k
	}else if( yetAnotherThing ){
		outputList[ Index ].Edit2 := v
	}

}

Gui, New, +AlwaysOnTop
Gui, Margin, 20 , 20
Gui, Add, DDL, xm ym w200 r10 AltSubmit vMyDDL gChangeFeilds choose1 , % MyDisplayList
Gui, Add, Edit, xm w200 r1 vEdit1 , % outputList[ 1 ].Edit1
Gui, Add, Edit, xm w200 r1 vEdit2 , % outputList[ 1 ].Edit2
Gui, Show

return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

;%%%%%%%%%%%%%%%%%%%%%%%%
ChangeFeilds:
	GuiControlGet, out ,, MyDDL
	GuiControl,, Edit1 , % outputList[ out ].Edit1
	GuiControl,, Edit2 , % outputList[ out ].Edit2
	return
;%%%%%%%%%%%%%%%%%%%%%%%%	
I can't test this code so I can't refine it to the specs of your task.
joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

Re: dynamic list , populated in droplist, asigned to varibles

14 Aug 2023, 19:52

@Hellbent
btw cheers! , it's been a minute

i used comspec /c , because it wasn't putting output into clipboard, as far as i remember...

this is the basic cmd output below. it shows the boot entry's on a pc. unfortunately it don't have a built in way of parsing that output. there are certain variables that are important like path, description, identifier,device. so i'm going to have to find a way to parse the variables based off the identifier, then populate into text boxes. then ill create a save button. bcdedit does have cmds to set each field just not query them.

I'm finding allot of powershell attempts online but nothing that works yet...

Code: Select all

C:\Windows\system32>bcdedit /enum

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume1
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-US
inherit                 {globalsettings}
default                 {current}
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Windows Boot Loader
-------------------
identifier              {current}
device                  partition=C:
path                    \Windows\system32\winload.efi
description             Windows 10
locale                  en-US
inherit                 {bootloadersettings}
recoverysequence        {9b37dbc3-3950-11ee-a851-a33fbd0a893f}
displaymessageoverride  Recovery
recoveryenabled         Yes
isolatedcontext         Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \Windows
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
nx                      OptIn
bootmenupolicy          Standard

C:\Windows\system32>

User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: dynamic list , populated in droplist, asigned to varibles

14 Aug 2023, 19:59

It could also be that you want premade templates.
Selecting the item in the ddl will try to match with an associative array name.

Code: Select all


#SingleInstance, Force

BootMgr := { Edit1: "Blah" , Edit2: "Blah, Blah" }

Gui, Add, DDL, vMyDDL gChangeit , BootMgr|other|
Gui, Add, Edit, w200 vEdit1 ,
Gui, Show, 
return
*ESC::ExitApp

Changeit:
	SoundBeep
	Gui, Submit, NoHide
	GuiControl,, Edit1 , % ( %MyDDL% ).Edit1
	return

*Edit* Just saw your new post
joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

Re: dynamic list , populated in droplist, asigned to varibles

14 Aug 2023, 20:19

@Hellbent

i found this powershell script that does seem to query the output into variables, so i can display in text boxes eventually...

Code: Select all

bcdedit /enum | where {$_ -match "^[^-]"}| foreach -Begin {$props = $null} -Process {
    $a,$b = $_.Split(' ',2).trim()
    if($a -eq 'Windows')
    {
        if($props.keys.Count -gt 0)
        {
            [pscustomobject]$props
        }
        $props = [ordered]@{}
        $props.Add($a,$b)
    }
    else
    {
        $props.Add($a,$b)
    }
} -End {[pscustomobject]$props} -OutVariable bcd
example of basic query

Code: Select all

PS C:\Windows\system32> bcdedit /enum

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume1
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-US
inherit                 {globalsettings}
default                 {current}
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Windows Boot Loader
-------------------
identifier              {current}
device                  partition=C:
path                    \Windows\system32\winload.efi
description             Windows 10
locale                  en-US
inherit                 {bootloadersettings}
recoverysequence        {9b37dbc3-3950-11ee-a851-a33fbd0a893f}
displaymessageoverride  Recovery
recoveryenabled         Yes
isolatedcontext         Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \Windows
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
nx                      OptIn
bootmenupolicy          Standard

PS C:\Windows\system32> 
after the initial PowerShell script this cmd will help me fill the text boxes based off the dropdown.

Code: Select all

PS C:\Windows\system32> $bcd | where identifier -eq '{current}' | select -ExpandProperty description
Windows 10
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: dynamic list , populated in droplist, asigned to varibles

17 Aug 2023, 02:56

I'm not sure if this will work for you or not but it seems to work for the sample you gave.

This function takes a string and an array of identifiers that you want to collect data on [ "Path" , "Other" ],
and returns an array for each instance it finds of "identifier" ( if it finds 10 instances it will return an array that has 10 elements ).
The values of each instance are stored in an associative array nested in each index in the array arr[ 1 ] := { Path: "" , Key: "Value" }

Code: Select all

;******************************
Get_InsertNameHere_Object( String , SearchList ){ ;custom parsing function. returns arr[{}]
	local OutputLists := []
	SearchListString := ""
	Loop, % SearchList.Length()	
		SearchListString .= SearchList[ A_Index ] "|"
	clipArray := StrSplit( string , "`n" , "`r" )
	Loop, 	{
		if( pos := instr( string , "identifier" ,,, A_Index ) ){
			tempObj := {}
			for k , v in SearchList	
				tempObj[ v ] := ""
			OutputLists.Push( tempObj )
			if( A_Index = 1 ){
				Start_%A_Index% := pos
			}else{
				num := A_Index - 1
				End_%num% := pos - 1
				Start_%A_Index% := pos
			}
		}else{
			break
		}
	}
	Sections := []
	Loop, % OutputLists.Length() - 1
		Sections.Push( subStr( string , Start_%A_Index% , End_%A_Index% - STart_%A_Index% ) )
	num := OutputLists.Length()
	Sections.Push( subStr( string , Start_%num% ) )
	Loop, % Sections.Length()	{
		LineArray := StrSplit( Sections[ A_Index ] , "`n" , "`r" )
		Index := A_Index
		Loop, % LineArray.Length()	{
			if( InStr( SearchListString , ( out := StrSplit( Trim( LineArray[ A_Index ] ) , " " )[ 1 ] ) )  && out != "" ){
				OutputLists[ Index ][ out ] := Trim( SubStr( Trim( LineArray[ A_Index ] ) , StrLen( out ) + 1 ) )
				if( out = "identifier" )
					OutputLists[ Index ][ "DisplayValue" ] := OutputLists[ Index ][ out ]
			}
		}
	}
	return OutputLists
}
;******************************
Here is how you call the function.

Code: Select all



SearchList := [ "Identifier" , "Device" , "Path" , "Description" , "Locale" , "Systemroot" , "Default" ] ;List of items to filter for.
OutputLists := Get_InsertNameHere_Object( ClipBoard , SearchList ) ;returns an [ array ] of { objects } ; ||| ; i.e. OutputLists[ 1 ].Path 


and that can then be used to populate a simple gui ( working example [ copy / paste ] ).

Code: Select all

#SingleInstance, Force
;Test String. Can replace with clipboard.
string =
( `join
PS C:\Windows\system32> bcdedit /enum

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume1
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-US
inherit                 {globalsettings}
default                 {current}
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Windows Boot Loader
-------------------
identifier              {current}
device                  partition=C:
path                    \Windows\system32\winload.efi
description             Windows 10
locale                  en-US
inherit                 {bootloadersettings}
recoverysequence        {9b37dbc3-3950-11ee-a851-a33fbd0a893f}
displaymessageoverride  Recovery
recoveryenabled         Yes
isolatedcontext         Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \Windows
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
nx                      OptIn
bootmenupolicy          Standard

PS C:\Windows\system32> 
)
;******************************
SearchList := [ "Identifier" , "Device" , "Path" , "Description" , "Locale" , "Systemroot" , "Default" ] ;List of items to filter for.
OutputLists := Get_InsertNameHere_Object( String , SearchList ) ;returns an [ array ] of { objects } ; ||| ; i.e. OutputLists[ 1 ].Path 
;******************************
MyDisplayString := ""
Loop, % OutputLists.Length()
	MyDisplayString .= OutputLists[ A_Index ].DisplayValue "|" ;creating a list to display in the dropdownlist control. "Item|Item|Item|"
;******************************
Gui, New, +AlwaysOnTop
Gui, Add, DDL, xm ym w300 r10 vMyDDL gChangeIt choose1 AltSubmit, % MyDisplayString
index := 1
for k , v in SearchList	{
	if( v = "identifier" )
		continue 
	Gui, Add, Text, xm y+10 w60 r1 , % v 
	Gui, Add, Edit, x+10 w230 r1 vEdit_%Index% , % OutputLists[ 1 ][ v ] 
	Index++
}
Gui, Show, 
return ;<<<---- End of the auto execute section of the script.
;******************************
GuiClose: ;<<<--- Exit Routine.
GuiContextMenu:
*ESC::ExitApp
;******************************
Changeit: ;called when something is selected in the dropdownlist
	GuiControlGet, SelectedIndex ,, MyDDL 
	Index := 1 
	Loop, % SearchList.Length()	{ 
		if( ( keyname := SearchList[ A_Index ] ) = "identifier" )
			continue
		GuiControl, , % "Edit_" Index , % OutputLists[ SelectedIndex ][ KeyName ]
		Index++
	}
	return
;******************************
Get_InsertNameHere_Object( String , SearchList ){ ;custom parsing function. returns arr[{}]
	local OutputLists := []
	SearchListString := ""
	Loop, % SearchList.Length()	
		SearchListString .= SearchList[ A_Index ] "|"
	clipArray := StrSplit( string , "`n" , "`r" )
	Loop, 	{
		if( pos := instr( string , "identifier" ,,, A_Index ) ){
			tempObj := {}
			for k , v in SearchList	
				tempObj[ v ] := ""
			OutputLists.Push( tempObj )
			if( A_Index = 1 ){
				Start_%A_Index% := pos
			}else{
				num := A_Index - 1
				End_%num% := pos - 1
				Start_%A_Index% := pos
			}
		}else{
			break
		}
	}
	Sections := []
	Loop, % OutputLists.Length() - 1
		Sections.Push( subStr( string , Start_%A_Index% , End_%A_Index% - STart_%A_Index% ) )
	num := OutputLists.Length()
	Sections.Push( subStr( string , Start_%num% ) )
	Loop, % Sections.Length()	{
		LineArray := StrSplit( Sections[ A_Index ] , "`n" , "`r" )
		Index := A_Index
		Loop, % LineArray.Length()	{
			if( InStr( SearchListString , ( out := StrSplit( Trim( LineArray[ A_Index ] ) , " " )[ 1 ] ) )  && out != "" ){
				OutputLists[ Index ][ out ] := Trim( SubStr( Trim( LineArray[ A_Index ] ) , StrLen( out ) + 1 ) )
				if( out = "identifier" )
					OutputLists[ Index ][ "DisplayValue" ] := OutputLists[ Index ][ out ]
			}
		}
	}
	return OutputLists
}
;******************************
The way it started isn't the way it ended, so... you have to use "Identifier" in the "SearchList" array even though it's mostly hard coded into the function. :D

If you have any questions feel free to ask.
joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

Re: dynamic list , populated in droplist, asigned to varibles

17 Aug 2023, 10:36

@Hellbent

works great :salute: thats allot of work, thanks so much :salute: so much snappier /faster than reling on powershell script :bravo: :bravo: :bravo:

i edited your script to add more to the string. because i have to run the cmd 2 ways to get a full list. the only issue now is it has a duplicate of {bootmgr} and all {fwbootmgr} need removed from ddl. i tried and got {fwbootmgr} removed. and removed one of the {bootmgr} , but ddl has a blank and the output is swaped with the other {bootmgr} .

Code: Select all

#SingleInstance, Force
; Test String. Can replace with clipboard. i added 2nd cmd that also needs added to string, because one cmd dont get all results
; we dont need the cmd line included in the string, not sure if it will throw off the results
; so after this we get 2 {bootmgr} and i need to remove 1 from ddl. also need to remove {fwbootmgr} from list totally.
string =
( `join
Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume1
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-US
inherit                 {globalsettings}
default                 {current}
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Windows Boot Loader
-------------------
identifier              {current}
device                  partition=C:
path                    \Windows\system32\winload.efi
description             Windows 10
locale                  en-US
inherit                 {bootloadersettings}
recoverysequence        {9b37dbc3-3950-11ee-a851-a33fbd0a893f}
displaymessageoverride  Recovery
recoveryenabled         Yes
isolatedcontext         Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \Windows
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
nx                      OptIn
bootmenupolicy          Standard

Firmware Boot Manager
---------------------
identifier              {fwbootmgr}
displayorder            {bootmgr}
                        {b63c85a7-3c94-11ee-8006-806e6f6e6963}
                        {4af6a055-3c9c-11ee-800a-806e6f6e6963}
                        {99f012a0-3c9b-11ee-9c0a-8c7f7582acf8}
timeout                 1

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume2
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-us
inherit                 {globalsettings}
default                 {current}
resumeobject            {bd1ef51f-3c9b-11ee-9c0a-8c7f7582acf8}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Firmware Application (101fffff)
-------------------------------
identifier              {4af6a055-3c9c-11ee-800a-806e6f6e6963}
device                  partition=R:
path                    \EFI\BOOT\BOOTX64.EFI
description             UEFI OS

Firmware Application (101fffff)
-------------------------------
identifier              {99f012a0-3c9b-11ee-9c0a-8c7f7582acf8}
device                  partition=\Device\HarddiskVolume38
description             UEFI: Samsung Flash Drive FIT 1100, Partition 2

Firmware Application (101fffff)
-------------------------------
identifier              {b63c85a7-3c94-11ee-8006-806e6f6e6963}
device                  partition=R:
path                    \EFI\BOOT\BOOTX64.EFI
description             UEFI: WDC PC SN730 SDBPNTY-512G-1032, Partition 5
)




;********************************************************************************
;if we dont use string output above. and run cmd with admin

string = ""
stringa = ""
stringb = ""

Runwait %comspec% /c bcdedit /enum | clip,,hide
stringa := % Clipboard
Clipboard := ""

;able to remove from ddl, although there is a blank selection and output is swapped with the other {bootmgr}

Runwait %comspec% /c bcdedit /enum firmware | clip,,hide
stringb := % Clipboard
StringReplace, stringb, stringb, {fwbootmgr}, ,
StringReplace, stringb, stringb, {bootmgr}, ,

string = %stringa% . %stringb%
;***************************************************************************************



;******************************
SearchList := [ "Identifier" , "Device" , "Path" , "Description" , "Locale" , "Systemroot" , "Default" ] ;List of items to filter for.
OutputLists := Get_InsertNameHere_Object( String , SearchList ) ;returns an [ array ] of { objects } ; ||| ; i.e. OutputLists[ 1 ].Path 
;******************************
MyDisplayString := ""
Loop, % OutputLists.Length()
	MyDisplayString .= OutputLists[ A_Index ].DisplayValue "|" ;creating a list to display in the dropdownlist control. "Item|Item|Item|"
;******************************
Gui, New, +AlwaysOnTop
Gui, Add, DDL, xm ym w300 r10 vMyDDL gChangeIt choose1 AltSubmit, % MyDisplayString
index := 1
for k , v in SearchList	{
	if( v = "identifier" )
		continue 
	Gui, Add, Text, xm y+10 w60 r1 , % v 
	Gui, Add, Edit, x+10 w230 r1 vEdit_%Index% , % OutputLists[ 1 ][ v ] 
	Index++
}
Gui, Show, 
return ;<<<---- End of the auto execute section of the script.
;******************************
GuiClose: ;<<<--- Exit Routine.
GuiContextMenu:
*ESC::ExitApp
;******************************
Changeit: ;called when something is selected in the dropdownlist
	GuiControlGet, SelectedIndex ,, MyDDL 
	Index := 1 
	Loop, % SearchList.Length()	{ 
		if( ( keyname := SearchList[ A_Index ] ) = "identifier" )
			continue
		GuiControl, , % "Edit_" Index , % OutputLists[ SelectedIndex ][ KeyName ]
		Index++
	}
	return
;******************************
Get_InsertNameHere_Object( String , SearchList ){ ;custom parsing function. returns arr[{}]
	local OutputLists := []
	SearchListString := ""
	Loop, % SearchList.Length()	
		SearchListString .= SearchList[ A_Index ] "|"
	clipArray := StrSplit( string , "`n" , "`r" )
	Loop, 	{
		if( pos := instr( string , "identifier" ,,, A_Index ) ){
			tempObj := {}
			for k , v in SearchList	
				tempObj[ v ] := ""
			OutputLists.Push( tempObj )
			if( A_Index = 1 ){
				Start_%A_Index% := pos
			}else{
				num := A_Index - 1
				End_%num% := pos - 1
				Start_%A_Index% := pos
			}
		}else{
			break
		}
	}
	Sections := []
	Loop, % OutputLists.Length() - 1
		Sections.Push( subStr( string , Start_%A_Index% , End_%A_Index% - STart_%A_Index% ) )
	num := OutputLists.Length()
	Sections.Push( subStr( string , Start_%num% ) )
	Loop, % Sections.Length()	{
		LineArray := StrSplit( Sections[ A_Index ] , "`n" , "`r" )
		Index := A_Index
		Loop, % LineArray.Length()	{
			if( InStr( SearchListString , ( out := StrSplit( Trim( LineArray[ A_Index ] ) , " " )[ 1 ] ) )  && out != "" ){
				OutputLists[ Index ][ out ] := Trim( SubStr( Trim( LineArray[ A_Index ] ) , StrLen( out ) + 1 ) )
				if( out = "identifier" )
					OutputLists[ Index ][ "DisplayValue" ] := OutputLists[ Index ][ out ]
			}
		}
	}
	return OutputLists
}
;******************************

joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

Re: dynamic list , populated in droplist, asigned to varibles

17 Aug 2023, 12:37

i got them removed, typo ...

works great now i just have to add set cmd for detail and see if it updates in system.

ill reply in here with updated script as i go

Code: Select all

#SingleInstance, Force
; Test String. Can replace with clipboard. i added 2nd cmd that also needs added to string, because one cmd dont get all results
; we dont need the cmd line included in the string, not sure if it will throw off the results
; so after this we get 2 {bootmgr} and i need to remove 1 from ddl. also need to remove {fwbootmgr} from list totally.
string =
( `join
Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume1
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-US
inherit                 {globalsettings}
default                 {current}
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Windows Boot Loader
-------------------
identifier              {current}
device                  partition=C:
path                    \Windows\system32\winload.efi
description             Windows 10
locale                  en-US
inherit                 {bootloadersettings}
recoverysequence        {9b37dbc3-3950-11ee-a851-a33fbd0a893f}
displaymessageoverride  Recovery
recoveryenabled         Yes
isolatedcontext         Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \Windows
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
nx                      OptIn
bootmenupolicy          Standard

Firmware Boot Manager
---------------------
identifier              {fwbootmgr}
displayorder            {bootmgr}
                        {b63c85a7-3c94-11ee-8006-806e6f6e6963}
                        {4af6a055-3c9c-11ee-800a-806e6f6e6963}
                        {99f012a0-3c9b-11ee-9c0a-8c7f7582acf8}
timeout                 1

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume2
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-us
inherit                 {globalsettings}
default                 {current}
resumeobject            {bd1ef51f-3c9b-11ee-9c0a-8c7f7582acf8}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Firmware Application (101fffff)
-------------------------------
identifier              {4af6a055-3c9c-11ee-800a-806e6f6e6963}
device                  partition=R:
path                    \EFI\BOOT\BOOTX64.EFI
description             UEFI OS

Firmware Application (101fffff)
-------------------------------
identifier              {99f012a0-3c9b-11ee-9c0a-8c7f7582acf8}
device                  partition=\Device\HarddiskVolume38
description             UEFI: Samsung Flash Drive FIT 1100, Partition 2

Firmware Application (101fffff)
-------------------------------
identifier              {b63c85a7-3c94-11ee-8006-806e6f6e6963}
device                  partition=R:
path                    \EFI\BOOT\BOOTX64.EFI
description             UEFI: WDC PC SN730 SDBPNTY-512G-1032, Partition 5
)




;********************************************************************************
;if we dont use string output above. and run cmd with admin

string = ""
stringa = ""
stringb = ""

Runwait %comspec% /c bcdedit /enum | clip,,hide
stringa := % Clipboard
Clipboard := ""

;able to remove from ddl, although there is a blank selection and output is swapped with the other {bootmgr}

Runwait %comspec% /c bcdedit /enum firmware | clip,,hide
stringb := % Clipboard
StringReplace, stringb, stringb, identifier              {fwbootmgr}, ,
StringReplace, stringb, stringb, identifier              {bootmgr}, ,

string = %stringa% . %stringb%
;***************************************************************************************



;******************************
SearchList := [ "Identifier" , "Device" , "Path" , "Description" , "Locale" , "Systemroot" , "Default" ] ;List of items to filter for.
OutputLists := Get_InsertNameHere_Object( String , SearchList ) ;returns an [ array ] of { objects } ; ||| ; i.e. OutputLists[ 1 ].Path 
;******************************
MyDisplayString := ""
Loop, % OutputLists.Length()
	MyDisplayString .= OutputLists[ A_Index ].DisplayValue "|" ;creating a list to display in the dropdownlist control. "Item|Item|Item|"
;******************************
Gui, New, +AlwaysOnTop
Gui, Add, DDL, xm ym w300 r10 vMyDDL gChangeIt choose1 AltSubmit, % MyDisplayString
index := 1
for k , v in SearchList	{
	if( v = "identifier" )
		continue 
	Gui, Add, Text, xm y+10 w60 r1 , % v 
	Gui, Add, Edit, x+10 w230 r1 vEdit_%Index% , % OutputLists[ 1 ][ v ] 
	Index++
}
Gui, Show, 
return ;<<<---- End of the auto execute section of the script.
;******************************
GuiClose: ;<<<--- Exit Routine.
GuiContextMenu:
*ESC::ExitApp
;******************************
Changeit: ;called when something is selected in the dropdownlist
	GuiControlGet, SelectedIndex ,, MyDDL 
	Index := 1 
	Loop, % SearchList.Length()	{ 
		if( ( keyname := SearchList[ A_Index ] ) = "identifier" )
			continue
		GuiControl, , % "Edit_" Index , % OutputLists[ SelectedIndex ][ KeyName ]
		Index++
	}
	return
;******************************
Get_InsertNameHere_Object( String , SearchList ){ ;custom parsing function. returns arr[{}]
	local OutputLists := []
	SearchListString := ""
	Loop, % SearchList.Length()	
		SearchListString .= SearchList[ A_Index ] "|"
	clipArray := StrSplit( string , "`n" , "`r" )
	Loop, 	{
		if( pos := instr( string , "identifier" ,,, A_Index ) ){
			tempObj := {}
			for k , v in SearchList	
				tempObj[ v ] := ""
			OutputLists.Push( tempObj )
			if( A_Index = 1 ){
				Start_%A_Index% := pos
			}else{
				num := A_Index - 1
				End_%num% := pos - 1
				Start_%A_Index% := pos
			}
		}else{
			break
		}
	}
	Sections := []
	Loop, % OutputLists.Length() - 1
		Sections.Push( subStr( string , Start_%A_Index% , End_%A_Index% - STart_%A_Index% ) )
	num := OutputLists.Length()
	Sections.Push( subStr( string , Start_%num% ) )
	Loop, % Sections.Length()	{
		LineArray := StrSplit( Sections[ A_Index ] , "`n" , "`r" )
		Index := A_Index
		Loop, % LineArray.Length()	{
			if( InStr( SearchListString , ( out := StrSplit( Trim( LineArray[ A_Index ] ) , " " )[ 1 ] ) )  && out != "" ){
				OutputLists[ Index ][ out ] := Trim( SubStr( Trim( LineArray[ A_Index ] ) , StrLen( out ) + 1 ) )
				if( out = "identifier" )
					OutputLists[ Index ][ "DisplayValue" ] := OutputLists[ Index ][ out ]
			}
		}
	}
	return OutputLists
}
;******************************

User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: dynamic list , populated in droplist, asigned to varibles

18 Aug 2023, 02:12

joekingcool wrote:
17 Aug 2023, 10:36
@Hellbent

works great :salute: thats allot of work, thanks so much :salute: so much snappier /faster than reling on powershell script :bravo: :bravo: :bravo:
I'm glad that it's working for you.
i edited your script to add more to the string. because i have to run the cmd 2 ways to get a full list. the only issue now is it has a duplicate of {bootmgr} and all {fwbootmgr} need removed from ddl. i tried and got {fwbootmgr} removed. and removed one of the {bootmgr} , but ddl has a blank and the output is swaped with the other {bootmgr} .
I edited the function to take one more optional argument to have it remove duplicate identifiers.

This is what I added to the function.

Code: Select all

	;************************************************
	;************************************************
	if( RemoveDuplicates ){ 													;if duplicates should be removed
		idList := "|" 															;create a new string to concatenate new items to. 
		temp := [] 																;create a new array to store the copied data from the original array to.
		index := 0 																;the current number of unique items.
		Loop, % OutputLists.Length()	{										;loop through all of the lists
			if( !InStr( idList , "|" OutputLists[ A_Index ].identifier "|" ) ){	;check to see if the identifier for the current list isn't in the idList string.
				idList .= OutputLists[ A_Index ].identifier "|"					;add the identifier to the idlist string so that it can't get used again.
				temp[ ++index ] := {}											;add a new element to the temp array.
				for k , v in OutputLists[ A_Index ]								;Copy the current list and all its values.
					temp[ index ][ k ] := v							
			}
		}
		return temp
	}
	;************************************************
	;************************************************
Here is an example of calling the edited function.

Code: Select all

;******************************
String := Clipboard
SearchList := [ "Identifier" , "Device" , "Path" , "Description" ] 
RemoveDuplicates := 1	;<<<---  [ true or false ] / [ 1 or 0 ]
OutputLists := Get_InsertNameHere_Object( String , SearchList , RemoveDuplicates ) 
;******************************
Here is the new function. You can just replace the old function in the test script with the gui and it should work.

Code: Select all

;******************************
Get_InsertNameHere_Object( String , SearchList , RemoveDuplicates := 0 ){ ;custom parsing function. returns arr[{}]
	local OutputLists := []
	SearchListString := ""
	Loop, % SearchList.Length()	
		SearchListString .= SearchList[ A_Index ] "|"
	Loop, 	{
		if( pos := instr( string , "identifier" ,,, A_Index ) ){
			tempObj := {}
			for k , v in SearchList	
				tempObj[ v ] := ""
			OutputLists.Push( tempObj )
			if( A_Index = 1 ){
				Start_%A_Index% := pos
			}else{
				num := A_Index - 1
				End_%num% := pos - 1
				Start_%A_Index% := pos
			}
		}else{
			break
		}
	}
	Sections := []
	Loop, % OutputLists.Length() - 1
		Sections.Push( subStr( string , Start_%A_Index% , End_%A_Index% - STart_%A_Index% ) )
	num := OutputLists.Length()
	Sections.Push( subStr( string , Start_%num% ) )
	Loop, % Sections.Length()	{
		LineArray := StrSplit( Sections[ A_Index ] , "`n" , "`r" )
		Index := A_Index
		Loop, % LineArray.Length()	{
			if( InStr( SearchListString , ( out := StrSplit( Trim( LineArray[ A_Index ] ) , " " )[ 1 ] ) )  && out != "" ){
				OutputLists[ Index ][ out ] := Trim( SubStr( Trim( LineArray[ A_Index ] ) , StrLen( out ) + 1 ) )
				if( out = "identifier" )
					OutputLists[ Index ][ "DisplayValue" ] := OutputLists[ Index ][ out ]
			}
		}
	}
	;************************************************
	;************************************************
	if( RemoveDuplicates ){ ;if duplicates should be removed
		idList := "|"
		temp := []
		index := 0
		Loop, % OutputLists.Length()	{
			if( !InStr( idList , "|" OutputLists[ A_Index ].identifier "|" ) ){
				idList .= OutputLists[ A_Index ].identifier "|"
				temp[ ++index ] := {}
				for k , v in OutputLists[ A_Index ]
					temp[ index ][ k ] := v
			}
		}
		return temp
	}
	;************************************************
	;************************************************
	return OutputLists
}
;******************************
I noticed that your new sample string includes situations where there is more than one line associated with the header.
If you want to get more than one line you will need to edit the function to have it look ahead of its current line position and see if there is a pattern you can match. If you have a match you can concatenate to the current key:*value*

If you have any questions feel free to ask.


***EDIT***
I just noticed that you also want to be able to select items to be excluded.
You can edit in one more optional argument to the function to have it also exclude unwanted identifiers.
Or you use that same remove duplicates code and edit it to remove whatever you want on the outside of the function, after you have called the function.
Let me know if you need help adding it.
joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

Re: dynamic list , populated in droplist, asigned to varibles

19 Aug 2023, 15:12

@Hellbent

Thanks so much for function and works great. although it might be an issue in future depending on situation. i just need to remove one of the {bootmgr} and {fwbootmgr} and the rest is fine even if its a duplicate. it works ethier way right now though.

i am having trouble figuring out. how to get the varibles of the current edit boxes that are displayed. i need to pipe them into cmds so i can update those values. then i send to begining of script to refresh the app.

example of a section

Code: Select all

Save:
Gui, Submit, nohide
Runwait %comspec% /c bcdedit /set %list% description '%description%',,hide
Runwait %comspec% /c bcdedit /set %list% device '%device%',,hide
Runwait %comspec% /c bcdedit /set %list% path '%path%',,hide
Runwait %comspec% /c bcdedit /set %list% recoveryenabled '%Recoveryenabled%',,hide
Runwait %comspec% /c bcdedit /set %list% nx '%NX%',,hide
GuiControl,, info, Saved Fields to guid
sleep 2000
goto, begin

Delete:
Gui, Submit, nohide
Runwait %comspec% /c bcdedit /delete "%list%",,hide
GuiControl,, info, Deleted Guid 
goto, begin


Export:
Runwait %comspec% /c bcdedit /export "%A_ScriptDir%\bcd-backup.bcd",,hide
GuiControl,, info, Backed Up Boot Config
return

Import:
Runwait %comspec% /c bcdedit /import "%A_ScriptDir%\bcd-backup.bcd",,hide
GuiControl,, info, Restored Boot Config
sleep 2000
goto, begin

Default:
return
also im having trouble adding the buttons dynamically like you have current edit boxes.

Code: Select all

;******************************
SearchList := [ "Identifier" , "Description" , "Device" , "Path" , "Displayorder" , "Default" , "Locale", "Systemroot" , "Osdevice" , "Resumeobject" , "NX" ] ;List of items to filter for.
OutputLists := Get_InsertNameHere_Object( String , SearchList ) ;returns an [ array ] of { objects } ; ||| ; i.e. OutputLists[ 1 ].Path 
;******************************
MyDisplayString := ""
Loop, % OutputLists.Length()
	MyDisplayString .= OutputLists[ A_Index ].DisplayValue "|" ;creating a list to display in the dropdownlist control. "Item|Item|Item|"
;******************************
Gui, New, +AlwaysOnTop
Gui, Add, DDL, xm ym w300 r10 vMyDDL gChangeIt choose1 AltSubmit, % MyDisplayString
index := 1
for k , v in SearchList	{
	if( v = "identifier" )
		continue 
	Gui, Add, Text, xm y+3 w80 r5 , % v 
	Gui, Add, Edit, x+3 w230 r1 vEdit_%Index% , % OutputLists[ 1 ][ v ] 
	Index++
}
Gui, add, button, x10 y280 h25 w60 gSave, Save
Gui, add, button, x70 y280 h25 w60 gDelete, Delete
Gui, add, button, x130 y280 h25 w60 gExport, Export
Gui, add, button, x190 y280 h25 w60 gImport, Import
Gui, add, button, x250 y280 h25 w60 gDefault, Default


Gui, Show,  , BCD Boot Entry Edit Tool
return ;<<<---- End of the auto execute section of the script.

joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

Re: dynamic list , populated in droplist, asigned to varibles

21 Aug 2023, 17:50

@Hellbent

im starting to learn how the varibles are working in the array. i found a way to get what is currently displayed in each field into a varible. although if i edit those fields, i dont know how to update the varibles for those fields....

current script

Code: Select all

begin:

#SingleInstance, Force
string =
( `join
Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume1
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-US
inherit                 {globalsettings}
default                 {current}
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Windows Boot Loader
-------------------
identifier              {current}
device                  partition=C:
path                    \Windows\system32\winload.efi
description             Windows 10
locale                  en-US
inherit                 {bootloadersettings}
recoverysequence        {9b37dbc3-3950-11ee-a851-a33fbd0a893f}
displaymessageoverride  Recovery
recoveryenabled         Yes
isolatedcontext         Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \Windows
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
nx                      OptIn
bootmenupolicy          Standard

Firmware Boot Manager
---------------------
identifier              {fwbootmgr}
displayorder            {bootmgr}
                        {b63c85a7-3c94-11ee-8006-806e6f6e6963}
                        {4af6a055-3c9c-11ee-800a-806e6f6e6963}
                        {99f012a0-3c9b-11ee-9c0a-8c7f7582acf8}
timeout                 1

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume2
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-us
inherit                 {globalsettings}
default                 {current}
resumeobject            {bd1ef51f-3c9b-11ee-9c0a-8c7f7582acf8}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Firmware Application (101fffff)
-------------------------------
identifier              {4af6a055-3c9c-11ee-800a-806e6f6e6963}
device                  partition=R:
path                    \EFI\BOOT\BOOTX64.EFI
description             UEFI OS

Firmware Application (101fffff)
-------------------------------
identifier              {99f012a0-3c9b-11ee-9c0a-8c7f7582acf8}
device                  partition=\Device\HarddiskVolume38
description             UEFI: Samsung Flash Drive FIT 1100, Partition 2

Firmware Application (101fffff)
-------------------------------
identifier              {b63c85a7-3c94-11ee-8006-806e6f6e6963}
device                  partition=R:
path                    \EFI\BOOT\BOOTX64.EFI
description             UEFI: WDC PC SN730 SDBPNTY-512G-1032, Partition 5
)




;********************************************************************************
;if we dont use string output above. and run cmd with admin

string = ""
stringa = ""
stringb = ""

Runwait %comspec% /c bcdedit /enum | clip,,hide
stringa := % Clipboard
Clipboard := ""

Runwait %comspec% /c bcdedit /enum firmware | clip,,hide
stringb := % Clipboard
StringReplace, stringb, stringb, identifier              {fwbootmgr}, ,
StringReplace, stringb, stringb, identifier              {bootmgr}, ,

string = %stringa% . %stringb%
;***************************************************************************************



;******************************
SearchList := [ "Identifier" , "Description" , "Device" , "Path" , "Displayorder" , "Default" , "Locale", "Systemroot" , "Osdevice" , "Resumeobject" , "NX" , "Recoveryenabled"] ;List of items to filter for.
OutputLists := Get_InsertNameHere_Object( String , SearchList ) ;returns an [ array ] of { objects } ; ||| ; i.e. OutputLists[ 1 ].Path 
;******************************
MyDisplayString := ""
Loop, % OutputLists.Length()
	MyDisplayString .= OutputLists[ A_Index ].DisplayValue "|" ;creating a list to display in the dropdownlist control. "Item|Item|Item|"
;******************************
Gui, destroy
Gui, New, +AlwaysOnTop
Gui, Add, DDL, xm ym w300 r10 vMyDDL gChangeIt choose1 AltSubmit, % MyDisplayString
index := 1
for k , v in SearchList	{
	if( v = "Identifier" )
		continue 
	Gui, Add, Text, xm y+3 w80 r5 , % v 
	Gui, Add, Edit, x+3 w230 r1 vEdit_%Index% , % OutputLists[ 1 ][ v ] 
	Index++


}

list :=% OutputLists[ 1 ][ "Identifier" ]
Description :=% OutputLists[ 1 ][ "Description" ]
Device :=% OutputLists[ 1 ][ "Device" ]
Path :=% OutputLists[ 1 ][ "Path" ]
Displayorder :=% OutputLists[ 1 ][ "Displayorder" ]
Default :=% OutputLists[ 1 ][ "Default" ]
Locale :=% OutputLists[ 1 ][ "Locale" ]
Systemroot :=% OutputLists[ 1 ][ "Systemroot" ]
Osdevice :=% OutputLists[ 1 ][ "Osdevice" ]
Resumeobject :=% OutputLists[ 1 ][ "Resumeobject" ]
NX :=% OutputLists[ 1 ][ "NX" ]
Recoveryenabled :=% OutputLists[ 1 ][ "Recoveryenabled" ]

Gui, add, button, x10 y280 h25 w60 gSave, Save
Gui, add, button, x70 y280 h25 w60 gDelete, Delete
Gui, add, button, x130 y280 h25 w60 gExport, Export
Gui, add, button, x190 y280 h25 w60 gImport, Import
Gui, add, button, x250 y280 h25 w60 gDefault, Default


Gui, Show,  , BCD Boot Entry Edit Tool
return ;<<<---- End of the auto execute section of the script.
;******************************
GuiClose: ;<<<--- Exit Routine.
GuiContextMenu:
*ESC::ExitApp



Save:
;Gui, Submit, nohide
msgbox,  bcdedit /set %List% description %Description%
Runwait, bcdedit /set %List% description %Description%,,hide
Runwait %comspec% /c bcdedit /set %List% device '%Device%',,hide
Runwait %comspec% /c bcdedit /set %List% path '%Path%',,hide
Runwait %comspec% /c bcdedit /set %List% recoveryenabled '%Recoveryenabled%',,hide
Runwait %comspec% /c bcdedit /set %List% nx '%NX%',,hide
;GuiControl,, info, Saved Fields to guid
goto, begin

Delete:
Gui, Submit, nohide
Runwait %comspec% /c bcdedit /delete "%List%",,hide
GuiControl,, info, Deleted Guid 
goto, begin


Export:
Runwait %comspec% /c bcdedit /export "%A_ScriptDir%\bcd-backup.bcd",,hide
GuiControl,, info, Backed Up Boot Config
return

Import:
Runwait %comspec% /c bcdedit /import "%A_ScriptDir%\bcd-backup.bcd",,hide
GuiControl,, info, Restored Boot Config
sleep 2000
goto, begin

Default:
return













;******************************
Changeit: ;called when something is selected in the dropdownlist
	GuiControlGet, SelectedIndex ,, MyDDL 
	Index := 1 
	Loop, % SearchList.Length()	{ 
		if( ( keyname := SearchList[ A_Index ] ) = "identifier" )
			continue
		GuiControl, , % "Edit_" Index , % OutputLists[ SelectedIndex ][ KeyName ]
		Index++
	}

List :=% OutputLists[ SelectedIndex ][ "Identifier" ]
Description :=% OutputLists[ SelectedIndex ][ "Description" ]
Device :=% OutputLists[ SelectedIndex ][ "Device" ]
Path :=% OutputLists[ SelectedIndex ][ "Path" ]
Displayorder :=% OutputLists[ SelectedIndex ][ "Displayorder" ]
Default :=% OutputLists[ SelectedIndex ][ "Default" ]
Locale :=% OutputLists[ SelectedIndex ][ "Locale" ]
Systemroot :=% OutputLists[ SelectedIndex ][ "Systemroot" ]
Osdevice :=% OutputLists[ SelectedIndex ][ "Osdevice" ]
Resumeobject :=% OutputLists[ SelectedIndex ][ "Resumeobject" ]
NX :=% OutputLists[ SelectedIndex ][ "NX" ]
Recoveryenabled :=% OutputLists[ SelectedIndex ][ "Recoveryenabled" ]

	return
;******************************
Get_InsertNameHere_Object( String , SearchList ){ ;custom parsing function. returns arr[{}]
	local OutputLists := []
	SearchListString := ""
	Loop, % SearchList.Length()	
		SearchListString .= SearchList[ A_Index ] "|"
	clipArray := StrSplit( string , "`n" , "`r" )
	Loop, 	{
		if( pos := instr( string , "identifier" ,,, A_Index ) ){
			tempObj := {}
			for k , v in SearchList	
				tempObj[ v ] := ""
			OutputLists.Push( tempObj )
			if( A_Index = 1 ){
				Start_%A_Index% := pos
			}else{
				num := A_Index - 1
				End_%num% := pos - 1
				Start_%A_Index% := pos
			}
		}else{
			break
		}
	}
	Sections := []
	Loop, % OutputLists.Length() - 1
		Sections.Push( subStr( string , Start_%A_Index% , End_%A_Index% - STart_%A_Index% ) )
	num := OutputLists.Length()
	Sections.Push( subStr( string , Start_%num% ) )
	Loop, % Sections.Length()	{
		LineArray := StrSplit( Sections[ A_Index ] , "`n" , "`r" )
		Index := A_Index
		Loop, % LineArray.Length()	{
			if( InStr( SearchListString , ( out := StrSplit( Trim( LineArray[ A_Index ] ) , " " )[ 1 ] ) )  && out != "" ){
				OutputLists[ Index ][ out ] := Trim( SubStr( Trim( LineArray[ A_Index ] ) , StrLen( out ) + 1 ) )
				if( out = "identifier" )
					OutputLists[ Index ][ "DisplayValue" ] := OutputLists[ Index ][ out ]
			}
		}
	}
	return OutputLists
}
;******************************

i used a msgbox before the cmd ran to see what cmd it was running. and its using what was pulled from the orignal string. not from the edit boxs.
New Bitmap Image.jpg
New Bitmap Image.jpg (96.14 KiB) Viewed 1238 times
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: dynamic list , populated in droplist, asigned to varibles

22 Aug 2023, 10:47

This is one way that you can update your values from the edit controls.

Code: Select all

#SingleInstance, Force


SectionsArray := [ "Item1" , "Item2" , "Item3" , "Item4" , "Item5" , "Item6" ] ;A list of the sections ( Path , Device , etc )


listsArray := [] ;This would be done by the parsing function
listsArray [ 1 ] := { Item1: "Item 1" , Item2: "Item 2" , Item3: "Item 3" , Item4: "Item 4" , Item5: "Item 5" , Item6: "Item 6" }
listsArray [ 2 ] := { Item1: "Item 1" , Item2: "Item 2" , Item3: "Item 3" , Item4: "Item 4" , Item5: "Item 5" , Item6: "Item 6" }


;This happens when you select an item from the dropdownlist
SelectedList := 1

for k , v in SectionsArray { ;Loop through the list of sections and create an edit control for each one. 
	
	Gui, Add, Edit, xm w200 r1 gUpdate vEdit%k% , % listsArray[ SelectedList ][ v ]

}



Gui, Show, 
Return
GuiClose:
*ESC::ExitApp


Update:
	GuiControlGet, output ,, % A_GuiControl
	Num := SubStr( A_GuiControl , StrLen( A_GuiControl ) ) ;Each of the controls has a number at the end of it that I want to get because it matches a index in the sections array (path,etc.).
	Field := SectionsArray[ num ] ;get the name of the section ( path , etc.).
	listsArray[ SelectedList ][ Field ] := output ;update the section with the value from the edit.
	Return

joekingcool
Posts: 238
Joined: 14 Dec 2019, 20:21

Re: dynamic list , populated in droplist, asigned to varibles

24 Aug 2023, 19:31

@Hellbent

after looking over your examples more i found how to get the current edit fields. now its working great! thanks so much for your help as always and @flyingDman !

im going to continue adding features to this. but if someone wants to move this to the ahk scripts for others to use they can. or i will eventually after i get things caught up.

Code: Select all

begin:

#SingleInstance, Force
string =
( `join
Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume1
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-US
inherit                 {globalsettings}
default                 {current}
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Windows Boot Loader
-------------------
identifier              {current}
device                  partition=C:
path                    \Windows\system32\winload.efi
description             Windows 10
locale                  en-US
inherit                 {bootloadersettings}
recoverysequence        {9b37dbc3-3950-11ee-a851-a33fbd0a893f}
displaymessageoverride  Recovery
recoveryenabled         Yes
isolatedcontext         Yes
allowedinmemorysettings 0x15000075
osdevice                partition=C:
systemroot              \Windows
resumeobject            {9b37dbc1-3950-11ee-a851-a33fbd0a893f}
nx                      OptIn
bootmenupolicy          Standard

Firmware Boot Manager
---------------------
identifier              {fwbootmgr}
displayorder            {bootmgr}
                        {b63c85a7-3c94-11ee-8006-806e6f6e6963}
                        {4af6a055-3c9c-11ee-800a-806e6f6e6963}
                        {99f012a0-3c9b-11ee-9c0a-8c7f7582acf8}
timeout                 1

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=\Device\HarddiskVolume2
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
description             Windows Boot Manager
locale                  en-us
inherit                 {globalsettings}
default                 {current}
resumeobject            {bd1ef51f-3c9b-11ee-9c0a-8c7f7582acf8}
displayorder            {current}
toolsdisplayorder       {memdiag}
timeout                 30

Firmware Application (101fffff)
-------------------------------
identifier              {4af6a055-3c9c-11ee-800a-806e6f6e6963}
device                  partition=R:
path                    \EFI\BOOT\BOOTX64.EFI
description             UEFI OS

Firmware Application (101fffff)
-------------------------------
identifier              {99f012a0-3c9b-11ee-9c0a-8c7f7582acf8}
device                  partition=\Device\HarddiskVolume38
description             UEFI: Samsung Flash Drive FIT 1100, Partition 2

Firmware Application (101fffff)
-------------------------------
identifier              {b63c85a7-3c94-11ee-8006-806e6f6e6963}
device                  partition=R:
path                    \EFI\BOOT\BOOTX64.EFI
description             UEFI: WDC PC SN730 SDBPNTY-512G-1032, Partition 5
)




;********************************************************************************
;if we dont use string output above. and run cmd with admin

string = ""
stringa = ""
stringb = ""
Runwait %comspec% /c bcdedit /enum | clip,,hide
stringa := % Clipboard
Clipboard := ""
StringReplace, stringa, stringa, identifier              {bootmgr}, ,
Runwait %comspec% /c bcdedit /enum firmware | clip,,hide
stringb := % Clipboard
StringReplace, stringb, stringb, identifier              {fwbootmgr}, ,
string = %stringa% . %stringb%
;***************************************************************************************



;******************************
SearchList := [ "Identifier" , "Description" , "Device" , "Path" , "Displayorder" , "Default" , "Locale", "Systemroot" , "Osdevice" , "Resumeobject" , "NX" , "Recoveryenabled"] ;List of items to filter for.
OutputLists := Get_InsertNameHere_Object( String , SearchList ) ;returns an [ array ] of { objects } ; ||| ; i.e. OutputLists[ 1 ].Path 
;******************************
MyDisplayString := ""
Loop, % OutputLists.Length()
	MyDisplayString .= OutputLists[ A_Index ].DisplayValue "|" ;creating a list to display in the dropdownlist control. "Item|Item|Item|"
;******************************
Gui, destroy
Gui, New, +AlwaysOnTop
Gui, Add, DDL, xm ym w300 r10 vMyDDL gChangeIt choose1 AltSubmit, % MyDisplayString
index := 1
for k , v in SearchList	{
	if( v = "Identifier" )
		continue 
	Gui, Add, Text, xm y+3 w80 r5 , % v 
	Gui, Add, Edit, x+3 w230 r1 vEdit_%Index% , % OutputLists[ 1 ][ v ] 
	Index++


}

Gui, add, button, x10 y340 h25 w60 gSave, Save
Gui, add, button, x70 y340 h25 w60 gDelete, Delete
Gui, add, button, x130 y340 h25 w60 gExport, Export
Gui, add, button, x190 y340 h25 w60 gImport, Import
Gui, add, button, x250 y340 h25 w60 gDefault, Default


Gui, Show,  , BCD Boot Entry Edit Tool
return ;<<<---- End of the auto execute section of the script.
;******************************************************************************************************
GuiClose: ;<<<--- Exit Routine.
GuiContextMenu:
*ESC::ExitApp


Save:
Gui, Submit, nohide
if (SelectedIndex ="")
SelectedIndex :=1
List :=% OutputLists[ SelectedIndex ][ "Identifier" ]

;msgbox,  bcdedit /set %List% description "%Edit_1%"


Runwait, bcdedit /set %List% Description "%Edit_1%",,hide
Runwait, bcdedit /set %List% Device "%Edit_2%",,hide
Runwait, bcdedit /set %List% Path "%Edit_3%",,hide
Runwait, bcdedit /set %List% Displayorder "%Edit_4%",,hide
Runwait, bcdedit /set %List% Default "%Edit_5%",,hide
Runwait, bcdedit /set %List% Locale "%Edit_6%",,hide
Runwait, bcdedit /set %List% Systemroot "%Edit_7%",,hide
Runwait, bcdedit /set %List% Osdevice "%Edit_8%",,hide
Runwait, bcdedit /set %List% Resumeobject "%Edit_9%",,hide
Runwait, bcdedit /set %List% NX "%Edit_10%",,hide
Runwait, bcdedit /set %List% Recoveryenabled "%Edit_11%",,hide
goto, begin

Delete:
Gui, Submit, nohide
if (SelectedIndex ="")
SelectedIndex :=1
List :=% OutputLists[ SelectedIndex ][ "Identifier" ]
Runwait, bcdedit /delete %List%,,hide
goto, begin


Export:
Runwait, bcdedit /export "%A_ScriptDir%\bcd-backup.bcd",,hide
return

Import:
Runwait, bcdedit /import "%A_ScriptDir%\bcd-backup.bcd",,hide
goto, begin

Default:
return



;******************************
Changeit: ;called when something is selected in the dropdownlist
	GuiControlGet, SelectedIndex ,, MyDDL 
	Index := 1 
	Loop, % SearchList.Length()	{ 
		if( ( keyname := SearchList[ A_Index ] ) = "identifier" )
			continue
		GuiControl, , % "Edit_" Index , % OutputLists[ SelectedIndex ][ KeyName ]
		Index++
	}
	return
;******************************
Get_InsertNameHere_Object( String , SearchList ){ ;custom parsing function. returns arr[{}]
	local OutputLists := []
	SearchListString := ""
	Loop, % SearchList.Length()	
		SearchListString .= SearchList[ A_Index ] "|"
	clipArray := StrSplit( string , "`n" , "`r" )
	Loop, 	{
		if( pos := instr( string , "identifier" ,,, A_Index ) ){
			tempObj := {}
			for k , v in SearchList	
				tempObj[ v ] := ""
			OutputLists.Push( tempObj )
			if( A_Index = 1 ){
				Start_%A_Index% := pos
			}else{
				num := A_Index - 1
				End_%num% := pos - 1
				Start_%A_Index% := pos
			}
		}else{
			break
		}
	}
	Sections := []
	Loop, % OutputLists.Length() - 1
		Sections.Push( subStr( string , Start_%A_Index% , End_%A_Index% - STart_%A_Index% ) )
	num := OutputLists.Length()
	Sections.Push( subStr( string , Start_%num% ) )
	Loop, % Sections.Length()	{
		LineArray := StrSplit( Sections[ A_Index ] , "`n" , "`r" )
		Index := A_Index
		Loop, % LineArray.Length()	{
			if( InStr( SearchListString , ( out := StrSplit( Trim( LineArray[ A_Index ] ) , " " )[ 1 ] ) )  && out != "" ){
				OutputLists[ Index ][ out ] := Trim( SubStr( Trim( LineArray[ A_Index ] ) , StrLen( out ) + 1 ) )
				if( out = "identifier" )
					OutputLists[ Index ][ "DisplayValue" ] := OutputLists[ Index ][ out ]
			}
		}
	}
	return OutputLists
}
;******************************


Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: macromint, peter_ahk, Rauvagol, Spawnova, wineguy and 303 guests