|
Sie vermissen die Maus-Ereignisse bei der ComboBox und dem
ImageCombo-Steuerelement (aus den Microsoft Common Controls ab
Visual Basic 6)? Zumindest ein MouseDown-Ereignis
können Sie aber erhalten - auf einem Umweg.
Setzen Sie die Eigenschaft DragMode auf "1 -
Automatisch", wird für das Steuerelement der
Standard-VB-Drag&Drop-Vorgang eingeleitet. Da daraufhin sofort
das DragOver-Ereignis ausgelöst wird, haben Sie damit im Prinzip
schon Ihr MouseDown-Ereignis mit den X- und Y-Koordinaten. Damit der
Drag-Vorgang nicht sichtbar wird, schalten Sie ihn einfach gleich
wieder aus:
Combo.Drag 0
Ganz so einfach ist jedoch nicht. Die ComboBox lässt sich nun
nicht mehr aufklappen. Aber da Sie ja die Koordinaten haben, können
Sie feststellen, ob sich der Mauszeiger über der
Aufklapp-Schaltfläche befindet. Ist dies der Fall senden Sie über
die API-Funktion SendMessage
die Nachricht CB_SHOWDROPDOWN an die ComboBox, um sie zu öffnen.
Ebenfalls stillgelegt ist die Möglichkeit, den Cursor mit der Maus
zu setzen (Combo-Style 1 oder 2). Aber da Sie ja die
Koordinaten haben, ist auch das wieder herstellbar. Lediglich die
Möglichkeit, einen Textbereich zu markieren, ist nicht mehr
realisierbar.
Im Großen und Ganzen ist ein MouseDown-Ereignis einer einfachen
ComboBox nicht so übermäßig nützlich, das einer ImageCombo
dagegen schon. Zum einen können Sie nun zum Beispiel einen
OLE-Drag-Vorgang (.OLEDrag) einleiten. Denn auch die Einstelllung
der OLEDragMode-Eigenschaft auf "1 - ccOLEDragAutomatic"
bringt eine ImageCombo nicht dazu, einen OLE-Drag-Vorgang zu
starten. Zum anderen können sie nämlich zusätzlich ermitteln, ob
das Symbol aktuell gewählten und dargestellten ComboItems getroffen
wurde. Damit ist der Start eines OLE-Drag-Vorgangs wie in der
Adresszeile des Internet Explorers möglich. Und sie können das
Symbol als Schaltfläche nutzen, etwa um einen Selektions-Zustand
des aktuellen ComboItems zu ändern und darzustellen. Wie wäre es
beispielsweise mit CheckBox-Symbolen?
Sowohl für die einfache ComboBox als auch für die ImageCombo
haben wir wieder praktische Funktionen erstellt, die Sie nur noch
aus den DragOver-Ereignissen der Steuerelemente aufzurufen brauchen.
Geben die Funktion True zurück, hat sie ihre Aufgabe erfüllt.
Anderenfalls ist ein anderes Steuerelement per VB-Drag&Drop
darüber gezogen worden - die ComboBox kann also auch weiterhin auf
ein Standard-VB-Drag&Drop mit anderen gezogenen Steuerelementen
wie gewohnt reagieren.
Der Funktion ComboMouse übergeben Sie die betreffende ComboBox,
das im DragOver-Ereignis übergebene Source-Control und die Koordinaten
X und Y. Im optionalen Parameter DropDown
können Sie das automatische Ausklappen der Liste unterdrücken,
indem Sie direkt den Wert False übergeben. Übergeben Sie eine
Variable des Datentyps Boolean mit dem Wert False, erhalten Sie in
dieser Variable ein True zurück, wenn die Ausklappschaltfläche
getroffen wurde. Sie können die Ausklappliste dann gegebenenfalls
selbst noch öffnen (siehe "Klappe
auf - Klappe zu").
Die Funktion ImageComboMouse hat den zusätzlichen optionalen
Parameter ImageDown. Über ihn erhalten Sie die Information, ob das
Symbol des aktuell gewählten ComboItems getroffen wurde.
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare Function GetWindowRect Lib "user32" _
(ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function GetCursorPos Lib "user32" _
(lpPoint As POINTAPI) 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 Declare Function GetSystemMetrics Lib "user32" _
(ByVal nIndex As Long) As Long
Private Declare Function GetFocus Lib "user32" () As Long
Private Const CB_SHOWDROPDOWN = &H14F
Private Const SM_CXVSCROLL = 2
Private Const CBEM_GETCOMBOCONTROL = &H406
Public Function ComboMouse(Combo As ComboBox, Source As Control, _
ByVal X As Single, ByVal Y As Single, _
Optional DropDown As Boolean = True) As Boolean
Dim nFocus As Long
Dim i As Integer
Dim nPos As Long
Static sLastSelStart As Integer
Static sLastSelLength As Integer
If Combo Is Source Then
ComboMouse = True
With Combo
nFocus = GetFocus()
.Drag 0
.SetFocus
Select Case X
Case Is > .Width - (2 + GetSystemMetrics(SM_CXVSCROLL)) _
* Screen.TwipsPerPixelX
If .Style <> 2 Then
If nFocus = GetFocus() Then
.SelStart = sLastSelStart
.SelLength = sLastSelLength
End If
End If
If DropDown Then
SendMessage .hwnd, CB_SHOWDROPDOWN, True, 0
Else
DropDown = True
End If
Case Else
If .Style <> 2 Then
If nFocus = GetFocus() Then
nPos = X + 3 * Screen.TwipsPerPixelX
If nPos > .Parent.ScaleX(.Parent.TextWidth(.Text), _
.Parent.ScaleMode, vbTwips) Then
.SelStart = Len(.Text)
Else
For i = Len(.Text) To 1 Step -1
If .Parent.ScaleX(.Parent.TextWidth(Left$(.Text, _
i)), .Parent.ScaleMode, vbTwips) <= nPos Then
.SelStart = i - 1
Exit For
End If
Next 'i
End If
End If
End If
End Select
If .Style <> 2 Then
sLastSelStart = .SelStart
sLastSelLength = .SelLength
End If
End With
End If
End Function
Public Function ImageComboMouse(ImageCombo As ImageCombo, _
Source As Control, ByVal X As Single, ByVal Y As Single, _
Optional DropDown As Boolean = True, _
Optional ImageDown As Boolean) As Boolean
Dim nWnd As Long
Dim nRect As RECT
Dim nPoint As POINTAPI
Dim nFocus As Long
Dim i As Integer
Dim nPos As Long
Dim nImageWidth As Long
Static sLastSelStart As Integer
Static sLastSelLength As Integer
If ImageCombo Is Source Then
ImageComboMouse = True
With ImageCombo
nFocus = GetFocus()
.Drag 0
.SetFocus
GetWindowRect .hwnd, nRect
GetCursorPos nPoint
If Not (.ImageList Is Nothing) Then
nImageWidth = .ImageList.ImageWidth
End If
Select Case nPoint.X
Case Is < nRect.Left + 3 + nImageWidth
If nFocus = GetFocus() Then
.SelStart = sLastSelStart
.SelLength = sLastSelLength
End If
ImageDown = True
Case Is > nRect.Right - 2 - GetSystemMetrics(SM_CXVSCROLL)
If nFocus = GetFocus() Then
.SelStart = sLastSelStart
.SelLength = sLastSelLength
End If
If DropDown Then
nWnd = SendMessage(.hwnd, CBEM_GETCOMBOCONTROL, 0, 0)
SendMessage nWnd, CB_SHOWDROPDOWN, True, 0
Else
DropDown = True
End If
Case Else
If nFocus = GetFocus() Then
nPos = nPoint.X - nRect.Left + 1 - nImageWidth
If nPos > .Parent.ScaleX(.Parent.TextWidth(.Text), _
.Parent.ScaleMode, vbPixels) Then
.SelStart = Len(.Text)
Else
For i = Len(.Text) To 1 Step -1
If .Parent.ScaleX(.Parent.TextWidth(Left$(.Text, i)), _
.Parent.ScaleMode, vbPixels) <= nPos Then
.SelStart = i - 1
.SelLength = 0
Exit For
End If
Next 'i
End If
End If
End Select
sLastSelStart = .SelStart
sLastSelLength = .SelLength
End With
End If
End Function
|