vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
sevDataGrid - Gönnen Sie Ihrem SQL-Kommando diesen krönenden Abschluß!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik:    |   VB-Versionen: VB4, VB5, VB601.08.01
Alternative DriveListBox

Ein Beispiel für eine DriveListBox - Marke Eigenbau.

Autor:  Dieter OtterBewertung:     [ Jetzt bewerten ]Views:  1.501 
http://www.tools4vb.de/System:  Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt 

Im Normalfall reicht die Standard-DriveListBox von Visual-Basic völlig aus. Was jedoch nicht so schön ist, daß CDROM-Laufwerke nur mit dem jeweiligen Laufwerksbuchstaben aufgeführt sind - und nicht zusätzlich die Datenträgerbezeichnung angezeigt wird, wie das z.B. bei den Festplatten-Laufwerken der Fall ist.

Also liegt es nahe seine eigene DriveListBox "zusammenzubauen". Um nicht auf die schönen kleinen Bildsymbole vor den jeweiligen Laufwerks-Einträgen verzeichten zu müssen, sollten Sie eine ImageComboBox anstelle der normalen Standard Combobox verwenden. Die ImageComboBox ist Bestandteil der Microsoft Windows Common Control (MSCOMCTL.OCX). Also fügen Sie Ihrem Projekt zunächst diese Komponente hinzu (Menü Projekt - Komponenten).

Plazieren Sie das ImageCombo auf die Form, setzen die Eigenschaft Locked = True und plazieren irgendwo daneben noch eine Abbildungsliste (ImageList), welche die benötigten Bildsymbole enthalten muss. Fügen Sie also der ImageList die entsprechenden Bildsymbole hinzu. Für unser Beispiel werden folgende Symbole benötigt:

Wie können nun die einzelnen verfügbaren Laufwerksbuchstaben ermittelt werden?
Nun ja. Wir durchlaufen eine For...Next-Schleife von 65 (A) bis 90 (Z). Über die Windows API-Funktion GetDriveType ermitteln wir den Typ des Laufwerks. Je nach fügen wir dann der ImageComboBox den entsprechenden Eintrag hinzu, natürlich unter Verwendung des korrekten Symbols. Vorher wird noch eben schnell die Datenträgerbezeichnung ermittelt - und zwar erfolgt das über die API-Funktion GetVolumeInformation. Hier müssen wir allerdings zwischen normalen logischen Laufwerken und Netz-Laufwerken unterscheiden. Handelt es sich bei dem Laufwerk um ein Netz-Laufwerk, so soll nicht die Datenträgerbezeichnung, sondern vielmehr der Computernamen ermittelt werden. Auch hierfür stellt uns das Windows-API eine entsprechende Funktion zur Verfügung: WNetGetConnection.

Nachfolgend der Code:

' zunächst die benötigten API-Deklarationen
Private Declare Function GetDriveType Lib "kernel32" _
  Alias "GetDriveTypeA" ( _
  ByVal nDrive As String) As Long
 
Private Declare Function GetVolumeInformation Lib "kernel32" _
  Alias "GetVolumeInformationA" ( _
  ByVal lpRootPathName As String, _
  ByVal lpVolumeNameBuffer As String, _
  ByVal nVolumeNameSize As Long, _
  lpVolumeSerialNumber As Long, _
  lpMaximumComponentLength As Long, _
  lpFileSystemFlags As Long, _
  ByVal lpFileSystemNameBuffer As String, _
  ByVal nFileSystemNameSize As Long) As Long
 
Private Declare Function WNetGetConnection Lib "Mpr.dll" _
  Alias "WNetGetConnectionA" ( _
  ByVal lpszLocalName As String, _
  ByVal lpszRemoteName As String, _
  cbRemoteName As Long) As Long
 
Private Declare Function SendMessage Lib "user32" _
  Alias "SendMessageA" ( _
  ByVal hWnd As Long, _
  ByVal wMsg As Long, _
  ByVal wParam As Long, _
  lParam As Any) As Long
 
Private Const RESOURCETYPE_DISK = &H1
 
Private Const DRIVE_REMOVABLE = 2
Private Const DRIVE_FIXED = 3
Private Const DRIVE_REMOTE = 4
Private Const DRIVE_CDROM = 5
Private Const DRIVE_RAMDISK = 6
 
