Terminar evento MouseDown con el botón del ratón pulsado

Iniciado por Lekim, 12 Junio 2016, 17:24 PM

0 Miembros y 1 Visitante están viendo este tema.

Lekim


He cambiado el título de la pregunta porque no estaba bien hecha, ya que hacía referencia al foco de objeto cuando en realidad me refiero al evento. Cuando se presiona sobre el objeto éste recibe el foco, por eso usé esa palabra.

Realmente lo que necesito es terminar o salir del evento MouseDown y volver a entrar sin soltar el botón del ratón  al salir y entrar en otro objeto de un mismo array




Hola

Estoy intentado que al pulsar un objeto sea un Label, picture o botón, al salir de él éste salga del evento de pulsado (Mousedown) del objeto y al entras seguidamente en otro objeto éste reciba el enfoque y el evento MouseDown

Para que se me entienda.

Imagina el teclado del ordenador y pasas y pulsas A el botón baja, luego deslizas el dedo manteniendo pulsado y pasa a S. el botón S bajará y el A subirá.  En un editor de texto se escribiría AS sin haber levantado el dedo.

Necesito eso mismo pero con controles. pero no se como hacerlo. He probado con Hover y Enter, pero no me sale.


Parece una tontaría y muy simple pero llevo rato inentandolo y nada

Gracias





Aquí dejo lo que he hecho.

Al pulsar sobre el Label(2) éste cambia de color al azul y sin soltar, al salir de él y entrar en Label(1), pierde su color azul, pero el Label(1) no cambia de color porque todavía está en el evento MousDown Label(2).

Necesito que al entrar en Label(1) entre en el evento Mousdown de este control y salga del MouseDown del Label(2).


Código (vbnet) [Seleccionar]

'Programmed by Lekim'
Option Strict On
Imports System.Runtime.InteropServices


Public Class Form1

   <DllImport("user32.dll")> _
   Private Shared Sub mouse_event(ByVal dwFlags As UInteger, _
                                  ByVal dx As UInteger, _
                                  ByVal dy As UInteger, _
                                  ByVal dwData As UInteger, _
                                  ByVal dwExtraInfo As Integer)
   End Sub


   Dim lblkey(5) As Label
   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

       Dim locLBL As New Point(10, 10)
       Dim inc As Integer
       For I As Integer = 0 To 5
           lblkey(I) = New Label
           lblkey(I).Size = CType(New Point(20, 100), Drawing.Size)
           lblkey(I).BorderStyle = BorderStyle.FixedSingle
           lblkey(I).Location = New Point(locLBL.X + inc, locLBL.Y)
           Me.Controls.Add(lblkey(I))
           inc += 19
       Next
       For I As Integer = 0 To 5
           AddHandler lblkey(I).MouseDown, AddressOf lblkey_MouseDown
           AddHandler lblkey(I).MouseUp, AddressOf lblkey_MouseUp
           AddHandler lblkey(I).MouseMove, AddressOf lblkey_MouseMove

       Next

   End Sub
   Private Sub lblkey_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       Dim Index As Integer = Array.IndexOf(lblkey, sender)
       Dim mPoint As New Point(Me.PointToClient(Cursor.Position).X, Me.PointToClient(Cursor.Position).Y)
       Dim X As Integer = mPoint.X

       If X < CInt(lblkey(Index).Left) Or
           X > (CInt(lblkey(Index).Left) + _
                CInt(lblkey(Index).Width)) Then
           EventoUp()
           EventoDown()
       End If

   End Sub
   Private Sub lblkey_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       Dim Index As Integer = Array.IndexOf(lblkey, sender)
       If Button.MouseButtons = MouseButtons.Left Then
           lblkey(Index).BackColor = Color.Azure
       End If
   End Sub
   Private Sub lblkey_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       Dim Index As Integer = Array.IndexOf(lblkey, sender)
       lblkey(Index).BackColor = Color.Transparent
   End Sub

