Foros del Web » Programación para mayores de 30 ;) » Programación General » Visual Basic clásico »

Problema al arrastrar un formulario

Estas en el tema de Problema al arrastrar un formulario en el foro de Visual Basic clásico en Foros del Web. Resulta que si pincho en un formulario y lo arrastro, en ese intervalo de tiempo el programa desatiende el resto de tareas que son en ...
  #1 (permalink)  
Antiguo 06/11/2009, 06:35
 
Fecha de Ingreso: octubre-2009
Mensajes: 15
Antigüedad: 14 años, 6 meses
Puntos: 0
Problema al arrastrar un formulario

Resulta que si pincho en un formulario y lo arrastro, en ese intervalo de tiempo el programa desatiende el resto de tareas que son en tiempo real.

¿hay alguna forma de poder arrastrar un formulario y que no afecte al resto de la aplicación?
  #2 (permalink)  
Antiguo 06/11/2009, 10:33
Avatar de lokoman  
Fecha de Ingreso: septiembre-2009
Mensajes: 502
Antigüedad: 14 años, 7 meses
Puntos: 47
Respuesta: Problema al arrastrar un formulario

Hola!!!
Escribe Doevents en tu codigo de arrastrar el form.
  #3 (permalink)  
Antiguo 06/11/2009, 11:17
 
Fecha de Ingreso: octubre-2009
Mensajes: 15
Antigüedad: 14 años, 6 meses
Puntos: 0
Respuesta: Problema al arrastrar un formulario

Cita:
Iniciado por lokoman Ver Mensaje
Hola!!!
Escribe Doevents en tu codigo de arrastrar el form.
Buenas. No hay ningún código para arrastrar el form, eso lo hace windows automáticamente.

¿alguna solución?
  #4 (permalink)  
Antiguo 06/11/2009, 11:32
Avatar de lokoman  
Fecha de Ingreso: septiembre-2009
Mensajes: 502
Antigüedad: 14 años, 7 meses
Puntos: 47
Respuesta: Problema al arrastrar un formulario

??
El Doevents permite que se cotinuen ejecutando los programas de fondo... pero si es windows desactiva los temas/efectos visuales o instala mas ram. Me imagino que re pasa con cualquier otra aplicación...
  #5 (permalink)  
Antiguo 06/11/2009, 14:03
 
Fecha de Ingreso: octubre-2009
Mensajes: 15
Antigüedad: 14 años, 6 meses
Puntos: 0
Respuesta: Problema al arrastrar un formulario

Bueno, pues al final lo he solucionado haciendo dos ejecutables:

El primero que sería invisible va guardando el resultado de los cálculos en tiempo real en el portapapeles de windows usando el Objeto Clipboard

El segundo es el que contiene el formulario con el text box y lo que hace es tomar el texto del portapapeles y cargarlo en el TextBox.

Ahora, por mucho que arrastre o mueva el formulario no afecta para nada a la otra aplicación, porque son ejecutables distintos.

¿alguien sabe alguna forma más profesional de hacerlo? porque lo del portapapeles me parece una chapuza (aunque de momento me saca las castañas del fuego)
  #6 (permalink)  
Antiguo 06/11/2009, 16:01
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Problema al arrastrar un formulario

Quizá puedas usar SaveSetting y GetSetting para ir pasando los datos a través del registro.

En el receptor pones un timer con algo como esto:
Timer1_Timer()
TextoCapturado = GetSetting(App.Title, "TXRX", "Datos", "")
SaveSetting App.Title, "TXRX", "Datos", ""
Call ProcesaDatos (TextoCapturado)
End Sub
o puedes hacer un bucle con un Loop como lo tenias

y en el transmisor:
SaveSetting App.Title, "TXRX", "Datos", GetSetting(App.Title, "TXRX", "Datos", "") & vbCrLf & DatosAEnviar

De este modo si el transmisor es más rápido que el receptor irá acumulando los datos en el registro y cuando el receptor los lea los borra y procesa todos los paquetes enviados.

Es una idea.

Otra idea es usar SendMessage para mandar los datos a un textbox del programa receptor. Incluso para no tener que andar usando FindWindow para conseguir el hWnd del textbox receptor puedes hacer que el programa receptor al arrancar guarde el hwnd del textbox receptor en el registro usando savesetting y el transmisor mande los datos con sendmessage a ese hwnd, evitando así usar findwindow tantas veces. No se si me explico.

