Registryeinträge in Listenfeld übernehmen

  • Ich möchte gerne folgendes realisieren:
    Per Schlatfläche sollen bestimmte Registryeinträge in ein Listenfeld übernommen werden. Und zwar jeder Keywert in eine eigene Spalte im Listenfeld.

    Das ganze sieht momentan so aus:

    [autoit]

    Select
    Case $nMsg = $Button1
    $i = 1
    Dim $Programm[4]
    while $i <=3
    $var = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup\" & $i, "Name")
    $Programm[$i] = GUICtrlCreateListViewItem($var, $ListView1)
    GUICtrlSetData($Programm[$i],$var)
    $i = $i + 1
    WEnd
    EndSelect

    [/autoit]

    Funktioniert prinzipel problemlos.
    Nur möchte ich den Wert 4 bzw. 3 durch die Anzahl ersetzen der wirklich vorhandenen Schlüssel in der Registry.
    Wie kann ich das vorher überprüfen?

    meine zweite Frage wäre, wie fragt mein einen Klick auf einen der Listenfeldeinträge ab?

    3 Mal editiert, zuletzt von DerSchatten (1. September 2007 um 22:04)

    • Offizieller Beitrag

    1. Schau dir mal RegEnumKey() an

    2. Das Ereignis $NM_CLICK kannst du dafür nutzen.
    Wenn das Ereignis eintritt,fragst du den Index des selektierten ListView-Eintrages ab und kannst damit dann den Text des Eintrags zurückgeben.

    Spoiler anzeigen
    [autoit]

    #include <guiconstants.au3>
    #include <guilistview.au3>
    Global $listview
    Global Const $WM_NOTIFY = 0x004E
    Global Const $NM_FIRST = 0
    Global Const $NM_LAST = (-99)
    Global Const $NM_OUTOFMEMORY = ($NM_FIRST - 1)
    Global Const $NM_CLICK = ($NM_FIRST - 2)
    Global Const $NM_DBLCLK = ($NM_FIRST - 3)

    [/autoit] [autoit][/autoit] [autoit]

    $main = GUICreate('')
    $listview = GUICtrlCreateListView ("Name|Ping" , 9,150,191,580, -1, BitOR($LVS_EX_REGIONAL, $LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))
    GUICtrlCreateListViewItem("G0011111" & "|" & "3ms",$listview )
    GUIRegisterMsg($WM_NOTIFY, "MY_WM_COMMAND")
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $msg = GUIGetMsg()
    Select
    Case $msg = - 3
    Exit
    ;Case $msg = $listview
    ;_GUICtrlListViewSort($B_DESCENDING_listview , $B_DESCENDING_listview , GUICtrlGetState($B_DESCENDING_listview ))
    EndSelect
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID
    Local $tagNMHDR, $event
    Switch $wParam
    Case $listview
    $tagNMHDR = DllStructCreate("int;int;int", $lParam)
    If @error Then Return
    $event = DllStructGetData($tagNMHDR, 3)
    Switch $event
    Case $NM_CLICK
    MsgBox(64, 'Info', 'You clicked the listview')
    EndSwitch
    EndSwitch
    $tagNMHDR = 0
    EndFunc

    [/autoit]
  • Hallo,
    Punkt 1 konnte ich lösen.

    Für das zweite Problem habe ich noch keine Lösung gefunden.
    Die Abfrage des Klicks ist nicht das Problem, sondern den "Index des selektierten ListView Eintrages abzufragen".

    Kann mir da jemand weiterhelfen?

    • Offizieller Beitrag

    Hier das Bsp.aus der Hilfe. Ich habe es bei Ausgabe String erweitert, sodass auch der Text des markierten Eintrages zurückgegeben wird.

    Tipp: Wenn du nur einen bestimmten (angeklickten) Spalteneintrag ermitteln möchtest, kannst du den Index des SubItems(Spalte) mit GUICtrlGetState() ermitteln.

    Spoiler anzeigen
    [autoit]

    #include <GuiConstants.au3>
    #include <GuiListView.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt ('MustDeclareVars', 1)
    Dim $listview, $Btn_Exit, $msg, $Status, $Btn_piped, $Btn_array
    GUICreate("ListView Get Selected Indices", 392, 322)

    [/autoit] [autoit][/autoit] [autoit]

    $listview = GUICtrlCreateListView("col1|col2|col3", 40, 30, 310, 149, BitOR($LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER))
    GUICtrlSendMsg($listview, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
    GUICtrlSendMsg($listview, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
    GUICtrlCreateListViewItem("line1|data1|more1", $listview)
    GUICtrlCreateListViewItem("line2|data2|more2", $listview)
    GUICtrlCreateListViewItem("line3|data3|more3", $listview)
    GUICtrlCreateListViewItem("line4|data4|more4", $listview)
    GUICtrlCreateListViewItem("line5|data5|more5", $listview)
    $Btn_piped = GUICtrlCreateButton("Return string", 75, 210, 90, 30)
    $Btn_array = GUICtrlCreateButton("Return array", 180, 210, 90, 30)
    $Btn_Exit = GUICtrlCreateButton("Exit", 150, 260, 70, 30)
    $Status = GUICtrlCreateLabel("", 0, 302, 392, 20, BitOR($SS_SUNKEN, $SS_CENTER))
    GUISetState()
    While 1
    $msg = GUIGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE Or $msg = $Btn_Exit
    ExitLoop
    Case $msg = $Btn_piped
    Local $s_indices = _GUICtrlListViewGetSelectedIndices($listview)
    If($s_indices == $LV_ERR) Then
    GUICtrlSetData($Status, "Not Items Selected")
    Else
    MsgBox(0,"Selected", "Index: " & $s_indices & @LF & _
    "Text: " & _GUICtrlListViewGetItemText($listview, $s_indices))
    EndIf
    Case $msg = $Btn_array
    Local $a_indices = _GUICtrlListViewGetSelectedIndices($listview,1)
    If(IsArray($a_indices))Then
    Local $i
    For $i = 1 To $a_indices[0]
    MsgBox(0,"Selected", $a_indices[$i])
    Next
    Else
    GUICtrlSetData($Status, "Not Items Selected")
    EndIf
    EndSelect
    WEnd
    Exit

    [/autoit]
  • Hier ist ein Beispiel:

    Spoiler anzeigen
    [autoit]

    #include <guiconstants.au3>
    #include <guilistview.au3>
    Global $listview
    Global Const $WM_NOTIFY = 0x004E
    Global Const $NM_FIRST = 0
    Global Const $NM_LAST = (-99)
    Global Const $NM_OUTOFMEMORY = ($NM_FIRST - 1)
    Global Const $NM_CLICK = ($NM_FIRST - 2)
    Global Const $NM_DBLCLK = ($NM_FIRST - 3)

    $main = GUICreate('Test Gui',300,300)
    $listview = GUICtrlCreateListView ("Name|Ping" , 9,9,280,280, -1, BitOR($LVS_EX_REGIONAL, $LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES))
    GUICtrlCreateListViewItem("G0011111" & "|" & "3ms",$listview )
    GUICtrlCreateListViewItem("Test Key1",$listview )
    GUIRegisterMsg($WM_NOTIFY, "MY_WM_COMMAND")
    GUISetState()

    While 1
    $msg = GUIGetMsg()
    Select
    Case $msg = - 3
    Exit
    ;Case $msg = $listview
    ;_GUICtrlListViewSort($B_DESCENDING_listview , $B_DESCENDING_listview , GUICtrlGetState($B_DESCENDING_listview ))
    EndSelect
    WEnd

    Func MY_WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    ;#forceref $hWndGUI, $MsgID
    Local $tagNMHDR, $event
    Switch $wParam
    Case $listview
    $tagNMHDR = DllStructCreate("int;int;int", $lParam)
    If @error Then Return
    $event = DllStructGetData($tagNMHDR, 3)
    Switch $event
    Case $NM_CLICK
    Local $s_indices = _GUICtrlListViewGetSelectedIndices($listview)
    Switch $s_indices
    Case -1
    MsgBox(0,"Selected", "No Items Selected")
    Case Else
    MsgBox(0,"Selected", "Index: " & $s_indices & @LF & _
    "Text: " & _GUICtrlListViewGetItemText($listview, $s_indices))
    EndSwitch
    EndSwitch
    EndSwitch
    $tagNMHDR = 0
    EndFunc

    [/autoit]

    Einmal editiert, zuletzt von progandy (2. September 2007 um 17:34)

    • Offizieller Beitrag

    Du kannst auch ohne MY_WM_COMMAND arbeiten, wenn du nur SingleClick abfragst.
    Wichtig ist, du mußt für jedes Item ein Handle erzeugen (z.B. $arItem=..) und darauf mit dem Event ListViewClick verweisen.

    Spoiler anzeigen
    [autoit]

    #include <GuiConstants.au3>
    #include <GuiListView.au3>
    Opt ("GUIOnEventMode", 1)
    Dim $gui, $listview
    $gui = GUICreate("ListView Get Selected Indices", 392, 322)
    GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
    $listview = GUICtrlCreateListView("col1|col2|col3", 40, 30, 310, 149, BitOR($LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER))
    GUICtrlSendMsg($listview, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
    GUICtrlSendMsg($listview, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)
    $item1 = GUICtrlCreateListViewItem("line1|data1|more1", $listview)
    $item2 = GUICtrlCreateListViewItem("line2|data2|more2", $listview)
    $item3 = GUICtrlCreateListViewItem("line3|data3|more3", $listview)
    $item4 = GUICtrlCreateListViewItem("line4|data4|more4", $listview)
    $item5 = GUICtrlCreateListViewItem("line5|data5|more5", $listview)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = $item1 To $item5
    GUICtrlSetOnEvent($i, '_ListViewClick')
    Next

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(100)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func Form1Close()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _ListViewClick()
    Local $s_indices = _GUICtrlListViewGetSelectedIndices($listview)
    MsgBox(0,"Selected", "Index: " & $s_indices & @LF & _
    "Text: " & _GUICtrlListViewGetItemText($listview, $s_indices))
    EndFunc

    [/autoit]
  • Danke euch! Das sollte mir erst mal weiterhelfen.

    Habe da noch eine weitere Frage:
    Ich habe in der Registry durchnummerierte Schlüssel erstellt:
    1
    2
    3
    5

    Wird nun einer der Schlüssel dazwischen gelöscht, fehlt diese Nummer dann.
    Jetzt möchte ich gerne abfragen welche Nummer noch frei ist und per:

    [autoit]

    RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup\" & $var2, "Name", "REG_SZ", GUICtrlRead($Input1))

    [/autoit]


    einen freien nummerierten Schlüssel erstellen.
    Damit das ganze dann so aussieht:
    1
    2
    3
    4
    5

    Ich habe schon einiges ausprobiert.
    Aber ich komme auf keinen grünen Zweig.
    Vielleicht habt ihr da auch einen Tip für mich.

    • Offizieller Beitrag

    Das ist sicher möglich, aber ich bin dafür möglichst einfache Wege zu gehen ;)
    Es besteht ja keine Notwendigkeit eine Reihenfolge der Nummerierung beizubehalten.
    Also lies einfach alle Schlüssel in diesem Zweig aus und verwende als neuen Schlüssel: letzter Schlüssel + 1
    Welchen Namen der Schlüssel annimmt ist doch letztendlich ohne Belang.

  • Daran habe ich auch schon gedacht. Dies stellt mich allerdings vor ein ähnliches Problem.
    Mit RegEnumKey komme ich nicht weiter. Es kommt ja auch vor das der Schlüssel mit der Nummer 10 zb. zwischen der Nummerierung steht:
    1
    10
    2
    3
    4

    Gibt es sowas wie. "Gib die höchste Nummer aus" ?

    • Offizieller Beitrag
    [autoit]

    #include <array.au3>

    [/autoit][autoit][/autoit][autoit]

    Dim $arSubKey[1] = [0]
    $i = 1
    While 1
    $subkey = RegEnumKey('HKEY_CURRENT_USER\Software', $i)
    If @error Then ExitLoop
    $arSubKey[0] += 1
    ReDim $arSubKey[UBound($arSubKey)+1]
    $arSubKey[UBound($arSubKey)-1] = $subkey
    $i += 1
    WEnd

    [/autoit][autoit][/autoit][autoit]

    _ArrayDisplay($arSubKey)

    [/autoit][autoit][/autoit][autoit]

    ; wenn du numerische Einträge hast kannst du den größten Wert so ausgeben:
    ;~ MsgBox(0, 'größter numerischer Wert', _ArrayMax($arSubKey, 1, 1) )

    [/autoit]
  • Bekomme den Fehler: Array variable has incorrect number ....

    [autoit]

    Dim $arSubKey[1] = [0]
    $i = 1
    While 1
    $subkey = RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup", $i)
    ;$var2 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup\" & $i, "Name")
    if @error Then ExitLoop
    $arSubKey[0] += 1
    ReDim $arSubKey[UBound($arSubKey)+1]
    $arSubKey[UBound($arSubKey)-1] = $subkey
    $i += 1
    WEnd
    ;_ArrayDisplay($arSubKey)
    MsgBox(0, 'größter numerischer Wert', _ArrayMax($arSubKey, 1, 1))

    [/autoit]

    Wozu dient das _ArrayDisplay($arSubKey) ?

    • Offizieller Beitrag
    Zitat

    Original von DerSchatten
    Bekomme den Fehler: Array variable has incorrect number ....
    Wozu dient das _ArrayDisplay($arSubKey) ?

    Das _ArrayDisplay diente jetzt nur dazu, die ausgelesenen SubKeys anzuzeigen.

    Ich vermute aber, dass du gar keine Subkeys auslesen willst, sondern die Werte EINES Keys. Also das, was auf der rechten Seite des Regeditors steht. (li. Seite = Schlüsselbaum; re. Seite = WertName/WertInhalt)
    Dann ersetze einfach RegEnumKey durch RegEnumVal und gib den korrekten Schlüssel an.

  • Nein, es handelt sich tatsächlich um Keys, keine Werte:

    Bsp:

    HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup\1
    HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup\2
    HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup\3
    HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup\4
    HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup\5
    HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup\6

    Habe aber die Ursache gefunden.
    Und zwar tritt der Fehler dann auf, wenn dieser Key nicht existiert.
    Das heißt man müßte zuvor abfragen ob dieser existiert.

    • Offizieller Beitrag
    Zitat

    Original von DerSchatten
    Habe aber die Ursache gefunden.
    Und zwar tritt der Fehler dann auf, wenn dieser Key nicht existiert.
    Das heißt man müßte zuvor abfragen ob dieser existiert.

    Nö, muß man nicht.
    Du fragst die INSTANZEN unterhalb des Keys

    [autoit]

    RegEnumKey("HKEY_LOCAL_MACHINE\SOFTWARE\MasterBackup", Instanz)

    [/autoit]


    ab.
    In jedem Schleifenumlauf wird die Nummer der Instanz um 1 erhöht. Das hat nichts mit dem Namen des Schlüssels zu tun.
    Sind dort 5 Einträge und es wird nach Instanz 6 gefragt entsteht ein Fehler und die Schleife wird verlassen.

  • Ok, jedoch muß der Key MasterBackup existieren.

    Ich habe jetzt nur noch meine Schwierigkeit das ganze in die RegWrite Funktion einzubauen.
    Welche Variable ist denn nun ausschlaggebend?
    $i liefert mir immer den Wert 5
    $arSubKey gar nichts.

    • Offizieller Beitrag

    Hier mal ein Test Szenario.
    - erstellt die Unterschlüssel \TEST\1 bis ..\19 (nur ungerade Werte)
    - gibt alle Unterschlüssel aus
    - zeigt größten Wert der Unterschlüssel
    - löscht alle Testschlüssel wieder

    Das ConsoleWrite() dient nur als Kontrolle ob alles fehlerfrei abläuft.

    Spoiler anzeigen
    [autoit]

    #include <array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To 20 Step 2 ; erzeugt Schlüssel mit ungeraden Zahlen bis 19
    ConsoleWrite($i & ' RegWrite= '& RegWrite("HKCU\TEST\" & $i, '', 'REG_SZ', '') & ' Fehler: ' &@error & @CRLF)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Dim $arSubKey[1] = [0]
    $i = 1
    While 1
    $subkey = RegEnumKey("HKCU\TEST", $i)
    If @error Then ExitLoop
    $arSubKey[0] += 1
    ReDim $arSubKey[UBound($arSubKey)+1]
    $arSubKey[UBound($arSubKey)-1] = $subkey
    $i += 1
    WEnd
    _ArrayDisplay($arSubKey, 'Testschlüssel')
    MsgBox(0, 'größter numerischer Wert', _ArrayMax($arSubKey, 1, 1)) ; größter Wert 19

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite($i & ' RegDelete= '& RegDelete("HKCU\TEST") & ' Fehler: ' &@error & @CRLF) ; Testschlüssel löschen

    [/autoit]