End Class
Module modEventMouse
   <DllImport("user32.dll")> _
   Public Sub mouse_event(ByVal dwFlags As UInteger, _
                                  ByVal dx As UInteger, _
                                  ByVal dy As UInteger, _
                                  ByVal dwData As UInteger, _
                                  ByVal dwExtraInfo As Integer)
   End Sub
   <Flags()> _
   Public Enum MouseEventFlags As UInteger
       MOUSEEVENTF_ABSOLUTE = &H8000
       MOUSEEVENTF_LEFTDOWN = &H2
       MOUSEEVENTF_LEFTUP = &H4
       MOUSEEVENTF_MIDDLEDOWN = &H20
       MOUSEEVENTF_MIDDLEUP = &H40
       MOUSEEVENTF_MOVE = &H1
       MOUSEEVENTF_RIGHTDOWN = &H8
       MOUSEEVENTF_RIGHTUP = &H10
       MOUSEEVENTF_XDOWN = &H80
       MOUSEEVENTF_XUP = &H100
       MOUSEEVENTF_WHEEL = &H800
       MOUSEEVENTF_HWHEEL = &H1000
   End Enum
   ''' <summary>
   ''' Simulate MouseDown the left mouse button
   ''' </summary>
   ''' <remarks></remarks>
   Public Sub EventoDown()
       Call modEventMouse.mouse_event(MouseEventFlags.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
   End Sub
   ''' <summary>
   ''' Simulate MouseUp the left mouse button
   ''' </summary>
   ''' <remarks></remarks>
   Public Sub EventoUp()
       Call modEventMouse.mouse_event(MouseEventFlags.MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0)
   End Sub


End Module





DarK_FirefoX

Con respecto a tu analogía con el teclado habría que ver como funciona un controlador de teclado, no se mucho sobre controladores, y no se si de alguna forma a muy bajo nivel utilice threads (que es como se me ocurre a priori) (también voy a probar con eventos). Me explico:

Hice la prueba que dices con el teclado, presione la A (y la deje apretada, por ende en el editor de texto, se repite la AAAAAAA.....) luego, presione la S (da lo mismo con que dedo) con otro dedo, y se escribio la S (SSSSSSSSSSSSSSS.....), si ahora, en efecto se "paso" de un lugar a otro el "foco" de una tecla a otra, pero si suelto la tecla S no vuelve a pasar a la tecla A, y lo probé recursivamente con varias teclas en profundidad  y sucede lo mismo.

De cualquier manera voy a hacer mis pruebas y luego te digo, si aparece alguien que sepa como hacerlo o tenga alguna idea, la espero igual que tu.

Salu2s

Lekim

#2
Cita de: DarK_FirefoX en 12 Junio 2016, 18:51 PM
Con respecto a tu analogía con el teclado habría que ver como funciona un controlador de teclado, no se mucho sobre controladores, y no se si de alguna forma a muy bajo nivel utilice threads (que es como se me ocurre a priori) (también voy a probar con eventos). Me explico:

Hice la prueba que dices con el teclado, presione la A (y la deje apretada, por ende en el editor de texto, se repite la AAAAAAA.....) luego, presione la S (da lo mismo con que dedo) con otro dedo, y se escribio la S (SSSSSSSSSSSSSSS.....), si ahora, en efecto se "paso" de un lugar a otro el "foco" de una tecla a otra, pero si suelto la tecla S no vuelve a pasar a la tecla A, y lo probé recursivamente con varias teclas en profundidad  y sucede lo mismo.

De cualquier manera voy a hacer mis pruebas y luego te digo, si aparece alguien que sepa como hacerlo o tenga alguna idea, la espero igual que tu.

Salu2s

Si eso también lo quiero que mientras esté pulsado se mantenga la orden. Usando como ejemplo lo del teclado si mantengo pulsado A sale "AAAAAA..." y sin soltar el dedo deslizo hacia S y mantengo pulsado pone "SSSSSSSSSSSSSSS" y si suelto deja de escribir.

Pues eso pero con controles y en lugar del dedo el ratón.





Me estoy acercando...  :xD

He conseguido hacerlo pero solo funciona cuando mueves a la izquierda pero no a la derecha, usando API.

Código (vbnet) [Seleccionar]
Imports System.Runtime.InteropServices

Public Class Form1

   <DllImport("user32.dll")> _
   Private Shared Sub mouse_event(ByVal dwFlags As UInteger, ByVal dx As UInteger, ByVal dy As UInteger, ByVal dwData As UInteger, ByVal dwExtraInfo As Integer)
   End Sub

   Const MOUSEEVENTF_MOVE = &H1 '  movimiento del mouse
   Const MOUSEEVENTF_LEFTDOWN = &H2 '  botón izquierdo presionado
   Const MOUSEEVENTF_LEFTUP = &H4 '  botón izquierdo soltado
   Const MOUSEEVENTF_RIGHTDOWN = &H8 '  botón derecho presionado
   Const MOUSEEVENTF_RIGHTUP = &H10 '  botón derecho soltado
   Const MOUSEEVENTF_MIDDLEDOWN = &H20 '  botón central presionado
   Const MOUSEEVENTF_MIDDLEUP = &H40 ' botón central soltado
   Const MOUSEEVENTF_ABSOLUTE = &H8000 '  movimiento absoluto
   Dim lblkey(2) As Label
   Dim Pulsado As Integer = False
   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

       Dim locLBL As New Point(10, 10)
       Dim inc As Integer
       For I As Integer = 0 To 2

           lblkey(I) = New Label
           lblkey(I).Size = New Point(20, 100)
           lblkey(I).BorderStyle = BorderStyle.FixedSingle
           lblkey(I).Location = New Point(locLBL.X + inc, locLBL.Y)
           Me.Controls.Add(lblkey(I))
           inc += 19
       Next
       For I As Integer = 0 To 2
           AddHandler lblkey(I).MouseDown, AddressOf lblkey_MouseDown
           AddHandler lblkey(I).MouseUp, AddressOf lblkey_MouseUp
           AddHandler lblkey(I).MouseEnter, AddressOf lblkey_MouseEnter
           AddHandler lblkey(I).Click, AddressOf lblkey_MouseClick
           AddHandler lblkey(I).MouseMove, AddressOf lblkey_MouseMove
       Next

   End Sub
   Private Sub lblkey_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       Dim Index As Integer = Array.IndexOf(lblkey, sender)
       Dim punto As New Point(Me.PointToClient(Cursor.Position))
       Dim X As Integer = punto.X

       If X < CInt(lblkey(Index).Left) Or X > (CInt(lblkey(Index).Left) + CInt(lblkey(Index).Width)) And _
           Button.MouseButtons = MouseButtons.Left And Pulsado = True Then
           SueltaBoton()
           ClicBoton()

       End If
   End Sub
   Private Sub lblkey_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       Dim Index As Integer = Array.IndexOf(lblkey, sender)
       If Button.MouseButtons = MouseButtons.Left Then
           lblkey(Index).BackColor = Color.Azure
       End If
   End Sub

   Private Sub lblkey_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
   End Sub
   Private Sub lblkey_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs)
   End Sub
   Private Sub lblkey_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       Dim Index As Integer = Array.IndexOf(lblkey, sender)
       lblkey(Index).BackColor = Color.Transparent
   End Sub
   Public Sub ClicBoton()
       'Simula el clic del boton izquierdo del ratón
       Call mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
   End Sub

   Public Sub SueltaBoton()
       'Simula el clic del boton izquierdo del ratón
       Call mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0)
   End Sub
End Class





¡¡CONSEGUIDO!!

Pulsa con el botón derecho del ratón sobre una banda y luego desliza sin soltar el botón, las bandas(que son Labels), se activarán al pasar el puntero.



Código (vbnet) [Seleccionar]


'Programmed by Lekim'
Option Strict On
Imports System.Runtime.InteropServices


Public Class Form1

   <DllImport("user32.dll")> _
   Private Shared Sub mouse_event(ByVal dwFlags As UInteger, _
                                  ByVal dx As UInteger, _
                                  ByVal dy As UInteger, _
                                  ByVal dwData As UInteger, _
                                  ByVal dwExtraInfo As Integer)
   End Sub


   Dim lblkey(5) As Label
   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

       Dim locLBL As New Point(10, 10)
       Dim inc As Integer
       For I As Integer = 0 To 5
           lblkey(I) = New Label
           lblkey(I).Size = CType(New Point(20, 100), Drawing.Size)
           lblkey(I).BorderStyle = BorderStyle.FixedSingle
           lblkey(I).Location = New Point(locLBL.X + inc, locLBL.Y)
           Me.Controls.Add(lblkey(I))
           inc += 19
       Next
       For I As Integer = 0 To 5
           AddHandler lblkey(I).MouseDown, AddressOf lblkey_MouseDown
           AddHandler lblkey(I).MouseUp, AddressOf lblkey_MouseUp
           AddHandler lblkey(I).MouseMove, AddressOf lblkey_MouseMove

       Next

   End Sub
   Private Sub lblkey_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       Dim Index As Integer = Array.IndexOf(lblkey, sender)
       Dim mPoint As New Point(Me.PointToClient(Cursor.Position).X, Me.PointToClient(Cursor.Position).Y)
       Dim X As Integer = mPoint.X

       If X < CInt(lblkey(Index).Left) Or
           X > (CInt(lblkey(Index).Left) + _
                CInt(lblkey(Index).Width)) Then
           EventoUp()
           EventoDown()
       End If

   End Sub
   Private Sub lblkey_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       Dim Index As Integer = Array.IndexOf(lblkey, sender)
       If Button.MouseButtons = MouseButtons.Left Then
           lblkey(Index).BackColor = Color.Azure
       End If
   End Sub
   Private Sub lblkey_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       Dim Index As Integer = Array.IndexOf(lblkey, sender)
       lblkey(Index).BackColor = Color.Transparent
   End Sub

