Autor
|
Tema: [VB.NET] Pegar texto en otra ventana (Leído 5,002 veces)
|
EAX_
Desconectado
Mensajes: 26
inside myself..
|
Hola comunidad, He estado investigando sobre este tema en particular hace unos días y no he encontrado lo que necesito. Lo que quiero hacer es que mi programa envíe la instrucción de pegar (CTRL + V) en otra ventana al momento de que yo utilice un atajo de teclado. Estuve buscando eventos que podrían ayudarme y al final me encontré con una función que me permitió bindear una tecla y pude enviar por teclado lo que quería pegar. Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean If msg.WParam.ToInt32 = CInt(Keys.F1) Then MsgBox("Tecla F1 pulsada") End If Return MyBase.ProcessCmdKey(msg, keyData) End Function
Enviaba la cadena que quiero pegar con Sendkeys.Send() pero el problema es que si no tengo activa la ventana de mi aplicación la tecla no es procesada por el programa. Confío que alguien me podrá dar una ayudadita Gracias de antemano y saludos
|
|
|
En línea
|
"Everyone is a genius. But if you judge a fish on its ability to climb a tree, it will live its whole life believing it is stupid." - Albert Einstein
|
|
|
Keyen Night
Desconectado
Mensajes: 496
Nothing
|
El API SendMenssage, puede enviar pulsaciones de teclas a un handle correspondiente a una ventana especifica, usando los parámetros WM_KEYUP, WM_KEYCHAR y WM_KEYDOWN. Una vez realice una clase para ese propósito está en C# pero es fácilmente traducible a Vb.Net. public sealed class Input { public enum WindowMessage : int { WM_KEYDOWN = 0x0100, WM_KEYUP = 0x0101, WM_CHAR = 0x0102, WM_LBUTTONDOWN = 0x201, WM_LBUTTONUP = 0x202 } public static void SendKey(IntPtr WindowhWnd, Int32 key) { SendMessage(WindowhWnd, WindowMessage.WM_KEYDOWN, (int)key, 0); SendMessage(WindowhWnd, WindowMessage.WM_CHAR, (int)key, 0); SendMessage(WindowhWnd, WindowMessage.WM_KEYUP, (int)key, 0); } public static void SendClick(IntPtr WindowhWnd, int X, int Y) { SendMessage(WindowhWnd, WindowMessage.WM_LBUTTONUP, 0, 0); int lpara = MakeLParam(X, Y); SendMessage(WindowhWnd, WindowMessage.WM_LBUTTONDOWN, 0, lpara); SendMessage(WindowhWnd, .WindowMessage.WM_LBUTTONUP, 0, lpara); Thread.Sleep(25); } public static void SendString(IntPtr WindowhWnd, string String) { foreach (var x in String) SendKey(WindowhWnd, Convert.ToInt32(x)); Thread.Sleep(3); } private static int MakeLParam(int LoWord, int HiWord) { return ((HiWord << 16) | (LoWord & 0xffff)); } }
|
|
« Última modificación: 5 Octubre 2012, 01:39 am por Keyen Night »
|
En línea
|
La Fé Mueve Montañas... ...De Dinero
La programación es más que un trabajo es más que un hobby es una pasión...
|
|
|
EAX_
Desconectado
Mensajes: 26
inside myself..
|
Hola, gracias por responder. Tengo una duda. Con esa clase que me das se supone que envías mensajes a una ventana en especifico cierto?
Sabes si hay una forma de que (mientras la ventana no esté activa) siga monitoreando mis teclas y pueda activar un evento?
Me gustaría aprovechar el evento OnKeyPress del formulario para lograr enviar algun texto a nivel PC asi como un CTRL + V mientras mi formulario no está activo.
Con respecto a la clase, estuve tratando de entenderla y no lo logré.
Saludos
|
|
« Última modificación: 5 Octubre 2012, 00:59 am por EAX_ »
|
En línea
|
"Everyone is a genius. But if you judge a fish on its ability to climb a tree, it will live its whole life believing it is stupid." - Albert Einstein
|
|
|
Keyen Night
Desconectado
Mensajes: 496
Nothing
|
Windows comunica muchas cosas a las aplicaciones a través de mensajes, y estos se envían por medio del API SendMessage, esta API es extremadamente dinámica, quiero decir que posee múltiples funcionalidades, para definir que tipo de tarea queremos que SendMessage efectué, existe una lista gigantesca de constantes WM_XXX, que describen situaciones, para este caso tenemos WM_KEYDOWN, WM_KEYUP, WM_CHAR, enviar tecla que se presiona, enviar tecla que se suelta y el Char que se imprime, respectivamente. Una vez definida la constate WM a pasar a SendMessage, entonces enviamos los parámetros para el trabajo que esta a punto de efectuar la función, en el caso de enviar una tecla construí la función SendKey: public static void SendKey(IntPtr WindowhWnd, Int32 key) { SendMessage(WindowhWnd, WindowMessage.WM_KEYDOWN, (int)key, 0); SendMessage(WindowhWnd, WindowMessage.WM_CHAR, (int)key, 0); SendMessage(WindowhWnd, WindowMessage.WM_KEYUP, (int)key, 0); }
El primer parámetro es el Handle (hWnd) de la ventana al cuál se va a enviar el mensaje, el siguiente parámetro es la constante WM, el tercer parámetro es el valor ASCII de la tecla a enviar, el último se omite para este trabajo. SendMenssage, imita en la ventana lo que el usuario hace para presionar una tecla, primero la pulsa (WM_KEYDOWN) luego se imprime (WM_CHAR) y la suelta (WM_KEYUP). Para capturar las teclas que se presionan fuera de tu aplicación tienes las dos opciones más usadas: el API GetAsynKeyState y el Hook de Teclado, que es mucho más limpio y organizado el trabajo. Acerca de esto hay mucha documentación tanto en el foro como en internet en general
|
|
« Última modificación: 5 Octubre 2012, 01:51 am por Keyen Night »
|
En línea
|
La Fé Mueve Montañas... ...De Dinero
La programación es más que un trabajo es más que un hobby es una pasión...
|
|
|
EAX_
Desconectado
Mensajes: 26
inside myself..
|
Agradezco tu respuesta, gracias a eso pude llegar a algo más acercado a mi realidad. Encontré algo interesante que es la función RegisterHotKey, con eso logré definir un atajo de teclado que fuera de la aplicación aun es posible ejecutarlo y, con eso, puedo hacer alguna acción (como enviar el texto que necesito) Ahora el único problema es que me gustaría que el HotKey fuese una sola tecla. Si alguien sabe por favor responder. Saludos Imports System.Runtime.InteropServices Public Class Form1 Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) If m.Msg = WM_HOTKEY Then Dim id As IntPtr = m.WParam Select Case (id.ToString) Case "100" SendKeys.Send("KEYS TO SEND") End Select End If MyBase.WndProc(m) End Sub Public Const WM_HOTKEY As Integer = &H312 <DllImport("User32.dll")> _ Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr, _ ByVal id As Integer, ByVal fsModifiers As Integer, _ ByVal vk As Integer) As Integer End Function <DllImport("User32.dll")> _ Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, _ ByVal id As Integer) As Integer End Function Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing UnregisterHotKey(Me.Handle, 100) End Sub Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load RegisterHotKey(Me.Handle, 100, MOD_ALT, Keys.G) End Sub End Class
|
|
|
En línea
|
"Everyone is a genius. But if you judge a fish on its ability to climb a tree, it will live its whole life believing it is stupid." - Albert Einstein
|
|
|
|
|