Asignar valores de una variable en una clase a un componente en un form !

Iniciado por TrashAmbishion, 22 Enero 2020, 04:48 AM

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

TrashAmbishion

Hola,

Tengo un codigo que me detecta las coordenadas del mouse y cuando presiono sus botones esto funciona de maravilla, todo esto en una clase.

Pero quiero tomar los valores de las coordenadas y mostrarlos en labels al hacerlo me da un  Callbackoncollecteddelegate

No logro captar bien porque sucede pero creo que es por como estoy haciendo el  llamado

Form1.label1.text = coordenadas.x

Form1.label2.text = coordenadas.y

Se que el error se produce por esto pues cuando retiro estas lineas funciona perfectamente.

Se me ocurrio crear unas variables globales en la clase y con un timer en el form cada 100ms mostrarlo pero siempre hay perdida.

Alguna forma de hacerlo sin perdidas de coordenadas.

Saludos

Hadess_inf

¿ Puedes publicar parte de tu código para poder ayudarte mejor ?

Saludos.

RoyMata

No necesitas variables globales o publicas ni tampoco un timer, ni un metodo en una clase externa. Simplemente utiliza el evento MouseMove dentro del mismo Form:

private void Form1_MouseMouse (Object sender, MouseEventArgs e)
{
     this.label1.Text = e.X;
     this.label1.Refresh();
     this.label2.Text = e.Y;
     this.label2.Refresh();
}

TrashAmbishion

Cita de: RoyMata en 22 Enero 2020, 17:33 PM
No necesitas variables globales o publicas ni tampoco un timer, ni un metodo en una clase externa. Simplemente utiliza el evento MouseMove dentro del mismo Form:

private void Form1_MouseMouse (Object sender, MouseEventArgs e)
{
     this.label1.Text = e.X;
     this.label1.Refresh();
     this.label2.Text = e.Y;
     this.label2.Refresh();
}


Gracias por la pronta respuesta, pero el codigo que tengo es para detectar los eventos del mouse a nivel global no solo a nivel de form.

TrashAmbishion

Cita de: Hadess_inf en 22 Enero 2020, 15:48 PM
¿ Puedes publicar parte de tu código para poder ayudarte mejor ?

Saludos.

Claro pero para no repetir codigo pues lo estaria repitiendo en otro post que ya tengo aqui te pongo a funcion donde estoy trabajando...

Código (vbnet) [Seleccionar]


Private Function MouseProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer

        If (nCode = HC_ACTION) Then
            Dim uInfo As MouseHookStruct = CType(Marshal.PtrToStructure(lParam, uInfo.GetType()), MouseHookStruct)
            Select Case wParam.ToInt32()
                Case WM_LBUTTONDOWN
                    MouseIsPress = True     ''Para verificar si el boton sigue presionado
                    RaiseEvent MouseDown(Me, New MouseEventArgs(MouseButtons.Left, 1, uInfo.pt.x, uInfo.pt.y, 0))
                    ' double-click hack...
                    If (m_dtLastLMouseDown.AddMilliseconds(m_iDoubleClickTime).CompareTo(Now) >= 0) Then
                        RaiseEvent MouseDoubleClick(Me, New MouseEventArgs(MouseButtons.Left, 2, uInfo.pt.x, uInfo.pt.y, 0))
                    Else
                        m_dtLastLMouseDown = Now
                    End If
                Case WM_RBUTTONDOWN
                    RaiseEvent MouseDown(Me, New MouseEventArgs(MouseButtons.Right, 1, uInfo.pt.x, uInfo.pt.y, 0))
                    ' double-click hack...
                    If (m_dtLastRMouseDown.AddMilliseconds(m_iDoubleClickTime).CompareTo(Now) >= 0) Then
                        RaiseEvent MouseDoubleClick(Me, New MouseEventArgs(MouseButtons.Right, 2, uInfo.pt.x, uInfo.pt.y, 0))
                    Else
                        m_dtLastRMouseDown = Now
                    End If
                Case WM_LBUTTONUP
                    MouseIsPress = False     ''Para verificar si el boton sigue presionado
                    RaiseEvent MouseUp(Me, New MouseEventArgs(MouseButtons.Left, 1, uInfo.pt.x, uInfo.pt.y, 0))
                Case WM_RBUTTONUP
                    RaiseEvent MouseUp(Me, New MouseEventArgs(MouseButtons.Right, 1, uInfo.pt.x, uInfo.pt.y, 0))
                Case Else
                    If (wParam <> WM_MOUSEMOVE) Then Debug.WriteLine(wParam)
            End Select

            ' uInfo es una estructura y almacena las coordenadas del mouse
            ' esta funcion esta en una clase y pense en mostrar los valores en par de labels de mi form
            ' Form1.label1.text = uInfo.pt.x
            ' Form1.label2.text = uInfo.pt.y

            ' estas lineas dan el error que ya explicaba, espero a ver sido un poco mas claro

        End If

        Return CallNextHookEx(m_iMouseHandle, nCode, wParam, lParam)


