Previous | Index | Next 

[PRB] Mouse custom cursor in drag-and-drop operations with ActiveX controls doesn’t work correctly

When implementing a drag-and-drop operation with an ActiveX control – more precisely, with a control generated by AxWrapperGen and that wraps an ActiveX control – you may notice that the setting a custom mouse cursor doesn’t work correctly.

To solve the problem, you should add the definition of the Cursor property to the AxWrapperGen-generated class. The following code example is for the TrueDBGrid control, but it can be easily adapted to other ActiveX controls:

    #Region "Cursor"

        ' the Cursor property of an ActiveX control isn't supported.
        ' This code is a partial workaround
		
        ' the cursor that has been assigned
        Dim m_Cursor As Cursor
        ' the original values when a new Cursor has been assigned
        Dim saveMouseIcon As Object = Nothing
        Dim saveMousePointer As TrueOleDBGrid80.MousePointerConstants
  
        Public Overrides Property Cursor() As Cursor
            Get
                If m_Cursor IsNot Nothing Then
                    Return m_Cursor
                Else
                    Return Me.Parent.Cursor
                End If
            End Get
            Set(ByVal value As Cursor)
                m_Cursor = value
                If value IsNot Nothing Then
                    ' Set parent container cursor in order to modify it and support
                    ' drag&drop cursor in interop environment
                    If Me.Parent IsNot Nothing Then Me.Parent.Cursor = value
                Else
                    ' restore the previous values
                    RestoreMouseCursor()
                End If
            End Set
        End Property
		
        ' Public method that should be called from inside DragOver event handler
        ' in order to set the right cursor inside the ActiveX control
  
        Public Sub SetCOMDragOverIcon(ByVal icon As Object, _
              ByVal state As DragOverConstants)
            If state = DragOverConstants.vbOver OrElse _
               icon Is Nothing OrElse Not TypeOf icon Is Bitmap Then Exit Sub
  
            Dim bmpIcon As Bitmap = CType(icon, Bitmap)
            Dim icon2 As Cursor = New Cursor(bmpIcon.GetHicon)
  
            If state = DragOverConstants.vbEnter Then
                ' save the previous values
                saveMousePointer = MyBase.MousePointer
                saveMouseIcon = MyBase.MouseIcon
  
                ' Set icon in ActiveX component
                MyBase.MousePointer = _
                   TrueOleDBGrid80.MousePointerConstants.dbgMPCustom
                MyBase.MouseIcon = AxHost.GetIPictureFromCursor(icon2)
            ElseIf state = DragOverConstants.vbLeave Then
                RestoreMouseCursor()
            End If
        End Sub
  
        Private Sub onVB6DragDrop() Handles Me.DragDrop
            RestoreMouseCursor()
        End Sub
  
        Private Sub RestoreMouseCursor()
            ' Restore ActiveX properties to original values
            MyBase.MousePointer = saveMousePointer
            MyBase.MouseIcon = saveMouseIcon

            saveMouseIcon = Nothing
        End Sub
  
    #End  Region

Next, you must insert a call to the new SetCOMDragOverIcon method in all event handlers that are related to drag-and-drop, as in this example:

        Private Sub TDBGrid1_DragOver(Source As Control, X As Single, _
              Y As Single, State As Integer)
            Source.DragIcon = LoadPicture(App.Path & "\drag1pg.ico")
            '## InsertStatement TDBGrid1.SetCOMDragOverIcon(CObj(Source).DragIcon, State)
        End Sub
  
        Private Sub TDBGrid2_DragOver(Source As Control, X As Single, Y As Single, _
              State As Integer)
            Source.DragIcon = LoadPicture(App.Path & "\drag1pg.ico")
            '## InsertStatement TDBGrid2.SetCOMDragOverIcon(CObj(Source).DragIcon, State)
        End Sub
  
        Private Sub TDBGrid3_DragOver(Source As Control, X As Single, Y As Single, _
              State As Integer)
            If State = 0 Then
                Source.DragIcon = LoadPicture(App.Path & "\drop1pg.ico")
            ElseIf State = 1 Then
                Source.DragIcon = LoadPicture(App.Path & "\drag1pg.ico")
            End If

            '## InsertStatement TDBGrid3.SetCOMDragOverIcon(CObj(Source).DragIcon, State)
        End Sub

 

Previous | Index | Next