' DriveListBox füllen
Private Sub InitDriveList()
  Dim I As Integer
  Dim Drive As String
  Dim DriveType As Long
  Dim VolName As String
 
  With ImageCombo1
    .ComboItems.Clear
    .ComboItems.Add , "Desktop", "Desktop", 1
    .ComboItems.Add , "Arbeitsplatz", "Arbeitsplatz", _
      2, , 1
 
    ' Laufwerksbuchstaben
    For I = 65 To 90
      Drive = Chr$(I) + ":\"
      DriveType = GetDriveType(Drive)
      If DriveType = DRIVE_REMOTE Then
        ' Netzlaufwerk
        VolName = WNetGetVolumeName(Drive)
 
      ElseIf DriveType = DRIVE_REMOVABLE And I < 68 Then
        ' Diskettenlaufwerk
        VolName = "3,5-Diskette"
      Else
        ' Wechseldatenträger, z.B. ZIP-Laufwerk
        VolName = GetVolumeName(Drive)
        If VolName = "" And DriveType = _
          DRIVE_REMOVABLE Then _
          VolName = "Wechseldatenträger"
      End If
      VolName = LTrim$(VolName + " (" + Left$(Drive, 2) _
        + ")")
 
      ' Eintrag der ComboBox hinzufügen
      ' unter Berücksichtigung der entsprechenden
      ' Bildsymbole
      Select Case DriveType
        Case 2
          If I < 68 Then
            .ComboItems.Add , Drive, VolName, 3, , 2
          Else
            .ComboItems.Add , Drive, VolName, 7, , 2
          End If
        Case 3
          .ComboItems.Add , Drive, VolName, 5, , 2
        Case 4
          .ComboItems.Add , Drive, VolName, 8, , 2
        Case 5
          .ComboItems.Add , Drive, VolName, 6, , 2
      End Select
    Next I
 
    ' aktuelles Laufwerk selektieren
    Set .SelectedItem = _
      .ComboItems(UCase$(Left$(CurDir$(), 3)))
  End With
End Sub
 
' Datenträgerbezeichnung
Private Function GetVolumeName(ByVal Drive As String) _
  As String
 
  Dim r As Long
  Dim DrvVolumeName As String
  Dim sPos As Integer
  Dim Unused1 As Long
  Dim Unused2 As Long
  Dim Unused3 As Long
  Dim UnusedStr As String
 
  DrvVolumeName = Space$(41)
  UnusedStr = Space$(32)
 
  If GetVolumeInformation(Drive, DrvVolumeName, _
    Len(DrvVolumeName), Unused1, Unused2, Unused3, _
    UnusedStr, Len(UnusedStr)) Then
    sPos = InStr(DrvVolumeName, Chr$(0))
    If sPos Then DrvVolumeName = Left$(DrvVolumeName, _
      sPos - 1)
  End If
 
  GetVolumeName = Trim$(UCase$(Left$(DrvVolumeName, 1)) + _
    LCase$(Mid$(DrvVolumeName, 2)))
End Function
 
' Natzlaufwerk-Bezeichnung
Private Function WNetGetVolumeName(ByVal Drive As String) _
  As String
 
  Dim Result As Long
  Dim VolName As String
  Dim nSize As Long
  Dim Text As String
  Dim sPos As Integer
 
  On Local Error Resume Next
  VolName = Space$(256)
  nSize = Len(VolName)
  Result = WNetGetConnection(Left$(Drive, 2), VolName, _
    nSize)
  If Result = 0 Then
    VolName = Left$(VolName, InStr(VolName, Chr$(0)) - 1)
    If Left$(VolName, 2) = "\\" Then
      VolName = Mid$(VolName, 3)
      sPos = InStr(VolName, "\")
      If sPos > 0 Then
        Text = Left$(VolName, sPos - 1)
        VolName = Mid$(VolName, sPos + 1) + " auf " + _
          Chr$(34) + UCase$(Left$(Text, 1)) + _
          LCase$(Mid$(Text, 2)) + Chr$(34)
      End If
    End If
  End If
  WNetGetVolumeName = VolName
End Function

Im Form_Load-Ereignis setzen Sie nun folgenden Aufruf, um die ImageComboBox mit den verfügbaren Laufwerksangaben zu füllen:

Private Sub Form_Load()
  ' DriveListe initialisieren
  InitDriveList
End Sub

Um die ImageComoboBox beim Erhalt des Fokus automatisch aufzuklappen (auch wenn nicht explizit auf den Abrufpfeil geklickt wird), wird noch folgender Code benötigt:

' ImageCombo bei Erhalt des Fokus aufklappen
Private Sub ImageCombo1_GotFocus()
  ImageCombo1.SelStart = 0
  ImageCombo1.SelLength = 999
  SendMessage ImageCombo1.hWnd, &H14F, True, 0
End Sub

Das waren dann auch schon der gesamte Programmieraufwand für Ihre eigene DriveListBox.