|
Nach der Verwendung von API-Funktionen, die das Fenster eines UserControls positionieren, wird die neue Position manchmal nicht korrekt von Visual Basic erkannt und wiedergegeben. Die Eigenschaften Left, Top, Width und Height enthalten dann noch die alten Werte, direkt sowohl aus der Sicht des Containers (Form usw.) als auch beim Extender-Objekt aus der Sicht des UserControls selbst.
Sie können jedoch die aktuelle, tatsächliche Position und Größe über API-Funktionen ermitteln. Das Rechteck des UserControl-Fensters erhalten Sie über die Funktion GetWindowRect - allerdings in Bildschirm-Koordinaten. Von der Funktion MapWindowPoints können Sie die Koordinaten in die Koordinaten bezogen auf das Eltern-Fenster (Container des UserControls) umrechnen lassen , dessen Fenster-Handle Sie über die Funktion GetParent erhalten.
Die folgende Hilfs-Funktion CtlSizePosAPIFromHandle liefert die Positions-Koordinaten und die Abmessungen in Pixels, wenn Sie ihr das Fenster-Handle des betreffenden UserControls übergeben. Da das innerhalb der Funktion ermittelte Rechteck des Fensters nicht wie in VB gewohnt die Breite und Höhe des Rechtecks direkt liefert, sondern API-üblich die Koordinaten der rechten unteren Ecke, werden die Breite und Höhe daraus berechnet und in Form der benutzerdefinierten Variablen SizePosPixels zurückgegeben.
Public Type SizePosPixels
Left As Long
Top As Long
Width As Long
Height As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function GetParent Lib "user32" _
(ByVal hWnd As Long) As Long
Private Declare Function GetWindowRect Lib "user32" _
(ByVal hWnd As Long, lpRect As RECT) As Long
Private Declare Function MapWindowPoints Lib "user32" _
(ByVal hwndFrom As Long, ByVal hwndTo As Long, lppt As Any, _
ByVal cPoints As Long) As Long
Public Function CtlSizePosAPIFromHandle(ByVal hWnd As Long) _
As SizePosPixels
Dim nRect As RECT
GetWindowRect hWnd, nRect
MapWindowPoints 0, GetParent(hWnd), nRect, 2
With CtlSizePosAPIFromHandle
.Left = nRect.Left
.Top = nRect.Top
.Width = nRect.Right - nRect.Left
.Height = nRect.Bottom - nRect.Top
End With
End Function
Sie können die Position und Abmessungen auch in der Maßeinheit (ScaleMode) des Containers, auf dem das Steuerelement platziert ist, erhalten. Dazu brauchen Sie jedoch das Parent-Form, in dem das UserControl bzw. dessen Container platziert ist. Sie brauchen dieses jedoch nicht selbst zu ermitteln, sondern können dies der folgenden Variante der oben stehenden Funktion überlassen. Anstelle des bloßen Fenster-Handles des UserControls übergeben Sie der Funktion CtlSizePosAPI das UserControl aus der Sicht des Forms (also den Steuerelement-Namen aus dessen Sicht) oder das Extender-Objekt aus der Sicht des UserControls. Im optionalen Parameter ScaleMode ist der Wert vbContainerSize voreingestellt, der dafür sorgt, dass die Angaben in der Maßeinheit des Containers geliefert werden. Sie können jedoch auch jeden anderen sinnvollen ScaleMode (vbTwips bis vbCentimeters) angeben, in dessen Maßeinheit Sie die Werte erhalten möchten. Die Funktion CtlSizePosAPI gibt die Werte in der benutzerdefinierten Variablen SizePos zurück, deren Elemente als Single-Datentyp deklariert sind.
Public Type SizePos
Left As Single
Top As Single
Width As Single
Height As Single
End Type
Public Function CtlSizePosAPI(Control As Control, _
Optional ByVal ScaleMode As ScaleModeConstants = _
vbContainerSize) As SizePos
Dim nRect As RECT
Dim nWnd As Long
Dim nParent As Object
Dim nContainer As Object
With Control
nWnd = .hWnd
Set nParent = .Parent
Set nContainer = .Container
End With
GetWindowRect nWnd, nRect
MapWindowPoints 0, GetParent(nWnd), nRect, 2
Select Case ScaleMode
Case vbContainerSize
With CtlSizePosAPI
.Left = nParent.ScaleX(nRect.Left, vbPixels, _
nContainer.ScaleMode)
.Top = nParent.ScaleY(nRect.Top, vbPixels, _
nContainer.ScaleMode)
.Width = nParent.ScaleX(nRect.Right - nRect.Left, _
vbPixels, nContainer.ScaleMode)
.Height = nParent.ScaleY(nRect.Bottom - nRect.Top, _
vbPixels, nContainer.ScaleMode)
End With
Case vbPixels
With CtlSizePosAPI
.Left = nRect.Left
.Top = nRect.Top
.Width = nRect.Right - nRect.Left
.Height = nRect.Bottom - nRect.Top
End With
Case vbTwips To vbCentimeters
With CtlSizePosAPI
.Left = nParent.ScaleX(nRect.Left, vbPixels, ScaleMode)
.Top = nParent.ScaleY(nRect.Top, vbPixels, ScaleMode)
.Width = nParent.ScaleX(nRect.Right - nRect.Left, _
vbPixels, ScaleMode)
.Height = nParent.ScaleY(nRect.Bottom - nRect.Top, _
vbPixels, ScaleMode)
End With
End Select
End Function
Wenn Sie diese zweite Funktion verwenden und das UserControl aus der Sicht des Forms übergeben, sollten Sie daran denken, die Eigenschaft hWnd des UserControls offen zu legen:
Public Property Get hWnd() As Long
hWnd = UserControl.hWnd
End Property
|