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?
| |||
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? |
| |||
Respuesta: Problema al arrastrar un formulario Buenas. No hay ningún código para arrastrar el form, eso lo hace windows automáticamente. ¿alguna solución? |
| |||
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) |
| ||||
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 |
| |||
Respuesta: Problema al arrastrar un formulario Cita: 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.
Iniciado por pkj ![]() 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. ¿Con SendMessage si oculto el textbox del receptor también funciona? |
| ||||
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. |
| |||
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 |
| |||
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:
y dentro del formulario (Que para este ejemplo se llama Form1)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
Código:
en la aplicacion que envia los mensagesOption Explicit Const PersonalKey = "MyKeyWindow" Private Sub Form_Load() StartListen PersonalKey End Sub Private Sub Form_Unload(Cancel As Integer) StopListen End Sub 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 |
| |||
Respuesta: Problema al arrastrar un formulario Cita: Gracias, voy a mirármelo con más calma. ¿Lo de COPY_DATA que es exactamente?
Iniciado por LeandroA ![]() 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:
y dentro del formulario (Que para este ejemplo se llama Form1)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
Código:
en la aplicacion que envia los mensagesOption Explicit Const PersonalKey = "MyKeyWindow" Private Sub Form_Load() StartListen PersonalKey End Sub Private Sub Form_Unload(Cancel As Integer) StopListen End Sub 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 |
| |||
Respuesta: Problema al arrastrar un formulario Cita: 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 |
| |||
Respuesta: Problema al arrastrar un formulario Cita: ok
Iniciado por leandroa ![]() 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. ![]() |
| |||
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. ![]() |