Eleкtro

Cita de: TrashAmbishion en 22 Enero 2020, 04:48 AM
Se me ocurrio crear unas variables globales en la clase y con un timer en el form cada 100ms mostrarlo pero siempre hay perdida.

Eso es exactamente lo que deberías hacer siempre y cuando desees mantener cierto equilibrio para que tu aplicación tenga un rendimiento óptimo sin llegar a saturar la carga de mensajes de ventana y operaciones de un control. No necesitas mostrar las nuevas coordenadas del mouse cada nanosegundo (exagerando xD), con actualizaciones en intervalos de 50ms o 100ms es más que suficiente.

Ten en cuenta que al desplazar el mouse a una posición, se enviarán decenas si no cientos de mensajes en menos de 1 segundo al procedimiento de ventana, y si por cada mensaje interceptado esperas mostrarlo en un label, pues... dependiendo de si tienes varios controles más realizando otras cosas, podrías percibir una notable ralentización y/o falta de respuesta o incluso congelación del form si tu metodología es sincrónica.




CitarCallbackOnCollectedDelegate

La carga pesada de lo que ya he opinado, y aunque no es el motivo principal del error "CallbackOnCollectedDelegate", aquí puedes leer como si que es un síntoma que puede estar derivando en dicho error:

Cita de: https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/callbackoncollecteddelegate-mdaThe callbackOnCollectedDelegate managed debugging assistant (MDA) is activated if a delegate is marshaled from managed to unmanaged code as a function pointer and a callback is placed on that function pointer after the delegate has been garbage collected.
Symptoms

Access violations occur when attempting to call into managed code through function pointers that were obtained from managed delegates. These failures, while not common language runtime (CLR) bugs, may appear to be so because the access violation occurs in the CLR code.

The failure is not consistent; sometimes the call on the function pointer succeeds and sometimes it fails. The failure might occur only under heavy load or on a random number of attempts.

El motivo del error también está explicado ahí, y más sencillo de entender aquí:

Muestra el código al completo para intentar identificar que declaración es la que está provocando dicho error.




Cita de: TrashAmbishion en 23 Enero 2020, 06:58 AM
es para detectar los eventos del mouse a nivel global no solo a nivel de form.

Para ello puedes utilizar la propiedad 'System.Windows.Forms.Cursor.Position'.




Por cierto, quizás esto te interese por lo del NoRecoil:
https://foro.elhacker.net/net/libreria_de_snippets_para_vbnet_compartan_aqui_sus_snippets-t378770.0.html;msg1875345#msg1875345




Cita de: TrashAmbishion en 23 Enero 2020, 07:08 AM
aqui te pongo a funcion donde estoy trabajando...

1. No estás mostrando la definición de la estructura MouseHookStruct, la cual podría contener errores de portabilidad en sus tipos. Te muestro como ya la defino:

MouseLowLevelHookStruct.vb
Código (vbnet) [Seleccionar]
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Contains information about a low-level mouse input event.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644970(v=vs.85).aspx"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
<StructLayout(LayoutKind.Sequential)>
Public Structure MouseLowLevelHookStruct ' MSLLHOOKSTRUCT

