ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 01.12.2000

Diese Seite wurde zuletzt aktualisiert am 01.12.2000
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Steuerelemente in der StatusBar

Zurück...


Anzeige

(-hg) mailto:hg_panelcontrol@aboutvb.de

Eine Fortschrittsanzeige in der Statuszeile? Oder irgend ein anderes Steuerelement in einer Anzeigefläche der Statuszeile? Anders gefragt: Wie bekommen Sie ein Steuerelement in eine Panel-Fläche eines StatusBar-Steuerelements (aus den Microsoft Common Controls) hinein?


Eine Fortschrittsanzeige in der Statuszeile - auch in einem MDI-Hauptform

Eine Möglichkeit wäre, das Steuerelement an die Position der Panel-Fläche zu schieben. Die linke Kante und die Breite liefert die Panel-Fläche selbst. Der Abstand der Oberkante innerhalb des StatusBar-Elements ist automatisch festgelegt, wie sich auch die Höhe automatisch aus der Höhe des StatusBar-Elements ergibt. Mit der Methode ZOrder des ProgressBar-Elements setzen Sie dieses in den Vordergrund.

Befindet sich die StatusBar jedoch in einem MDI-Hauptform, geht das nicht ganz so einfach. Denn dort müssten Sie das Steuerelement erst einmal außerhalb der StatusBar platzieren. Denn selbst wenn es ein Steuerelement wäre, das über die Align-Eigenschaft verfügt und sich so direkt auf einem MDI-Hauptform platzieren ließe, könnte es nicht verschoben werden. Hier müssen Sie eine zusätzliche PictureBox einfügen. Deren Visible-Eigenschaft setzen Sie auf False, falls Sie die PictureBox nicht anderweitig sichtbar benötigen und platzieren auf ihr das bzw. die in die StatusBar einzufügenden Steuerelement(e) auf dieser PictureBox.


Als "Vorratsbehälter" für die ProgressBar dient eine unsichtbare PictureBox

Damit haben wir nun das Problem gelöst, ein Steuerelement frei beweglich zu halten, aber zugleich haben wir uns das Problem eingehandelt, dass sich die StatusBar und das Steuerelement nicht länger im gleichen Container befinden, und daher das Steuerelement so nicht mehr über die StatusBar geschoben werden kann.

Allerdings können wir Steuerelemente, die uns ihr Fenster-Handle zur Verfügung stellen (hWnd-Eigenschaft), der StatusBar mittels der API-Funktion SetParent als Kind-Fenster "unterjubeln". Und nachdem ein Steuerelement so zu einem Kind der StatusBar geworden ist, können wir es darin an der gewünschten Stelle platzieren. Bei einem normalen Form wäre das zwar nicht notwendig - aber es schadet auch nichts. Daher können wir für beide Fälle ein und dasselbe Verfahren verwenden.

Die Funktion SetPanelControl übernimmt nicht nur die reine Platzierung über genau einer bestimmten Panel-Fläche der StatusBar, sondern sie berücksichtigt bei der Berechnung der Position auch die ScaleMode-Einstellung des Forms bzw. der PictureBox, auf dem sich das zu platzierende Steuerelement zu Beginn befindet. Sie übergeben ihr das zu platzierende Steuerelement und die StatusBar in den ersten beiden Parametern. Im Parameter PanelKey übergeben Sie entweder den Index oder den Schlüssel eines der Panels der StatusBar, oder gar direkt ein bestimmtes Panel. Im optionalen Parameter AdjustStatusBarToControl können Sie festlegen, ob die Höhe der StatusBar an das zu platzierende Steuerelement angepasst werden soll - dies ist beispielsweise bei ComboBoxen sinnvoll, deren Höhe nicht willkürlich geändert werden kann.

Wie beschrieben wird mittels SetParent das Fenster der StatusBar als Eltern-Fenster des Steuerelements gesetzt. Da es Steuerelemente gibt, die beim Entladen eines Forms Probleme bereiten, wenn sie sich dann nicht in ihrem ursprünglichen Eltern-Fenster befinden, sollte das Handle des ursprünglichen Eltern-Fensters, das von der SetParent-Funktion zurückgegeben wird, festgehalten werden. Damit Sie sich nicht um die Verwaltung dieses Handles zu kümmern brauchen, können Sie es in den meisten Fällen im User-Data-Feld des Steuerelement-Fensters ablegen (siehe "Extra-Tag per API" khwextratag.htm). Es gibt allerdings Steuerelemente, die dieses Datenfeld selbst mit Beschlag belegen. Ist dies der Fall, übergibt Ihnen SetPanelControl das Handle als Rückgabewert - in diesem Fall müssen Sie sich selbst um die Ablage kümmern. Ein solches Steuerelement ist übrigens Das ProgressBar-Steuerelement aus den Microsoft Common Controls. Die eigentliche Platzierung des Seuerlements erfolgt über die private Hilfsfunktion des Moduls zAdjust.

Private Declare Function GetWindowLong Lib "user32" _
 Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) _
 As Long
Private Declare Function SetParent Lib "user32" _
 (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function SetWindowLong Lib "user32" _
 Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, _
 ByVal dwNewLong As Any) As Long

Private Const GWL_USERDATA = (-21)

Public Enum PanelControlErrorConstants
  pcErrInvalidPanelObject = 10001
  pcErrInvalidPanelIndexKey = 10002
End Enum