PD:
El problema aquí es que si quieres conseguir acumular los datos enviados tienes que usar 3 veces sendmessage. Una para conseguir la longitud del texto actual, otra para conseguir el texto en si y otra para mandar el texto mas los nuevos datos.

Lo mejor sería probar primero sin intentar acumularlos a ver si el receptor responde bien.
Igual con sendmessage que con savesetting yo probaría primero sin acumular:

SaveSetting App.Title, "TXRX", "Datos", DatosAEnviar
en lugar de
SaveSetting App.Title, "TXRX", "Datos", GetSetting(App.Title, "TXRX", "Datos", "") & vbCrLf & DatosAEnviar
Si usas un Loop igual tiene suficiente velocidad el receptor.

Que se dé bien.

Última edición por pkj; 06/11/2009 a las 16:20
  #7 (permalink)  
Antiguo 06/11/2009, 16:24
 
Fecha de Ingreso: octubre-2009
Mensajes: 15
Antigüedad: 14 años, 6 meses
Puntos: 0
Respuesta: Problema al arrastrar un formulario

Cita:
Iniciado por pkj Ver Mensaje
Quizá puedas usar SaveSetting y GetSetting para ir pasando los datos a través del registro.

En el receptor pones un timer con algo como esto:
Timer1_Timer()
TextoCapturado = GetSetting(App.Title, "TXRX", "Datos", "")
SaveSetting App.Title, "TXRX", "Datos", ""
Call ProcesaDatos (TextoCapturado)
End Sub

y en el transmisor:
SaveSetting App.Title, "TXRX", "Datos", GetSetting(App.Title, "TXRX", "Datos", "") & vbCrLf & DatosAEnviar

De este modo si el transmisor es más rápido que el receptor irá acumulando los datos en el registro y cuando el receptor los lea los borra y procesa todos los paquetes enviados.

Es una idea.

Otra idea es usar SendMessage para mandar los datos a un textbox del programa receptor. Incluso para no tener que andar usando FindWindow para conseguir el hWnd del textbox receptor puedes hacer que el programa receptor al arrancar guarde el hwnd del textbox receptor en el registro usando savesetting y el transmisor mande los datos con sendmessage a ese hwnd, evitando así usar findwindow tantas veces. No se si me explico.

Que se dé bien.
Gracias tío. Pues no conocía eso del "Registro de windows", ¿me lo recomiendas mejor que el portapapeles? porque para borrar los datos en el portapapeles también se puede usar un Clipboard.Clear, así conforme voy leyendo voy eliminando. Mi duda es que si estás con el WORD o cualquier otra aplicación al mismo tiempo que se graben datos al portapapeles y se lie todo.

¿Con SendMessage si oculto el textbox del receptor también funciona?
  #8 (permalink)  
Antiguo 06/11/2009, 16:31
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Problema al arrastrar un formulario

Ese es el tema, que si usas el portapapeles con el programa no puedes usarlo en otro sitio.

Me has pillado con los 2 proyectos con los que estaba probando el sendmessage aun cargados y he comprobado que si que recibe los datos aunque el textbox esté oculto.
  #9 (permalink)  
Antiguo 06/11/2009, 17:12
 
Fecha de Ingreso: octubre-2009
Mensajes: 15
Antigüedad: 14 años, 6 meses
Puntos: 0
Respuesta: Problema al arrastrar un formulario

Creo que voy a ponerme las pilas con SendMessage, no sabía ni que existía eso.

Aquí he visto un ejemplo chulo:

http://foro.elhacker.net/programacio...t244803.0.html
  #10 (permalink)  
Antiguo 06/11/2009, 22:14
 
Fecha de Ingreso: abril-2005
Mensajes: 351
Antigüedad: 19 años
Puntos: 3
Respuesta: Problema al arrastrar un formulario

Hola te paso un ejemplo utlizando SendMessage con WM_COPYDATA (ojo nada que ver con el portapapeles)

En la Aplicacion que va a recivir los mensages

Dentro de un modulo bas
Código:
Option Explicit
'---------------------------------------
'Autor:     Leandro Ascierto
'Web:       www.leandroascierto.com.ar
'Date:      07/11/09
'---------------------------------------
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Declare Function CreateWindowEx Lib "user32.dll" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, ByRef lpParam As Any) As Long
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function DestroyWindow Lib "user32.dll" (ByVal hwnd As Long) As Long

Private Const GWL_WNDPROC = (-4)
Private Const WM_COPYDATA = &H4A

Private Type COPYDATASTRUCT
    dwData As Long
    cbData As Long
    lpData As Long
End Type

Dim PrevProc As Long
Dim hWin As Long

Public Sub StartListen(ByVal sKey As String)
    hWin = CreateWindowEx(0, "Static", sKey, 0, 0, 0, 0, 0, 0, 0, 0, 0&)
    PrevProc = SetWindowLong(hWin, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub StopListen()
    SetWindowLong hWin, GWL_WNDPROC, PrevProc
    DestroyWindow hWin
End Sub

Private Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    If uMsg = WM_COPYDATA Then
        Dim sBuff As String
        Dim CDS As COPYDATASTRUCT
        Call CopyMemory(CDS, ByVal lParam, Len(CDS))
        sBuff = Space(CDS.cbData)
        Call CopyMemory(ByVal sBuff, ByVal CDS.lpData, CDS.cbData)
        '------------
        ProcesarDatos sBuff
    End If

    WindowProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)


End Function

Private Sub ProcesarDatos(sDATA As String)
    Form1.Text1 = sDATA '<---Ojo aca con el nombre del formulario
End Sub
y dentro del formulario (Que para este ejemplo se llama Form1)
Código:
Option Explicit
Const PersonalKey = "MyKeyWindow"

Private Sub Form_Load()
    StartListen PersonalKey
End Sub

Private Sub Form_Unload(Cancel As Integer)
    StopListen
End Sub
en la aplicacion que envia los mensages
agrega para probar un formulario con un Command1
Código:
Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Const WM_COPYDATA = &H4A

Private Type COPYDATASTRUCT
    dwData As Long
    cbData As Long
    lpData As Long
End Type

Const PersonalKey = "MyKeyWindow"

Private Function SendData(ByVal sKey As String, ByVal sDATA As String) As Boolean
    Dim CDS As COPYDATASTRUCT
    Dim sSTR As String
    Dim hWin As String
        
    hWin = FindWindow("Static", sKey)
    If hWin Then
        sSTR = StrConv(sDATA, vbFromUnicode)
        With CDS
            .dwData = 3
            .cbData = LenB(sSTR)
            .lpData = StrPtr(sSTR)
        End With
        SendData = SendMessage(hWin, WM_COPYDATA, Me.hwnd, CDS) = 0
    End If
End Function


Private Sub Command1_Click()
    Call SendData(PersonalKey, "hola mundo")
End Sub
__________________
www.leandroascierto.com
  #11 (permalink)  
Antiguo 07/11/2009, 05:56
 
Fecha de Ingreso: octubre-2009
Mensajes: 15
Antigüedad: 14 años, 6 meses
Puntos: 0
Respuesta: Problema al arrastrar un formulario

Cita:
Iniciado por LeandroA Ver Mensaje
Hola te paso un ejemplo utlizando SendMessage con WM_COPYDATA (ojo nada que ver con el portapapeles)

En la Aplicacion que va a recivir los mensages

Dentro de un modulo bas
Código:
Option Explicit
'---------------------------------------
'Autor:     Leandro Ascierto
'Web:       www.leandroascierto.com.ar
'Date:      07/11/09
'---------------------------------------
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Declare Function CreateWindowEx Lib "user32.dll" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, ByRef lpParam As Any) As Long
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function DestroyWindow Lib "user32.dll" (ByVal hwnd As Long) As Long

Private Const GWL_WNDPROC = (-4)
Private Const WM_COPYDATA = &H4A

Private Type COPYDATASTRUCT
    dwData As Long
    cbData As Long
    lpData As Long
End Type

Dim PrevProc As Long
Dim hWin As Long

Public Sub StartListen(ByVal sKey As String)
    hWin = CreateWindowEx(0, "Static", sKey, 0, 0, 0, 0, 0, 0, 0, 0, 0&)
    PrevProc = SetWindowLong(hWin, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub StopListen()
    SetWindowLong hWin, GWL_WNDPROC, PrevProc
    DestroyWindow hWin
End Sub

Private Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    If uMsg = WM_COPYDATA Then
        Dim sBuff As String
        Dim CDS As COPYDATASTRUCT
        Call CopyMemory(CDS, ByVal lParam, Len(CDS))
        sBuff = Space(CDS.cbData)
        Call CopyMemory(ByVal sBuff, ByVal CDS.lpData, CDS.cbData)
        '------------
        ProcesarDatos sBuff
    End If

    WindowProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)


End Function

Private Sub ProcesarDatos(sDATA As String)
    Form1.Text1 = sDATA '<---Ojo aca con el nombre del formulario
End Sub
y dentro del formulario (Que para este ejemplo se llama Form1)
Código:
Option Explicit
Const PersonalKey = "MyKeyWindow"

Private Sub Form_Load()
    StartListen PersonalKey
End Sub

Private Sub Form_Unload(Cancel As Integer)
    StopListen
End Sub
en la aplicacion que envia los mensages
agrega para probar un formulario con un Command1
Código:
Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Const WM_COPYDATA = &H4A

Private Type COPYDATASTRUCT
    dwData As Long
    cbData As Long
    lpData As Long
End Type

Const PersonalKey = "MyKeyWindow"

Private Function SendData(ByVal sKey As String, ByVal sDATA As String) As Boolean
    Dim CDS As COPYDATASTRUCT
    Dim sSTR As String
    Dim hWin As String
        
    hWin = FindWindow("Static", sKey)
    If hWin Then
        sSTR = StrConv(sDATA, vbFromUnicode)
        With CDS
            .dwData = 3
            .cbData = LenB(sSTR)
            .lpData = StrPtr(sSTR)
        End With
        SendData = SendMessage(hWin, WM_COPYDATA, Me.hwnd, CDS) = 0
    End If
End Function


Private Sub Command1_Click()
    Call SendData(PersonalKey, "hola mundo")
End Sub
Gracias, voy a mirármelo con más calma. ¿Lo de COPY_DATA que es exactamente?
  #12 (permalink)  
Antiguo 07/11/2009, 09:37
 
Fecha de Ingreso: abril-2005
Mensajes: 351
Antigüedad: 19 años
Puntos: 3
Respuesta: Problema al arrastrar un formulario

Cita:
Iniciado por JAlbertoDJ Ver Mensaje
Gracias, voy a mirármelo con más calma. ¿Lo de COPY_DATA que es exactamente?

mm bueno aver como lo explico WM_COPY_DATA WM significa windows mensage

osea un mensage que recive la ventana hay muchos tipos de mensage (es algo asi como un evento) las ventanas reciben muchos tipos de mensages por ejemplo cuando pasas el mouse por ensima de esta recive el WM_MOUSEMOVE cuando activas la ventana recive el msg WM_ACTIVATE y bueno asi muchos mas

entonses cuando le pasas WM_COPY_DATA le estas indicando a la ventana que esta reciviendo una DATA donde dentro de un parametro LPARM esta el puntero de una extructura que contiene la informacion que esta va a recibir. este msg es algo personalizado ya que si vos no lo manejas a la ventana no le afecta ni produce nada en especial.
__________________
www.leandroascierto.com
  #13 (permalink)  
Antiguo 08/11/2009, 08:04
 
Fecha de Ingreso: octubre-2009
Mensajes: 15
Antigüedad: 14 años, 6 meses
Puntos: 0
Respuesta: Problema al arrastrar un formulario

Cita:
Iniciado por leandroa Ver Mensaje
mm bueno aver como lo explico wm_copy_data wm significa windows mensage

osea un mensage que recive la ventana hay muchos tipos de mensage (es algo asi como un evento) las ventanas reciben muchos tipos de mensages por ejemplo cuando pasas el mouse por ensima de esta recive el wm_mousemove cuando activas la ventana recive el msg wm_activate y bueno asi muchos mas

entonses cuando le pasas wm_copy_data le estas indicando a la ventana que esta reciviendo una data donde dentro de un parametro lparm esta el puntero de una extructura que contiene la informacion que esta va a recibir. Este msg es algo personalizado ya que si vos no lo manejas a la ventana no le afecta ni produce nada en especial.
ok
  #14 (permalink)  
Antiguo 10/11/2009, 15:56
 
Fecha de Ingreso: octubre-2009
Mensajes: 15
Antigüedad: 14 años, 6 meses
Puntos: 0
Respuesta: Problema al arrastrar un formulario

Bueno, pues se acabaron las tonterías.

Al final lo he solucionado enviando SendMessage al textbox de destino, con todo el contenido del textbox.

Call SendMessage(Hwndl, WM_SETTEXT, 0, ByVal RistraDeCaracteres)

Y listo.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 08:38.