VB-Homepage Tipp 384

Comboboxen - Anzeigefenster in Ausrichtung und Größe modifizieren

Ein feiner Tipp, der wieder etwas mehr Benutzerfreundlichkeit mitbringt.
Nutzen Sie für Ihr Projekt Comboboxen, dann wird beim aktivieren, die Anzeigeliste gerade mal so breit angezeigt, wie die Combobox selber breit ist.
Sind Ihre Einträge aber länger, und konnten Sie die Combobox aus Platzgründen nicht breiter definieren, kann man ggf. den Inhalt der Anzeige garnicht definieren, weil der wichtige Teil vielleicht gerade nicht mehr angezeigt werden kann.

Um so besser wird es mit diesem Tipp, der Ihnen ermöglicht, erstens die Höhe und Breite des aufzuklappenden Fenster, aber auch die Ausrichtung der Anzeige vorzugeben.
  1. Benötigen Sie ein neues Projekt mit einer Form und einem Modul

  2. Widmen wir uns zuerst dem Modul. Fügen Sie nachfolgenden Code in die
    entsprechenden Prozeduren ein.
    Allgemein/Deklarationen

    '************************************************
    Option Explicit
    '************************************************
    Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
    End Type

    Private Const GWL_WNDPROC& = (-4)
    Private Const WM_CTLCOLORLISTBOX = &H134

    Private Declare Function SetWindowLong& Lib "user32" Alias "SetWindowLongA" (ByVal hwnd&, ByVal nIndex&, ByVal dwNewLong&)
    Private Declare Function CallWindowProc& Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc&, ByVal hwnd&, ByVal MSG&, ByVal wParam&, ByVal lParam&)
    Private Declare Function SetWindowPos& Lib "user32" (ByVal hwnd&, ByVal hWndInsertAfter&, ByVal x&, ByVal y&, ByVal cx&, ByVal cy&, ByVal wFlags&)
    Private Declare Function GetWindowRect& Lib "user32" (ByVal hwnd&, lpRect As RECT)

    Private OldProc& '# Adresse der originalen Fensterprozedur

    Private lBreit&, lHoch& '# Breite und Höhe der Liste in Pixel
    Private lLeft&, lTop& '# Links- und Top-Position der Liste in Pixel
    Private cRect As RECT '# aktuelles Rechteck der Box
    Private cHwnd& '# Handle der Combobox
    Private bDiff& '# Breitendifferenz zwischen Box und Liste
    Private lHwnd& '# Handle der Comboliste
    Public Alignment% '# Ausrichtung der Liste; Public wegen Demo, sonst Private

    Allgemein/SubClass
    Sub SubClass(ByVal box As ComboBox, ByVal YesNo As Boolean, Optional LB&, Optional LH&, Optional Align% = 0)
    Dim rct As RECT

    Select Case YesNo

    Case True
    '# Subclassing der Fensterprozedur für die Box
    OldProc = SetWindowLong(box.hwnd, GWL_WNDPROC, AddressOf WindowProc)
    '# Bereitstellen der Parameter
    lBreit = LB: lHoch = LH
    Alignment = Align
    cHwnd = box.hwnd
    Call GetWindowRect(cHwnd, rct) '# Combobox
    With rct
    bDiff = lBreit - (.Right - .Left) '# Breitendifferenz speichern
    End With

    Case False
    '# Wiederherstellen des Originalzustandes
    Call SetWindowLong(box.hwnd, GWL_WNDPROC, OldProc)
    End Select
    End Sub

    Allgemein/WindowProc
    Public Function WindowProc&(ByVal hwnd&, ByVal wMsg&, ByVal wParam&, ByVal lParam&)

    If wMsg = WM_CTLCOLORLISTBOX And lHwnd = 0 Then lHwnd = lParam

    '# &H14 wird nur einmal vor dem Aufklappen gesendet.
    If wMsg = &H14 Then
       Call GetWindowRect(cHwnd, cRect) '# Aktuelle Position der Box ermitteln

       With cRect
          lTop = .Bottom

          Select Case Alignment
             Case 0 '# linksbündig
                lLeft = .Left
             Case 1 '# rechtsbündig
                lLeft = .Left - bDiff
             Case 2 '# zentriert
                lLeft = .Left - bDiff \ 2
          End Select
       End With

       '# Liste entsprechend positionieren
       Call SetWindowPos(lHwnd, 0, lLeft, lTop, lBreit, lHoch, 0)
    End If

    WindowProc = CallWindowProc(OldProc, hwnd, wMsg, wParam, lParam)

    End Function

  3. Widmen wir uns nun der Form.
    Zuersteinmal benötigen Sie zwei Comboboxen.
    Die eine soll uns später den "Normalzustand" und die andere den modifizierten Zustand darstellen.
    Combo1 (modifiziert) - Combo2 (normal)

    Desweiteren benötigen Sie, zum wechseln der Ausrichtung, drei Optionbutton. Fügen Sie einen der Form hinzu und erstellen Sie sich zwei weitere Kopien davon, so erhalten Sie Option1(0) - Option1(2)

  4. Unter Form_Load geben Sie folgenden Code ein.

    Form_Load
    Dim i%

    ' SubClass ComboBoxName, True, Breite, Höhe, Ausrichtung
    ' Ausrichtung: 0 = linksbündig, 1 = rechtsbündig, 2 = zentriert

    'Funktionsaufruf
    SubClass Combo1, True, 260, 100, 0

    'Füllen der Comboboxen
    For i = 1 To 10
    Combo1.AddItem "Das ist der Eintrag mit der eindeutigen Nummer " & Trim$(i)
    Combo2.AddItem "Das ist der Eintrag mit der eindeutigen Nummer " & Trim$(i)
    Next

    Option1(0).Caption = "linksbündig"
    Option1(1).Caption = "rechtsbündig"
    Option1(2).Caption = "zentriert"
    Option1(0) = 1

  5. Außerdem müssen Sie unter Option1_Click noch den Wechsel der
    Ausrichtung übergeben, wenn der aktive Optionbutton gewechselt wird.

    Option1_Click
    Alignment = index   'Publicvariable

  6. Und zum Schluß kommen wir zu etwas ganz wichtigen, da es sich hier um
    Subclassing handelt, müssen Sie das Programm umbedingt korrekt beenden.
    Diese übernimmt in der Form_Unload Methode folgender Aufruf.

    Form_Unload
    SubClass Combo1, False  '!!!!!!

    Damit wird das Subclassing aufgehoben, ansonsten verabschiedet sich VB.

  7. Damit ist Ihr Demoprojekt fertig und Sie können einen Test starten.

Tipp-Download

Quelle : Jürgen Tümmler / www.basicworld.com

Zurück zur Übersichtsseite