Public Function SetPanelControl(Control As Control, _
 StatusBar As StatusBar, PanelKey As Variant, _
 Optional ByVal AdjustStatusBarToControl As Boolean) As Long

  Dim nParent As Object
  Dim nControl As Control
  Dim nOldParentWnd As Long
  Dim nPanel As Panel
  
  With Control
    If TypeOf .Parent Is MDIForm Then
      Set nParent = .Container
    Else
      Set nParent = .Parent
    End If
  End With
  If IsObject(PanelKey) Then
    If TypeOf PanelKey Is Panel Then
      Set nPanel = PanelKey
    Else
      Err.Raise pcErrInvalidPanelObject, "SetPanelControl"
    End If
  End If
  On Error Resume Next
  If nPanel Is Nothing Then
    Set nPanel = StatusBar.Panels(PanelKey)
    If Err.Number Then
      Err.Raise pcErrInvalidPanelIndexKey, "SetPanelControl"
    End If
  End If
  On Error GoTo 0
  With Control
    nOldParentWnd = SetParent(.hWnd, StatusBar.hWnd)
    If GetWindowLong(.hWnd, GWL_USERDATA) = 0 Then
      SetWindowLong .hWnd, GWL_USERDATA, nOldParentWnd
    Else
      SetPanelControl = nOldParentWnd
    End If
  End With
  zAdjust Control, nParent, nPanel, StatusBar, _
   AdjustStatusBarToControl
End Function

Private Sub zAdjust(Control As Control, Parent As Object, _
 Panel As Panel, StatusBar As StatusBar, _
 ByVal AdjustStatusBarToControl As Boolean)

  On Error Resume Next
  With Parent
    If AdjustStatusBarToControl Then
      StatusBar.Height = Control.Height + .ScaleY(6, vbPixels)
      If Panel.Index = 1 Then
        Control.Move Panel.Left + .ScaleX(1, vbPixels), _
         .ScaleY(4, vbPixels), Panel.Width - .ScaleX(3, vbPixels)
      Else
        Control.Move Panel.Left + .ScaleX(3, vbPixels), _
         .ScaleY(4, vbPixels), Panel.Width - .ScaleX(4, vbPixels)
      End If
    Else
      If Panel.Index = 1 Then
        Control.Move Panel.Left + .ScaleX(1, vbPixels), _
         .ScaleY(4, vbPixels), Panel.Width - .ScaleX(3, vbPixels), _
         StatusBar.Height - .ScaleY(6, vbPixels)
      Else
        Control.Move Panel.Left + .ScaleX(3, vbPixels), _
         .ScaleY(4, vbPixels), Panel.Width - .ScaleX(4, vbPixels), _
         StatusBar.Height - .ScaleY(6, vbPixels)
      End If
    End If
  End With
End Sub

Der Rückwärtsgang, nämlich das Entfernen eines Steuerelements aus der StatusBar, erfolgt über die Prozedur RemovePanelControl. Ihr übergeben Sie das zu entfernende Steuerelement und gegebenenfalls das von Ihnen selbst gesicherte ursprüngliche Fenster-Handle.

Public Sub RemovePanelControl(Control As Control, _
 Optional OldParentWnd As Long)

  With Control
    .Visible = False
    If OldParentWnd Then
      SetParent .hWnd, OldParentWnd
    Else
      SetParent .hWnd, GetWindowLong(.hWnd, GWL_USERDATA)
    End If
  End With
End Sub

Da sich die Breite von Panels, bei denen die Eigenschaft AutoSize auf sbrSpring gesetzt ist, ändern kann, brauchen Sie eine Möglichkeit, die Größe eines auf einem solchen Panel platzierten Steuerelements nachzuführen. Sowohl für diesen Fall als auch allgemein für den Fall, dass sich die Größe eines Panels oder der StatusBar selbst ändern sollte, können Sie die Größe eines Steuerelement mit der Prozedur AdjustControlToPanel jederzeit an das zugehörige Panel anpassen. Die Parameter sind die gleichen wie bei der Funktion SetPanelControl.

Public Sub AdjustControlToPanel(Control As Control, _
 StatusBar As StatusBar, PanelKey As Variant, _
 Optional ByVal AdjustStatusBarToControl As Boolean)

  Dim nParent As Object
  Dim nPanel As Panel
  
  If IsObject(PanelKey) Then
    If TypeOf PanelKey Is Panel Then
      Set nPanel = PanelKey
    Else
      'Error
    End If
  End If
  If nPanel Is Nothing Then
    On Error Resume Next
    Set nPanel = StatusBar.Panels(PanelKey)
    If Err.Number Then
      'Error
    End If
    On Error GoTo 0
  End If
  With Control
    If TypeOf .Parent Is MDIForm Then
      Set nParent = .Container
    Else
      Set nParent = .Parent
    End If
  End With
  zAdjust Control, nParent, nPanel, StatusBar, _
   AdjustStatusBarToControl
End Sub

In den allermeisten Fällen gibt es keine Probleme mit den Ereignissen eines Steuerelementen, die in ein StatusBar verschoben worden sind. Sie kommen nach wie vor in den entsprechenden Ereignis-Prozeduren des Steuerelements an. Doch verschieben Sie beispielsweise einen simplen CommandButton, wird dessen Click-Ereignis seltsamerweise nicht mehr ausgelöst. In solchen Fällen verschieben Sie nicht das Steuerelement selbst, sondern verwenden eine PictureBox als Container, auf dem erst das Steuerelement platziert wird, und verschieben diese PictureBox in die StatusBar. Die Positionierung des Steuerelements und seine Anpassung an die Größe der PictureBox können Sie dann bequem im Resize-Ereignis der PictureBox vornehmen. Damit dieser kleine Trick nicht auffällt, setzen Sie die BorderStyle-Eigenschaft der PictureBox auf 0. Und damit die Tab-Reihenfolge nicht durcheinander gerät, sollten Sie die TabStop-Eigenschaft der PictureBox auf False setzen.


Beispiel-Projekt und Modul modPanelControl (panelcontrol.zip - ca. 8,4 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche



Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer