Seite 1 von 1

StartMenü komplett (Benutzer & alle Benutzer) auslesen

Verfasst: 05.08.2006 17:02
von Thorsten1867
Das Problem am StartMenü ist, dass die Einträge aus zwei verschiedenen Verzeichnissen stammen und somit nicht ohne Weiteres ausgelesen werden können. Mit folgendem Code sollte es möglich sein, das StartMenü auszulesen und den Pfad eines enthaltenen Ordners zu ermitteln.

Code: Alles auswählen

; StartMenü-Eintrag auswählen (PB4)
; by Thorsten Hoeppner (Thorsten1867)
; 
#WindowID = 0
#TreeGadgetID = 1

NewList DirList.s()

Procedure.s Reg_GetValue(topKey, sKeyName.s, sValueName.s, ComputerName.s = "")
  Protected lpData.s=Space(255), GetValue.s
  Protected GetHandle.l, hKey.l, lReturnCode.l, lhRemoteRegistry.l, lpcbData.l, lType.l, lpType.l
  Protected lpDataDWORD.l
  If Left(sKeyName, 1) = "\"
    sKeyName = Right(sKeyName, Len(sKeyName) - 1)
  EndIf
  If ComputerName = ""
    GetHandle = RegOpenKeyEx_(topKey, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
  Else
    lReturnCode = RegConnectRegistry_(ComputerName, topKey, @lhRemoteRegistry)
    GetHandle = RegOpenKeyEx_(lhRemoteRegistry, sKeyName, 0, #KEY_ALL_ACCESS, @hKey)
  EndIf
  If GetHandle = #ERROR_SUCCESS
    lpcbData = 255
    GetHandle = RegQueryValueEx_(hKey, sValueName, 0, @lType, @lpData, @lpcbData)
    If GetHandle = #ERROR_SUCCESS
      Select lType
        Case #REG_SZ
          GetHandle = RegQueryValueEx_(hKey, sValueName, 0, @lType, @lpData, @lpcbData)
          If GetHandle = 0
            GetValue = Left(lpData, lpcbData - 1)
          Else
            GetValue = ""
          EndIf
        Case #REG_DWORD
          GetHandle = RegQueryValueEx_(hKey, sValueName, 0, @lpType, @lpDataDWORD, @lpcbData)
          If GetHandle = 0
            GetValue = Str(lpDataDWORD)
          Else
            GetValue = "0"
          EndIf
      EndSelect
    EndIf
  EndIf
  RegCloseKey_(hKey)
  ProcedureReturn GetValue
EndProcedure

Procedure.s GetPath(Type) ; - Return the path of some system-directorys
  location$ = Space (#MAX_PATH+1)
  Select Type
    Case -1 : GetCurrentDirectory_(#MAX_PATH,@location$)                                                              ; Current
    Case -2 : GetSystemDirectory_(@location$, #MAX_PATH)                                                              ; System
    Case -3 : GetWindowsDirectory_(@location$, #MAX_PATH)                                                             ; Windows
    Case -4 : GetTempPath_(#MAX_PATH,@location$)                                                                      ; Temp
    Case -5 : location$=GetPath($1A)+"Microsoft\Internet Explorer\Quick Launch\"                                      ; QuickLaunch
    Case -6 : location$=Reg_GetValue(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Windows\CurrentVersion","ProgramFilesDir","")  ; ProgramFiles
    Case $2B :  location$=Reg_GetValue(#HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Windows\CurrentVersion","CommonFilesDir","") ; CommonFiles
    Default ;{ SpecialFolder
      *itemid.Long = #Null
      If SHGetSpecialFolderLocation_ (0, Type, @*itemid) = #NOERROR
        If SHGetPathFromIDList_ (*itemid, @location$)=#False
          location$=""
        EndIf
      Else
        location$=""
      EndIf ;}
  EndSelect
  If location$ And Right(location$,1)<>"\" : location$+"\" : EndIf
  ProcedureReturn location$
EndProcedure

Procedure EntryExists(entry.s, dir.s())
  ForEach dir()
    If dir() = entry
      ProcedureReturn #True
    EndIf
  Next
  ProcedureReturn #False
EndProcedure

Procedure GetStartMenu(directory.s, dir.s(), root.s)
  If Right(directory,1) <> "\" : directory + "\" : EndIf
  UsedDirectory = ExamineDirectory(#PB_Any, directory,"*.*") 
  While NextDirectoryEntry(UsedDirectory) 
    entryname.s = DirectoryEntryName(UsedDirectory) 
    If entryname = "." Or entryname = ".." : Continue : EndIf 
    If DirectoryEntryType(UsedDirectory) = 2
      GetStartMenu(directory+entryname, dir(), root)
      dir.s =  RemoveString(directory+entryname, root)
      If Not EntryExists(dir, dir())
        AddElement(dir())
        dir() = dir
      EndIf
    EndIf
  Wend
  FinishDirectory(UsedDirectory)
EndProcedure

Procedure JoinStartMenu(dir.s())
User$ = GetPath(#CSIDL_PROGRAMS)
AllUser$ = GetPath(#CSIDL_COMMON_PROGRAMS)
ClearList(dir())
GetStartMenu(User$, dir(), User$)
GetStartMenu(AllUser$, dir(), AllUser$)
SortList(dir(), 2)
EndProcedure

Procedure.s GetTreePath(GID.l)
  If Not IsGadget(GID) : ProcedureReturn "" : EndIf
  selected.l = GetGadgetState(GID)
  path$ = GetGadgetText(GID)
  level.b = GetGadgetItemAttribute(GID, selected, #PB_Tree_SubLevel)
  Repeat
    selected - 1
    If  GetGadgetItemAttribute(GID, selected, #PB_Tree_SubLevel) >= level : Continue : EndIf
    path$ = GetGadgetItemText(GID, selected, #Null) + "\" + path$
    level = GetGadgetItemAttribute(GID, selected, #PB_Tree_SubLevel)
  Until level = 0 Or selected < 0
  ProcedureReturn path$
EndProcedure

;- Fensteraufruf - Treegadget

If OpenWindow(#WindowID, 0, 0, 200, 180, "StartMenü", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(#WindowID))
  TreeGadget(#TreeGadgetID, 10, 10, 180, 160)
  
  JoinStartMenu(DirList()) ; Startmenü Benutzer & alle Benutzer auslesen
  
  ForEach DirList() ; In TreeGadget eintragen
    level.b = CountString(DirList(),"\")
    AddGadgetItem (#TreeGadgetID, -1, StringField(DirList(),level+1,"\"), 0, level)
  Next
  
  Repeat
    If WaitWindowEvent() = #PB_Event_Gadget
      If EventGadget() = #TreeGadgetID
        ; Selektierter Treegadget-Eintrag
        Debug "StartMenü: " + GetTreePath(#TreeGadgetID)
      EndIf
    EndIf
  Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
(Die Prozedur GetPath() könnte man hierfür natürlich entsprechend kürzen, aber so ist sie universell zu gebrauchen. )

Verfasst: 05.08.2006 21:10
von pankgraf
Nach meiner Meinung ein nützliches Programm. Schade, daß bei mir diese Fehlermeldung kommt:

Code: Alles auswählen

jaPBe - Compiler Fehler
Line 17 - GetRegKey() is not a function, array, macro or linked list
Ist dir bei Drag & Drop eine Prozedur verloren gegangen oder benutzt du eine Userlib, die den Zugriff auf Registrierungs-Funktionen bietet?

Verfasst: 05.08.2006 21:18
von ts-soft
Die fehlenden Routinen, angepaßt an PB4 findeste im IncludePack:
http://www.purebasic.fr/german/viewtopic.php?t=9190
Registry_Include.pbi

Verfasst: 05.08.2006 21:35
von Thorsten1867
Sorry, habe da eine Libary verwendet.

Habe die entsprechende Procedure hinzugefügt und das Beispiel geändert.
Sollte jetzt funktionieren.

Verfasst: 05.08.2006 22:41
von pankgraf
Vielen Dank für eure schnellen Antworten!

@ts-soft
Ich möchte gleich die Gelegenheit nutzen, um dir Danke für deinen Einsatz im Forum und für deine PB-Programme zu sagen. Natürlich darf ich dabei Kiffi nicht vergessen. Auch an ihn ergeht eine Danksagung.
Ihr seid ein gutes Team!


@Thorsten1867
Danke, jetzt klappt es. Sehr gute Arbeit!

Verfasst: 05.08.2006 23:03
von ts-soft
pankgraf hat geschrieben:@ts-soft
Ich möchte gleich die Gelegenheit nutzen, um dir Danke für deinen Einsatz im Forum und für deine PB-Programme zu sagen. Natürlich darf ich dabei Kiffi nicht vergessen. Auch an ihn ergeht eine Danksagung.
Ihr seid ein gutes Team!
Das tut gut :D
Ich hab immer das Gefühl, das es kaum genutzt wird, bzw. das viele von
PBOSL und ähnlichen Dingen überfordert sind. Aber Ideen, wie man es noch
einfacher macht, fehlen mir.

Im Moment gibts hier ja mehr Einsteiger als "Erfahrene User", da wäre das
erstellen von Tutorials wohl wichtiger als Includes oder Libs, aber da bin ich
dann überfordert.

Danke erstmal, auch im Namen von Kiffi (wird wohl einverstanden sein :wink: )

Verfasst: 05.08.2006 23:07
von Alves
Wenn es jetzt so kommt, sage ich auch mal Danke, da ihr wirklich sehr hilfreich seid! ts, Danke auch für die Hilfe im USB Thread, meine aber, ich habe jetzt eine iPod-seitige Lösung gefunden. Trotzdem Danke! (Falls es doch nicht funzt, werdet ihr es erfahren!)

Verfasst: 05.08.2006 23:42
von Kiffi
ts-soft hat geschrieben:Danke erstmal, auch im Namen von Kiffi (wird wohl einverstanden sein :wink: )
Klar doch! :D

@pankgraf: :allright:

Grüße ... Kiffi

Verfasst: 07.08.2006 09:26
von gnozal
pankgraf hat geschrieben:Nach meiner Meinung ein nützliches Programm. Schade, daß bei mir diese Fehlermeldung kommt:

Code: Alles auswählen

jaPBe - Compiler Fehler
Line 17 - GetRegKey() is not a function, array, macro or linked list
Ist dir bei Drag & Drop eine Prozedur verloren gegangen oder benutzt du eine Userlib, die den Zugriff auf Registrierungs-Funktionen bietet?
In jaPBe, just include Registry.pbi (Reg_GetValue() is in it).

Verfasst: 07.08.2006 17:00
von pankgraf
@gnozal

Vielen Dank für deine Antwort!
Inzwischen habe ich den ausgezeichneten IncludeViewer 1.0 entdeckt und dabei auch die Registry_Include.pbi gefunden.
Solche vorzüglichen Tools und Programme (dazu gehört u.A. auch jaPBe) machen das Arbeiten mit PureBasic zu einer reinen Freude.

Gnozal, du investierst viel Freizeit, um der PB-Community die Arbeit zu erleichtern. Genau wie ts-soft, Kiffi und einige Andere, hast du eigentlich vielmehr als ein Dankeschön verdient. Ich sag mal zu euch allen:
  • Vergelts Gott!