#Region " Fields "

   ''' <summary>
   ''' The x- and y-coordinates of the cursor, in screen coordinates.
   ''' </summary>
   Public Point As NativePoint

   ''' <summary>
   ''' If the message is <see cref="WindowMessages.WM_MouseWheel"/>,
   ''' the high-order word of this member is the wheel delta.
   ''' <para></para>
   ''' ( The low-order word is reserved. )
   ''' <para></para>
   ''' A positive value indicates that the wheel was rotated forward, away from the user;
   ''' a negative value indicates that the wheel was rotated backward, toward the user.
   ''' <para></para>
   ''' One wheel click is defined as <c>WHEEL_DELTA</c>, which is <c>120</c>.
   ''' <para></para>
   ''' <para></para>
   ''' <para></para>
   ''' If the message is <see cref="WindowMessages.WM_XButtonDown"/>, <see cref="WindowMessages.WM_XButtonUp"/>,
   ''' <see cref="WindowMessages.WM_XButtonDblClk"/>, <see cref="WindowMessages.WM_NcXButtonDown"/>,
   ''' <see cref="WindowMessages.WM_NcXButtonUp"/>, or <see cref="WindowMessages.WM_NcXButtonDblClk"/>,
   ''' the high-order word specifies which X button was pressed or released,
   ''' and the low-order word is reserved.
   ''' <para></para>
   ''' This value can be one or more of the following values. Otherwise, mouseData is not used.
   ''' </summary>
   Public MouseData As Integer

   ''' <summary>
   ''' The extended-key flag, event-injected flags, context code, and transition-state flag.
   ''' <para></para>
   ''' This member is specified as follows. An application can use the following values to test the mouse flags.
   ''' <para></para>
   ''' Testing <c>LLKHF_INJECTED</c> (bit 4) will tell you whether the event was injected.
   ''' If it was, then testing <c>LLKHF_LOWER_IL_INJECTED</c> (bit 1) will tell you whether or not the
   ''' event was injected from a process running at lower integrity level.
   ''' </summary>
   Public Flags As MouseLowLevelHookStructFlags

   ''' <summary>
   ''' The time stamp for this message, equivalent to what <c>GetMessageTime</c> would return for this message.
   ''' </summary>
   Public Time As UInteger

   ''' <summary>
   ''' Additional information associated with the message.
   ''' </summary>
   <SuppressMessage("Microsoft.Security", "CA2111:PointersShouldNotBeVisible", Justification:="Visible for API users")>
   Public ExtraInfo As UIntPtr

#End Region

End Structure


NativePoint.vb
Código (vbnet) [Seleccionar]
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Defines the x- and y- coordinates of a point.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd162805%28v=vs.85%29.aspx"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
<StructLayout(LayoutKind.Sequential)>
Public Structure NativePoint

#Region " Fields "

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' The X-coordinate of the point.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   Public X As Integer

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' The Y-coordinate of the point.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   Public Y As Integer

#End Region

#Region " Constructors "

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Initializes a new instance of the <see cref="NativePoint"/> struct.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <param name="x">
   ''' The X-coordinate of the point.
   ''' </param>
   '''
   ''' <param name="y">
   ''' The Y-coordinate of the point.
   ''' </param>
   ''' ----------------------------------------------------------------------------------------------------
   Public Sub New(x As Integer, y As Integer)
       Me.X = x
       Me.Y = y
   End Sub

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Initializes a new instance of the <see cref="NativePoint"/> struct.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <param name="pt">
   ''' A <see cref="Point"/> that contains the X-coordinate and the Y-coordinate.
   ''' </param>
   ''' ----------------------------------------------------------------------------------------------------
   Public Sub New(pt As Point)
       Me.New(pt.X, pt.Y)
   End Sub

#End Region

#Region " Operator Conversions "

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Performs an implicit conversion from <see cref="NativePoint"/> to <see cref="Point"/>.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <param name="pt">
   ''' The <see cref="NativePoint"/>.
   ''' </param>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <returns>
   ''' The resulting <see cref="Point"/>.
   ''' </returns>
   ''' ----------------------------------------------------------------------------------------------------
   Public Shared Widening Operator CType(pt As NativePoint) As Point
       Return New Point(pt.X, pt.Y)
   End Operator

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Performs an implicit conversion from <see cref="Point"/> to <see cref="NativePoint"/>.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <param name="pt">
   ''' The <see cref="Point"/>.
   ''' </param>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <returns>
   ''' The resulting <see cref="NativePoint"/>.
   ''' </returns>
   ''' ----------------------------------------------------------------------------------------------------
   Public Shared Widening Operator CType(pt As Point) As NativePoint
       Return New NativePoint(pt.X, pt.Y)
   End Operator

#End Region

End Structure


MouseLowLevelHookStructFlags.vb
Código (vbnet) [Seleccionar]
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' An application can use the following values to test a mouse low-level flags.
''' <para></para>
''' Flags combination for <see cref="Structures.MouseLowLevelHookStruct.Flags"/> field.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644970%28v=vs.85%29.aspx"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
<Flags>
Public Enum MouseLowLevelHookStructFlags As UInteger ' MSLLHOOKSTRUCTFlags

   ''' <summary>
   ''' Test the event-injected (from any process) flag.
   ''' </summary>
   Injected = &H1 ' LLKHF_INJECTED

   ''' <summary>
   ''' Test the event-injected (from a process running at lower integrity level) flag.
   ''' </summary>
   LowerILInjected = &H2 ' LLKHF_LOWER_IL_INJECTED

End Enum





2. Para los "hacks" del doble click, imagino que a estas alturas te dará pereza cambiarlo, pero es innecesario utilizar un objeto de tipo Date, ni TimeSpan ni StopWatch, en su lugar basta y es más eficiente con combinar la utilización de una variable de contador (para contar las veces que se repite el mensaje de ventana de un botón del mouse), la propiedad Environment.TickCount, y comprobar el valor de la función GetDoubleClickTime de la APi de Windows.

Lamentablemente no puedo mostrarte un código completo implementando lo que acabo de decir, ya que para ello tendría que extraer mucho más código para mostrar, como ya hice arriba por ejemplo.

Saludos