End Class
Module modEventMouse
   <DllImport("user32.dll")> _
   Public Sub mouse_event(ByVal dwFlags As UInteger, _
                                  ByVal dx As UInteger, _
                                  ByVal dy As UInteger, _
                                  ByVal dwData As UInteger, _
                                  ByVal dwExtraInfo As Integer)
   End Sub
   <Flags()> _
   Public Enum MouseEventFlags As UInteger
       MOUSEEVENTF_ABSOLUTE = &H8000
       MOUSEEVENTF_LEFTDOWN = &H2
       MOUSEEVENTF_LEFTUP = &H4
       MOUSEEVENTF_MIDDLEDOWN = &H20
       MOUSEEVENTF_MIDDLEUP = &H40
       MOUSEEVENTF_MOVE = &H1
       MOUSEEVENTF_RIGHTDOWN = &H8
       MOUSEEVENTF_RIGHTUP = &H10
       MOUSEEVENTF_XDOWN = &H80
       MOUSEEVENTF_XUP = &H100
       MOUSEEVENTF_WHEEL = &H800
       MOUSEEVENTF_HWHEEL = &H1000
   End Enum
   ''' <summary>
   ''' Simulate MouseDown the left mouse button
   ''' </summary>
   ''' <remarks></remarks>
   Public Sub EventoDown()
       Call modEventMouse.mouse_event(MouseEventFlags.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
   End Sub
   ''' <summary>
   ''' Simulate MouseUp the left mouse button
   ''' </summary>
   ''' <remarks></remarks>
   Public Sub EventoUp()
       Call modEventMouse.mouse_event(MouseEventFlags.MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0)
   End Sub


End Module






¿Realmente no hay forma de hacerlo usando puro NET?

He entrado en otro foro y no he recibido más que críticas por haber usado el API, pero ninguna solución.  :¬¬


DarK_FirefoX

Me hubiera gustado también hacerlo sin "código no manejado", realmente llevo varios días ocupado y no he tenido tiempo de intentarlo! Parece que @Eleкtro también ha estado ocupado, de seguro hubiéramos visto una respuesta de el.

En cuanto tenga un chance voy a probar!

Salu2s

Lekim

Cita de: DarK_FirefoX en 14 Junio 2016, 02:10 AM
Me hubiera gustado también hacerlo sin "código no manejado", realmente llevo varios días ocupado y no he tenido tiempo de intentarlo! Parece que @Eleкtro también ha estado ocupado, de seguro hubiéramos visto una respuesta de el.

En cuanto tenga un chance voy a probar!

Salu2s

Gracias

De seguro que @Eleкtro sabría hacerlo, y lo que hiciera no se si lo entendería pero mientras funcioné chapó.

He estado probando con System.Windows.Forms.MouseEventArgs y Sender, creo que por ahí van los tiros pero sin éxito.

Lo que quiero hacer no es algo que la gente demande y se encuentre buscando en google. Hay que tirar de ingenio. 

s2s

Eleкtro

#5
Cita de: Lekim en 14 Junio 2016, 10:01 AM
Gracias

De seguro que @Eleкtro sabría hacerlo, y lo que hiciera no se si lo entendería pero mientras funcioné chapó.

He estado probando con System.Windows.Forms.MouseEventArgs y Sender, creo que por ahí van los tiros pero sin éxito.

Lo que quiero hacer no es algo que la gente demande y se encuentre buscando en google. Hay que tirar de ingenio.  

s2s

Hola Lekim

No es que yo esté ocupado, es que me conecto poquísimo al foro estos días, de hecho no habia visto tu post hasta ahora.

No he revisado tu solución, pero he leido los mensajes y el contenido de forma superficial, y te puedo asegurar que no es necesario recurrir al código no administrado, todo lo que necesitas para intercambiar el foco de los controles pulsando A/S (o izquierda/derecha) es lo sigueinte:

1. Asignar un índice de tabulación correlativo a cada control.
  ( Menú View -> Tab Order )

2. Utilizar la función Control.SelectNextControl()
   (sobre todo hacer un uso adecuado del primer parámetro, el cual indica si debe elegir el control siguiente o el anterior.)
 
3. Controlar las teclas que desses, por supuesto, en este caso "A" y "S".

Es fácil, no creo que necesites ayuda, ya que siempre puedes informarte en la MSDN (o mediante IntelliSense) sobre el propósito de los parámetros de la función mencioanda.

--------------------------------------------------

Si además de eso también quieres poder elegir controles de una forma "vertical" entonces ya es más tedioso, puesto que una colección de controles no entiende de posiciones verticales u horizontales, sino de indices.
Cómo he dicho es tedioso, pero no imposible. Siempre puedes buscar el control más proximo hacia abajo o hacia arriba (y también de forma horizontal, reemplazando a la metodología del tabstop) mediante punteros del mouse, es decir, incrementando o disminuyendo la posición vertical (Point.Y), y haciendo uso de la función Control.GetChildAtPoint() con dicho puntero, pero te advierto esa metodología no te servirá para controles que estén superpuestos o dentro de una sub-colección de controles (ej. un Panel), así que te recomiendo utilizar mi función:

Código (vbnet) [Seleccionar]
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the corresponding control (if any) that is over the specified mouse point.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <param name="container">
''' The source container of controls where to search for.
''' <para></para>
''' Normally a <see cref="Form"/>, but you can specify another <see cref="Control"/> that contains a <see cref="ControlCollection"/>.
''' </param>
'''
''' <param name="pt">
''' The mouse point.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The resulting <see cref="Control"/>, or <see langword="Nothing"/>.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
Public Shared Function GetControlFromPoint(ByVal container As Control, ByVal pt As Point) As Control

   Dim child As Control = container
   Dim nextChild As Control = Nothing

   Do While True

       For Each ctrl As Control In child.Controls
           If (ctrl.Visible) AndAlso (ctrl.ClientRectangle.Contains(ctrl.PointToClient(pt))) Then
               nextChild = ctrl
               Exit For
           End If
       Next ctrl

       If (nextChild Is Nothing) Then
           If (container.ClientRectangle.Contains(container.PointToClient(pt))) Then
               Return container
           Else
               Return Nothing
           End If

       ElseIf (child.Equals(nextChild)) Then
           Exit Do

       Else
           child = nextChild

       End If

   Loop

   Return child

End Function


Ejemplo de uso:
Código (vbnet) [Seleccionar]
Dim ctrl As Control = GetControlFromPoint(Me, Cursor.Position)

PD: Llevo un rato preparando una respuesta con un código bastante largo para otra persona, así que por el momento no examinaré tu solución, pero si hay algo que no haya entendido bien dímelo, si o necesitas más ayuda, pídelo.

EDITO:
Algunos overloads de mi función: http://pastebin.com/Sb90A5nP

Saludos!








Lekim

#6
Hola

Bueno, pues ya lo he hecho y sin código no administrado. Ahora saldrá el listo que dirá, pero si es muy fácil no hace falta hacer tanta historia...

Cuando he preguntado y nadie me resolvía la papeleta. Incluso en otro foro (en inglés) un usuario me ha puesto de los nervios porque no hacía más que decirme que era muy fácil, que usara MouseEnter, MouseLeave. Yo le dije que estos eventos no fucionan cuando arrastras el puntero con el bóton del ratón presionado, que no devuelven el índice del control donde se encuentra el puntero. De nuevo me contesta - ten encuenta el OOP, bla, bla, bla...-, jolines si es tan fácil teclea un poco y lo pones maldito hijo de la gran....   Igual se penseava que es sólo el clic. Pero si es que hasta le puse imágenes de demostración.

Total que está hecho. No fuerzo la cancelación del evento, como hacía con Mouse_Event que era una alternativa para hacer lo que quería.

Lo he hecho usando lógica matemática, mediante un algoritmo obtengo el índice del Label en el que se encuentra el cursor, estando el botón pulsado y arrastrandose a través del array de Labels. Que repito, cuando haces esto los eventos se estancan en el primer label donde se ha hecho MouseDown y no devuelven una porra. Como demuestra este gif animado





El algoritmo:

-[(-Index)-int(X/20)]

Donde:
Index=  Indice actual (que no cambia hasta que no se colorea un nuevo label, por eso se obtiene en el evento Paint)
X = Posición X del cursor dentro del formulario
20 = Ancho del Label.


Código (vbnet) [Seleccionar]

Option Strict On
Imports System.Runtime.InteropServices


Public Class Form1
   Dim lblkey(5) As Label
   Dim index As Integer

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       Dim locLBL As New Point(10, 10)
       Dim inc As Integer
       For I As Integer = 0 To 5
           lblkey(I) = New Label
           lblkey(I).Size = CType(New Point(20, 100), Drawing.Size)
           lblkey(I).BorderStyle = BorderStyle.FixedSingle
           lblkey(I).Location = New Point(locLBL.X + inc, locLBL.Y)
           Me.Controls.Add(lblkey(I))
           inc += 19
       Next
       For I As Integer = 0 To 5
           AddHandler lblkey(I).MouseDown, AddressOf lblkey_MouseDown
           AddHandler lblkey(I).MouseUp, AddressOf lblkey_MouseUp
           AddHandler lblkey(I).MouseMove, AddressOf lblkey_MouseMove
           AddHandler lblkey(I).Paint, AddressOf lblkey_Paint
       Next

   End Sub
   Private Sub lblkey_Paint(ByVal sender As Object, ByVal e As System.EventArgs)
       index = Array.IndexOf(lblkey, sender)
   End Sub

   Private Sub lblkey_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       Dim lblPoint As New  _
       Point(lblkey(index).PointToClient(Cursor.Position).X, _
          lblkey(index).PointToClient(Cursor.Position).Y)

       If e.Button = System.Windows.Forms.MouseButtons.Left Then
           Dim newIndex As Double = - ((- index) - Conversion.Int(lblPoint.X / 20))
           Try
               Dim AllIndexs As New List(Of Integer)({0, 1, 2, 3, 4, 5})
               AllIndexs.Remove(CInt(newIndex))
               For Each El As Integer In AllIndexs
                   lblkey(El).BackColor = Color.Transparent
               Next
               lblkey(CInt(newIndex)).BackColor = Color.Red
           Catch ex As Exception
           End Try
       End If
   End Sub
   Private Sub lblkey_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        Dim indexDwn As Integer = Array.IndexOf(lblkey, sender)
       lblkey(indexDwn).BackColor = Color.Red
   End Sub
   Private Sub lblkey_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
       For I As Integer = 0 To lblkey.Count - 1
           lblkey(I).BackColor = Color.Transparent
       Next
   End Sub
End Class


lo que hay en Form_Load es para crear los Labels, configurarlos, y los eventos .

S2s




Había una errata en Mouse_Down, ya está corregida (Al hacer clic se activaba el siguiente)

Acabo de darme cuenta que el algoritmo funciona incluso aunque pongas 0 o 1 en lugar del máximo índice (N), de hecho se puede eliminar N. Ya lo he quitado.

Código (vbnet) [Seleccionar]
 Dim newIndex As Double = N - ((N -index) - Conversion.Int(lblPoint.X / 20))

Mejor así:

Código (vbnet) [Seleccionar]
 Dim newIndex As Double =  - ((-index) - Conversion.Int(lblPoint.X / 20))


También se podría poner así:

Código (vbnet) [Seleccionar]
 Dim newIndex As Double = ((index * (-1)) - Conversion.Int(lblPoint.X / 20)) * (-1)

Eleкtro

#7
Cita de: Lekim en 16 Junio 2016, 01:13 AMen otro foro (en inglés) un usuario me ha puesto de los nervios porque no hacía más que decirme que era muy fácil, que usara MouseEnter, MouseLeave. Yo le dije que estos eventos no fucionan cuando arrastras el puntero con el bóton del ratón presionado, que no devuelven el índice del control donde se encuentra el puntero. De nuevo me contesta - ten encuenta el OOP, bla, bla, bla...-, jolines si es tan fácil teclea un poco y lo pones maldito hijo de la gran....   Igual se penseava que es sólo el clic.

Hola Lekim.

Si me equivoco en mis suposiciones, corrígeme, pero según leo en ese comentario das a entender que lo que realmente quieres hacer (ahora) es conseguir que se dispare el evento MouseDown en un control mientras mantienes presionado el botón izquierdo del mouse sobre el Form y arrastras el puntero hasta ese control. ¿es así?.




Cita de: Lekim en 16 Junio 2016, 01:13 AMAhora saldrá el listo que dirá, pero si es muy fácil no hace falta hacer tanta historia...

Es que es muy fácil, no hace falta hacer tanta historia  ...xD.

No, ahora en serio, si tu propósito es hacer lo que he mencionado, entonces solamente tienes que controlar e ignorar el mensaje de ventana que se procesa cuando presionas el botón izquierdo del mouse sobre el Form (o sobre la ventana Win32 que sea), es decir, el mensaje de ventana WM_LBUTTONDOWN (&H201).

Esto puede interferir o no en lo que realmente quieras hacer, pero de todas formas te lo explicaré. Para ello simpelmente tienes que declarar un sustituto del controlador base de mensajes de ventana, el método WndProc:

Código (vbnet) [Seleccionar]
Public NotInheritable Class Form1 : Inherits Form

   Private Sub TextBox1_MouseEnter(sender As Object, e As EventArgs) Handles TextBox1.MouseEnter
       MsgBox("Hello World!")
   End Sub

   Protected Overrides Sub WndProc(ByRef m As Message)

       Select Case m.Msg
           Case &H201 ' WM_LButtonDown
               m.Result = IntPtr.Zero

           Case Else
               ' Return message to base message handler.
               MyBase.WndProc(m)
       End Select

   End Sub

End Class


Nota: El valor de retorno "0" realmente no es necesario, con dejar el bloque del Case vacío es suficiente, pero en las indicaciones de MSDN especifica que si procesamos el mensaje debemos devolver Cero ...por alguna razón será.

También te puede venir bien hacer uso del mensaje WM_NCHITTEST (&H84) junto a la enumeración de test de posicionamientos (ej. HTNOWHERE) que está documentada aquí abajo, pero esto es ya según lo que pretendas hacer.

Y ya que estamos, hago un poco de publicidad para recordarte que todo lo necesario (con respecto a lo que he explicado) lo puedes encontrar ya implementado en mi API (por si quieres trastear con la WinAPI sin tener que ponerte a declarar cientos de cosas):

EDITO:
Si necesitas un ejemplo para controlar el mensaje WM_NCHITTEST, quizás te sirva esto:
(localiza el método WndProc)

Saludos.








Lekim

#8
Cita de: Eleкtro en 16 Junio 2016, 02:20 AM
Hola Lekim.

Si me equivoco en mis suposiciones, corrígeme, pero según leo en ese comentario das a entender que lo que realmente quieres hacer (ahora) es conseguir que se dispare el evento MouseDown en un control mientras mantienes presionado el botón izquierdo del mouse sobre el Form y arrastras el puntero hasta ese control. ¿es así?.


No no es eso Elektro, pero parece que lo que has puesto puede servir, me lo voy a mirar.




Pero bueno que ya está hecho y tampoco es tanto código.
- Es código administrado
- He reducido el código considerablemente
- No tiene errores
- Es puro Net
- 100% cosecha propia

¿Cuál es la queja? XD

Lo que has puesto es a la inversa en un principio quería enviar el mensaje  WM_LBUTTONUP y Down  desde un evento. Usé Mouse_Event para hacerlo, aunque ahora veo por lo que as posteado que también podía haber usado SendMessage. Pero era un parche por no poder capturar el índice del label en el cual estaba posado el cursor con el botón del Mouse apretado al arrastrarlo por los labels.  Si reproduces el útlimo código que he posteado lo verás.


Y si has usado mi piano pues es el efecto de arrastrar el dedo por las teclas. Apretas y arrastras, suena cada nota por la que va pasando el dedo, a la vez que se apagan por las que ya a pasado y a la vez que se cambia el color de la tacla en la que se encuentra el dedo (el puntero), se pone la tecla de nuevo blanca la que ya no tiene el dedo (el puntero) y todo sin soltar. Facilísimo!!!


Eleкtro

Cita de: Lekim en 16 Junio 2016, 02:34 AM¿Cuál es la queja? XD

Por mi parte no hay ninguna queja, el código es tuyo y para ti, no para mi. Solo intento ayudarte a que puedas mejorar los hábitos de programación, pero como tu has dicho ya lo has resuelto de una manera, así que no hay que darle más vueltas.

Saludos