elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a la Factorización De Semiprimos (RSA)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Terminar evento MouseDown con el botón del ratón pulsado
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Terminar evento MouseDown con el botón del ratón pulsado  (Leído 6,662 veces)
Lekim

Desconectado Desconectado

Mensajes: 268



Ver Perfil
Terminar evento MouseDown con el botón del ratón pulsado
« en: 12 Junio 2016, 17:24 pm »


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
  1. 'Programmed by Lekim'
  2. Option Strict On
  3. Imports System.Runtime.InteropServices
  4.  
  5.  
  6. Public Class Form1
  7.  
  8.    <DllImport("user32.dll")> _
  9.    Private Shared Sub mouse_event(ByVal dwFlags As UInteger, _
  10.                                   ByVal dx As UInteger, _
  11.                                   ByVal dy As UInteger, _
  12.                                   ByVal dwData As UInteger, _
  13.                                   ByVal dwExtraInfo As Integer)
  14.    End Sub
  15.  
  16.  
  17.    Dim lblkey(5) As Label
  18.    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  19.  
  20.        Dim locLBL As New Point(10, 10)
  21.        Dim inc As Integer
  22.        For I As Integer = 0 To 5
  23.            lblkey(I) = New Label
  24.            lblkey(I).Size = CType(New Point(20, 100), Drawing.Size)
  25.            lblkey(I).BorderStyle = BorderStyle.FixedSingle
  26.            lblkey(I).Location = New Point(locLBL.X + inc, locLBL.Y)
  27.            Me.Controls.Add(lblkey(I))
  28.            inc += 19
  29.        Next
  30.        For I As Integer = 0 To 5
  31.            AddHandler lblkey(I).MouseDown, AddressOf lblkey_MouseDown
  32.            AddHandler lblkey(I).MouseUp, AddressOf lblkey_MouseUp
  33.            AddHandler lblkey(I).MouseMove, AddressOf lblkey_MouseMove
  34.  
  35.        Next
  36.  
  37.    End Sub
  38.    Private Sub lblkey_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  39.        Dim Index As Integer = Array.IndexOf(lblkey, sender)
  40.        Dim mPoint As New Point(Me.PointToClient(Cursor.Position).X, Me.PointToClient(Cursor.Position).Y)
  41.        Dim X As Integer = mPoint.X
  42.  
  43.        If X < CInt(lblkey(Index).Left) Or
  44.            X > (CInt(lblkey(Index).Left) + _
  45.                 CInt(lblkey(Index).Width)) Then
  46.            EventoUp()
  47.            EventoDown()
  48.        End If
  49.  
  50.    End Sub
  51.    Private Sub lblkey_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  52.        Dim Index As Integer = Array.IndexOf(lblkey, sender)
  53.        If Button.MouseButtons = MouseButtons.Left Then
  54.            lblkey(Index).BackColor = Color.Azure
  55.        End If
  56.    End Sub
  57.    Private Sub lblkey_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  58.        Dim Index As Integer = Array.IndexOf(lblkey, sender)
  59.        lblkey(Index).BackColor = Color.Transparent
  60.    End Sub
  61.  
  62. End Class
  63. Module modEventMouse
  64.    <DllImport("user32.dll")> _
  65.    Public Sub mouse_event(ByVal dwFlags As UInteger, _
  66.                                   ByVal dx As UInteger, _
  67.                                   ByVal dy As UInteger, _
  68.                                   ByVal dwData As UInteger, _
  69.                                   ByVal dwExtraInfo As Integer)
  70.    End Sub
  71.    <Flags()> _
  72.    Public Enum MouseEventFlags As UInteger
  73.        MOUSEEVENTF_ABSOLUTE = &H8000
  74.        MOUSEEVENTF_LEFTDOWN = &H2
  75.        MOUSEEVENTF_LEFTUP = &H4
  76.        MOUSEEVENTF_MIDDLEDOWN = &H20
  77.        MOUSEEVENTF_MIDDLEUP = &H40
  78.        MOUSEEVENTF_MOVE = &H1
  79.        MOUSEEVENTF_RIGHTDOWN = &H8
  80.        MOUSEEVENTF_RIGHTUP = &H10
  81.        MOUSEEVENTF_XDOWN = &H80
  82.        MOUSEEVENTF_XUP = &H100
  83.        MOUSEEVENTF_WHEEL = &H800
  84.        MOUSEEVENTF_HWHEEL = &H1000
  85.    End Enum
  86.    ''' <summary>
  87.    ''' Simulate MouseDown the left mouse button
  88.    ''' </summary>
  89.    ''' <remarks></remarks>
  90.    Public Sub EventoDown()
  91.        Call modEventMouse.mouse_event(MouseEventFlags.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
  92.    End Sub
  93.    ''' <summary>
  94.    ''' Simulate MouseUp the left mouse button
  95.    ''' </summary>
  96.    ''' <remarks></remarks>
  97.    Public Sub EventoUp()
  98.        Call modEventMouse.mouse_event(MouseEventFlags.MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0)
  99.    End Sub
  100.  
  101.  
  102. End Module
  103.  
  104.  
  105.  



« Última modificación: 14 Junio 2016, 11:10 am por Lekim » En línea

DarK_FirefoX


Desconectado Desconectado

Mensajes: 1.263


Be the change you wanna see in te world


Ver Perfil
Re: Quitar enfoque al salir de un objeto y en MouseDown
« Respuesta #1 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


En línea

Lekim

Desconectado Desconectado

Mensajes: 268



Ver Perfil
Re: Quitar enfoque al salir de un objeto y en MouseDown
« Respuesta #2 en: 12 Junio 2016, 18:58 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
  1. Imports System.Runtime.InteropServices
  2.  
  3. Public Class Form1
  4.  
  5.    <DllImport("user32.dll")> _
  6.    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)
  7.    End Sub
  8.  
  9.    Const MOUSEEVENTF_MOVE = &H1 '  movimiento del mouse
  10.    Const MOUSEEVENTF_LEFTDOWN = &H2 '  botón izquierdo presionado
  11.    Const MOUSEEVENTF_LEFTUP = &H4 '  botón izquierdo soltado
  12.    Const MOUSEEVENTF_RIGHTDOWN = &H8 '  botón derecho presionado
  13.    Const MOUSEEVENTF_RIGHTUP = &H10 '  botón derecho soltado
  14.    Const MOUSEEVENTF_MIDDLEDOWN = &H20 '  botón central presionado
  15.    Const MOUSEEVENTF_MIDDLEUP = &H40 ' botón central soltado
  16.    Const MOUSEEVENTF_ABSOLUTE = &H8000 '  movimiento absoluto
  17.    Dim lblkey(2) As Label
  18.    Dim Pulsado As Integer = False
  19.    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  20.  
  21.        Dim locLBL As New Point(10, 10)
  22.        Dim inc As Integer
  23.        For I As Integer = 0 To 2
  24.  
  25.            lblkey(I) = New Label
  26.            lblkey(I).Size = New Point(20, 100)
  27.            lblkey(I).BorderStyle = BorderStyle.FixedSingle
  28.            lblkey(I).Location = New Point(locLBL.X + inc, locLBL.Y)
  29.            Me.Controls.Add(lblkey(I))
  30.            inc += 19
  31.        Next
  32.        For I As Integer = 0 To 2
  33.            AddHandler lblkey(I).MouseDown, AddressOf lblkey_MouseDown
  34.            AddHandler lblkey(I).MouseUp, AddressOf lblkey_MouseUp
  35.            AddHandler lblkey(I).MouseEnter, AddressOf lblkey_MouseEnter
  36.            AddHandler lblkey(I).Click, AddressOf lblkey_MouseClick
  37.            AddHandler lblkey(I).MouseMove, AddressOf lblkey_MouseMove
  38.        Next
  39.  
  40.    End Sub
  41.    Private Sub lblkey_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  42.        Dim Index As Integer = Array.IndexOf(lblkey, sender)
  43.        Dim punto As New Point(Me.PointToClient(Cursor.Position))
  44.        Dim X As Integer = punto.X
  45.  
  46.        If X < CInt(lblkey(Index).Left) Or X > (CInt(lblkey(Index).Left) + CInt(lblkey(Index).Width)) And _
  47.            Button.MouseButtons = MouseButtons.Left And Pulsado = True Then
  48.            SueltaBoton()
  49.            ClicBoton()
  50.  
  51.        End If
  52.    End Sub
  53.    Private Sub lblkey_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  54.        Dim Index As Integer = Array.IndexOf(lblkey, sender)
  55.        If Button.MouseButtons = MouseButtons.Left Then
  56.            lblkey(Index).BackColor = Color.Azure
  57.        End If
  58.    End Sub
  59.  
  60.    Private Sub lblkey_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  61.    End Sub
  62.    Private Sub lblkey_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs)
  63.    End Sub
  64.    Private Sub lblkey_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  65.        Dim Index As Integer = Array.IndexOf(lblkey, sender)
  66.        lblkey(Index).BackColor = Color.Transparent
  67.    End Sub
  68.    Public Sub ClicBoton()
  69.        'Simula el clic del boton izquierdo del ratón
  70.        Call mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
  71.    End Sub
  72.  
  73.    Public Sub SueltaBoton()
  74.        'Simula el clic del boton izquierdo del ratón
  75.        Call mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0)
  76.    End Sub
  77. 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
  1.  
  2. 'Programmed by Lekim'
  3. Option Strict On
  4. Imports System.Runtime.InteropServices
  5.  
  6.  
  7. Public Class Form1
  8.  
  9.    <DllImport("user32.dll")> _
  10.    Private Shared Sub mouse_event(ByVal dwFlags As UInteger, _
  11.                                   ByVal dx As UInteger, _
  12.                                   ByVal dy As UInteger, _
  13.                                   ByVal dwData As UInteger, _
  14.                                   ByVal dwExtraInfo As Integer)
  15.    End Sub
  16.  
  17.  
  18.    Dim lblkey(5) As Label
  19.    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  20.  
  21.        Dim locLBL As New Point(10, 10)
  22.        Dim inc As Integer
  23.        For I As Integer = 0 To 5
  24.            lblkey(I) = New Label
  25.            lblkey(I).Size = CType(New Point(20, 100), Drawing.Size)
  26.            lblkey(I).BorderStyle = BorderStyle.FixedSingle
  27.            lblkey(I).Location = New Point(locLBL.X + inc, locLBL.Y)
  28.            Me.Controls.Add(lblkey(I))
  29.            inc += 19
  30.        Next
  31.        For I As Integer = 0 To 5
  32.            AddHandler lblkey(I).MouseDown, AddressOf lblkey_MouseDown
  33.            AddHandler lblkey(I).MouseUp, AddressOf lblkey_MouseUp
  34.            AddHandler lblkey(I).MouseMove, AddressOf lblkey_MouseMove
  35.  
  36.        Next
  37.  
  38.    End Sub
  39.    Private Sub lblkey_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  40.        Dim Index As Integer = Array.IndexOf(lblkey, sender)
  41.        Dim mPoint As New Point(Me.PointToClient(Cursor.Position).X, Me.PointToClient(Cursor.Position).Y)
  42.        Dim X As Integer = mPoint.X
  43.  
  44.        If X < CInt(lblkey(Index).Left) Or
  45.            X > (CInt(lblkey(Index).Left) + _
  46.                 CInt(lblkey(Index).Width)) Then
  47.            EventoUp()
  48.            EventoDown()
  49.        End If
  50.  
  51.    End Sub
  52.    Private Sub lblkey_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  53.        Dim Index As Integer = Array.IndexOf(lblkey, sender)
  54.        If Button.MouseButtons = MouseButtons.Left Then
  55.            lblkey(Index).BackColor = Color.Azure
  56.        End If
  57.    End Sub
  58.    Private Sub lblkey_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  59.        Dim Index As Integer = Array.IndexOf(lblkey, sender)
  60.        lblkey(Index).BackColor = Color.Transparent
  61.    End Sub
  62.  
  63. End Class
  64. Module modEventMouse
  65.    <DllImport("user32.dll")> _
  66.    Public Sub mouse_event(ByVal dwFlags As UInteger, _
  67.                                   ByVal dx As UInteger, _
  68.                                   ByVal dy As UInteger, _
  69.                                   ByVal dwData As UInteger, _
  70.                                   ByVal dwExtraInfo As Integer)
  71.    End Sub
  72.    <Flags()> _
  73.    Public Enum MouseEventFlags As UInteger
  74.        MOUSEEVENTF_ABSOLUTE = &H8000
  75.        MOUSEEVENTF_LEFTDOWN = &H2
  76.        MOUSEEVENTF_LEFTUP = &H4
  77.        MOUSEEVENTF_MIDDLEDOWN = &H20
  78.        MOUSEEVENTF_MIDDLEUP = &H40
  79.        MOUSEEVENTF_MOVE = &H1
  80.        MOUSEEVENTF_RIGHTDOWN = &H8
  81.        MOUSEEVENTF_RIGHTUP = &H10
  82.        MOUSEEVENTF_XDOWN = &H80
  83.        MOUSEEVENTF_XUP = &H100
  84.        MOUSEEVENTF_WHEEL = &H800
  85.        MOUSEEVENTF_HWHEEL = &H1000
  86.    End Enum
  87.    ''' <summary>
  88.    ''' Simulate MouseDown the left mouse button
  89.    ''' </summary>
  90.    ''' <remarks></remarks>
  91.    Public Sub EventoDown()
  92.        Call modEventMouse.mouse_event(MouseEventFlags.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
  93.    End Sub
  94.    ''' <summary>
  95.    ''' Simulate MouseUp the left mouse button
  96.    ''' </summary>
  97.    ''' <remarks></remarks>
  98.    Public Sub EventoUp()
  99.        Call modEventMouse.mouse_event(MouseEventFlags.MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0)
  100.    End Sub
  101.  
  102.  
  103. End Module
  104.  




¿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.  :¬¬

« Última modificación: 13 Junio 2016, 20:57 pm por Lekim » En línea

DarK_FirefoX


Desconectado Desconectado

Mensajes: 1.263


Be the change you wanna see in te world


Ver Perfil
Re: Quitar enfoque al salir de un objeto y en MouseDown
« Respuesta #3 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
En línea

Lekim

Desconectado Desconectado

Mensajes: 268



Ver Perfil
Re: Quitar enfoque al salir de un objeto y en MouseDown
« Respuesta #4 en: 14 Junio 2016, 10:01 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
En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.810



Ver Perfil
Re: Terminar evento MouseDown con el botón del ratón pulsado
« Respuesta #5 en: 14 Junio 2016, 22:31 pm »

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
  1. ''' ----------------------------------------------------------------------------------------------------
  2. ''' <summary>
  3. ''' Gets the corresponding control (if any) that is over the specified mouse point.
  4. ''' </summary>
  5. ''' ----------------------------------------------------------------------------------------------------
  6. ''' <param name="container">
  7. ''' The source container of controls where to search for.
  8. ''' <para></para>
  9. ''' Normally a <see cref="Form"/>, but you can specify another <see cref="Control"/> that contains a <see cref="ControlCollection"/>.
  10. ''' </param>
  11. '''
  12. ''' <param name="pt">
  13. ''' The mouse point.
  14. ''' </param>
  15. ''' ----------------------------------------------------------------------------------------------------
  16. ''' <returns>
  17. ''' The resulting <see cref="Control"/>, or <see langword="Nothing"/>.
  18. ''' </returns>
  19. ''' ----------------------------------------------------------------------------------------------------
  20. Public Shared Function GetControlFromPoint(ByVal container As Control, ByVal pt As Point) As Control
  21.  
  22.    Dim child As Control = container
  23.    Dim nextChild As Control = Nothing
  24.  
  25.    Do While True
  26.  
  27.        For Each ctrl As Control In child.Controls
  28.            If (ctrl.Visible) AndAlso (ctrl.ClientRectangle.Contains(ctrl.PointToClient(pt))) Then
  29.                nextChild = ctrl
  30.                Exit For
  31.            End If
  32.        Next ctrl
  33.  
  34.        If (nextChild Is Nothing) Then
  35.            If (container.ClientRectangle.Contains(container.PointToClient(pt))) Then
  36.                Return container
  37.            Else
  38.                Return Nothing
  39.            End If
  40.  
  41.        ElseIf (child.Equals(nextChild)) Then
  42.            Exit Do
  43.  
  44.        Else
  45.            child = nextChild
  46.  
  47.        End If
  48.  
  49.    Loop
  50.  
  51.    Return child
  52.  
  53. End Function

Ejemplo de uso:
Código
  1. 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!
« Última modificación: 14 Junio 2016, 22:53 pm por Eleкtro » En línea

Lekim

Desconectado Desconectado

Mensajes: 268



Ver Perfil
Re: Terminar evento MouseDown con el botón del ratón pulsado
« Respuesta #6 en: 16 Junio 2016, 01:13 am »

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:

Código:
 -[(-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
  1. Option Strict On
  2. Imports System.Runtime.InteropServices
  3.  
  4.  
  5. Public Class Form1
  6.    Dim lblkey(5) As Label
  7.    Dim index As Integer
  8.  
  9.    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  10.        Dim locLBL As New Point(10, 10)
  11.        Dim inc As Integer
  12.        For I As Integer = 0 To 5
  13.            lblkey(I) = New Label
  14.            lblkey(I).Size = CType(New Point(20, 100), Drawing.Size)
  15.            lblkey(I).BorderStyle = BorderStyle.FixedSingle
  16.            lblkey(I).Location = New Point(locLBL.X + inc, locLBL.Y)
  17.            Me.Controls.Add(lblkey(I))
  18.            inc += 19
  19.        Next
  20.        For I As Integer = 0 To 5
  21.            AddHandler lblkey(I).MouseDown, AddressOf lblkey_MouseDown
  22.            AddHandler lblkey(I).MouseUp, AddressOf lblkey_MouseUp
  23.            AddHandler lblkey(I).MouseMove, AddressOf lblkey_MouseMove
  24.            AddHandler lblkey(I).Paint, AddressOf lblkey_Paint
  25.        Next
  26.  
  27.    End Sub
  28.    Private Sub lblkey_Paint(ByVal sender As Object, ByVal e As System.EventArgs)
  29.        index = Array.IndexOf(lblkey, sender)
  30.    End Sub
  31.  
  32.    Private Sub lblkey_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  33.        Dim lblPoint As New  _
  34.        Point(lblkey(index).PointToClient(Cursor.Position).X, _
  35.           lblkey(index).PointToClient(Cursor.Position).Y)
  36.  
  37.        If e.Button = System.Windows.Forms.MouseButtons.Left Then
  38.            Dim newIndex As Double = - ((- index) - Conversion.Int(lblPoint.X / 20))
  39.            Try
  40.                Dim AllIndexs As New List(Of Integer)({0, 1, 2, 3, 4, 5})
  41.                AllIndexs.Remove(CInt(newIndex))
  42.                For Each El As Integer In AllIndexs
  43.                    lblkey(El).BackColor = Color.Transparent
  44.                Next
  45.                lblkey(CInt(newIndex)).BackColor = Color.Red
  46.            Catch ex As Exception
  47.            End Try
  48.        End If
  49.    End Sub
  50.    Private Sub lblkey_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  51.         Dim indexDwn As Integer = Array.IndexOf(lblkey, sender)
  52.        lblkey(indexDwn).BackColor = Color.Red
  53.    End Sub
  54.    Private Sub lblkey_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  55.        For I As Integer = 0 To lblkey.Count - 1
  56.            lblkey(I).BackColor = Color.Transparent
  57.        Next
  58.    End Sub
  59. End Class
  60.  

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
  1.  Dim newIndex As Double = N - ((N -index) - Conversion.Int(lblPoint.X / 20))

Mejor así:

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


También se podría poner así:

Código
  1.  Dim newIndex As Double = ((index * (-1)) - Conversion.Int(lblPoint.X / 20)) * (-1)
« Última modificación: 20 Junio 2016, 00:38 am por Lekim » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.810



Ver Perfil
Re: Terminar evento MouseDown con el botón del ratón pulsado
« Respuesta #7 en: 16 Junio 2016, 02:20 am »

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.

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í?.



Ahora 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
  1. Public NotInheritable Class Form1 : Inherits Form
  2.  
  3.    Private Sub TextBox1_MouseEnter(sender As Object, e As EventArgs) Handles TextBox1.MouseEnter
  4.        MsgBox("Hello World!")
  5.    End Sub
  6.  
  7.    Protected Overrides Sub WndProc(ByRef m As Message)
  8.  
  9.        Select Case m.Msg
  10.            Case &H201 ' WM_LButtonDown
  11.                m.Result = IntPtr.Zero
  12.  
  13.            Case Else
  14.                ' Return message to base message handler.
  15.                MyBase.WndProc(m)
  16.        End Select
  17.  
  18.    End Sub
  19.  
  20. 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.
« Última modificación: 16 Junio 2016, 02:38 am por Eleкtro » En línea

Lekim

Desconectado Desconectado

Mensajes: 268



Ver Perfil
Re: Terminar evento MouseDown con el botón del ratón pulsado
« Respuesta #8 en: 16 Junio 2016, 02:34 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!!!

« Última modificación: 20 Junio 2016, 00:34 am por Lekim » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.810



Ver Perfil
Re: Terminar evento MouseDown con el botón del ratón pulsado
« Respuesta #9 en: 16 Junio 2016, 05:24 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
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines