|
Wenn Sie verhindern möchten, dass die ListItems in einem
ListView-Steuerelement (View-Modus 0 - lvwIcon oder 1
- lvwSmallIcon) mit der Maus verschoben werden können, haben
Sie drei Möglichkeiten. Die ersten beiden dieser Möglichkeiten
"missbrauchen" den OLE-Drag&Drop-Mechanismus, die
dritte setzt ein ListItem nach dem Verschieben einfach wieder an
seine Ausgangsposition zurück.
Die effizientere der beiden OLE-Drag-&Drop-Varianten ist, die
Eigenschaft OLEDragMode auf 1 (ccOLEDragAutomatic) zu
setzen, und im OLEStartDrag-Ereignis das Ziehen gleich wieder
komplett abzuwürgen:
Private Sub ListView1_OLEStartDrag(Data As MSComctlLib.DataObject, _
AllowedEffects As Long)
AllowedEffects = ccOLEDropEffectNone
End Sub
Dabei verändert sich weder der Mauszeiger noch rückt das
ListItem von der Stelle. Diese radikale Möglichkeit verhindert
jedoch ein anderweitig vielleicht gewolltes OLE-Drag&Drop.
Weniger radikal, aber schon aufwändiger, ist die zweite
Möglichkeit. Auch hierbei setzen Sie wieder die
OLEDragMode-Eigenschaft auf 1. Aber statt nun das
Ziehen im OLEStartDrag-Ereignis abzuwürgen, können Sie dort den
gewünschten OLE-Drag-Vorgang einleiten. Sie müssen nun aber im
OLEDragOver-Ereignis des ListView-Steuerelements das entsprechende
Feedback geben, dass ein Ablegen auf der ListView-Fläche
unerwünscht ist:
Private Sub ListView1_OLEDragOver(Data As MSComctlLib.DataObject, _
Effect As Long, Button As Integer, Shift As Integer, _
x As Single, y As Single, State As Integer)
Effect = ccOLEDropEffectNone
End Sub
Sollen jedoch von anderswo her gezogene Objekte auf dem
ListView-Steuerelement abgelegt werden können, müssen Sie
natürlich wie gewohnt hier prüfen, ob das gezogene Objekt abgelegt
werden darf, und dabei die eigenen ListItems ausschließen. Dazu
definieren Sie am besten ein eigenes Format für das DataObjekt und
setzen es in OLEStartDrag. Wird in OLEDragOver nun ein DataObject
angeliefert, das dieses eigene Format enthält, handelt es sich bei
dem gezogenen Objekt um ein eigenes ListItem, das da gerade gezogen
wird.
Private Sub ListView1_OLEStartDrag(Data As MSComctlLib.DataObject, _
AllowedEffects As Long)
Data.SetFormat , 12345
' und z.B. :
Data.SetFormat ListView1.SelectedItem.Text, vbCFText
AllowedEffects = ccOLEDropEffectCopy
End Sub
Private Sub ListView1_OLEDragOver(Data As MSComctlLib.DataObject, _
Effect As Long, Button As Integer, Shift As Integer, _
x As Single, y As Single, State As Integer)
If Data.GetFormat(12345) Then
Effect = ccOLEDropEffectNone
ElseIf Data.GetFormat(vbCFText) Then
' z.B.
Debug.Print Data.GetData(vbCFText)
End If
End Sub
Die letzte Eingangs erwähnte Möglichkeit lässt das OLE-Drag&Drop
vollkommen unberührt. Sie hat aber den optischen Nachteil, dass ein
ListItem tatsächlich zunächst gezogen wird. Die Wirkung ist unterm
Strich dieselbe: Das ListItem sitzt anschließend nach wie vor an
seinem Platz. Das Prinzip ist simpel. Sie merken sich einfach das
gezogene ListItem und dessen Ausgangsposition in Form-weit gültigen
Variablen. Beim Loslassen des Mausknopfes nach dem Ziehen (MouseUp-Ereignis)
setzen Sie das gemerkte ListItem wieder an die zwischengespeicherte
Position zurück:
Private mItem As ListItem
Private mItemLeft As Single
Private mItemTop As Single
Private Sub ListView1_ItemClick(ByVal Item As MSComctlLib.ListItem)
Set mItem = Item
mItemLeft = mItem.Left
mItemTop = mItem.Top
End Sub
Private Sub ListView1_MouseUp(Button As Integer, Shift As Integer, _
x As Single, y As Single)
Debug.Print "MU"
mItem.Left = mItemLeft
mItem.Top = mItemTop
End Sub
|