bueno tengo un problema usando FindWindow, ya que al parecer estoy cometiendo algun error que se me pasa por alto.
despues de leer un poco y escribir varias veces el codigo no logro enviar un mensaje a la consola (DOS windows), desde mi programa.
alguien me puede dar una mano por favor?
Puedes replantear tu pregunta por favor? No entiendo qué tiene que ver FindWindow con la consola? O también postea esa parte del código a ver si vemos el error.
Un saludo!
estuve leyendo sobre como enviar un texto a una aplicacion externa a la mia, y encontre que se hace con FindWindow, FindWindowEx y SendMessage o PostMessage.
Tube la idea de enviar un mensaje a la consola de comandos de windows para ver si podia, pero al intentarlo no logre nada.
aca algunos de los codigos con los que intente (ya que no recuerdo todos):
Dim hWnd As Long, tmp As Long
'forma 1:
For Each P As Process In Process.GetProcesses
If P.ProcessName = "Símbolo del sistema" Then
hWnd = P.MainWindowHandle
End If
Next
SendMessage(hWnd, WM_SETTEXT, 0, "texto")
'forma 2:
For Each P As Process In Process.GetProcesses
If P.ProcessName = "Símbolo del sistema" Then
tmp = P.MainWindowHandle
End If
Next
hWnd = GetWindow(tmp, 5)
SendMessage(hWnd, WM_SETTEXT, 0, "texto")
'forma 3:
hWnd = FindWindow(vbNullString, "Símbolo del sistema")
SendMessage(hWnd, WM_SETTEXT, 0, "texto")
'forma 4:
tmp = FindWindow(vbNullString, "Símbolo del sistema")
hWnd = GetWindow(tmp, 5)
SendMessage(hWnd, WM_SETTEXT, 0, "texto")
nadie sabe como puedo hacer esto?
Hay una forma más fácil, no se si te funcione, es algo así:
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lp1, string lp2);
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
private void Test()
{
//Una prueba con el notepad
IntPtr handle = FindWindow("Notepad", "Untitled - Notepad");
if (!handle.Equals(IntPtr.Zero))
{
if (SetForegroundWindow(handle))
{
SendKeys.Send("Hello World!");
SendKeys.Send("{ENTER}");
}
}
}
Lo que hace es activar a esa ventana, y enviar texto como si fuese del teclado. Si no, la forma en que tu lo planteas es algo así:
private const int WM_SETTEXT = 0x000C;
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindows);
[DllImport("User32.dll")]
private static extern Int32 SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, StringBuilder lParam);
private void Test()
{
IntPtr hWnd = FindWindow("Notepad", "Untitled - Notepad");
if (!hWnd.Equals(IntPtr.Zero))
{
IntPtr edithWnd = FindWindowEx(hWnd, IntPtr.Zero, "Edit", null);
if (!edithWnd.Equals(IntPtr.Zero))
SendMessage(edithWnd, WM_SETTEXT, IntPtr.Zero, new StringBuilder("Hello World!"));
}
}
mira perdon que no sea tan bueno, pero no logro que el codigo funcione. lo pase a vb.net asi y no anda:
Public Sub test()
Dim hWnd As Long
hWnd = FindWindow("Notepad", "Untitled - Notepad")
If hWnd.Equals(IntPtr.Zero) <> 0 Then
Dim edithWnd As Long = FindWindowEx(hWnd, IntPtr.Zero, "Edit", vbNull)
If edithWnd.Equals(IntPtr.Zero) <> 0 Then SendMessage(edithWnd, WM_SETTEXT, IntPtr.Zero, "Hello World!")
End If
End Sub
Te da algún mensaje de error o algo?
puse un try aver si podia tener mas info, pero no.
simplemente no envia el mensaje, compila perfecto :S
Con cualquier aplicación funciona bien, pero con la consola no, al parecer Windows no deja hacer eso. Tiene los mensajes Protegidos, aún no le he encontrado solución :(
de ultima si no agregame al msn asi podriamos hablar mejor. mi idea era enviar un texto X a la consola, no importaba la forma, pero no logro hayar la solucion.
mi msn es the_chaoz92@hotmail.com
Hola, proba esto:
Public Class Form1
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Const WM_CHAR = &H102
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim vHwnd As Integer
Dim vTexto As String = "Holaaaaaaaaaaaaaaaa como va?"
vHwnd = FindWindow("ConsoleWindowClass", vbNullString)
For i As Integer = 1 To Len(vTexto)
PostMessage(vHwnd, WM_CHAR, Asc(Mid(vTexto, i, 1)), 0&)
Next i
PostMessage(vHwnd, WM_CHAR, Asc(vbCr), 0&)
PostMessage(vHwnd, WM_CHAR, Asc(vbLf), 0&)
End Sub
End Class
saludos.
no anda seba, a pesar de que cambie el "Dim vHwnd As Integer" por "As Long" me sigue diciendo que se proboca un desbordamiento en:
"PostMessage(vHwnd, WM_CHAR, Asc(Mid(vTexto, i, 1)), 0&)"
y no termino de entender porque.
alguien tiene otra idea?
Si estás en Vb.Net las declaraciones de las api's son diferentes, prueba así, ya a mi me funciono, deberia servir ._.
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("user32.dll", EntryPoint:="FindWindow", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindowByClass( _
ByVal lpClassName As String, _
ByVal zero As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As String, ByVal lParam As String) As IntPtr
End Function
Private WM_SETTEXT As Long = &HC
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim ConsoleHandle As IntPtr = FindWindowByClass("ConsoleWindowClass", IntPtr.Zero)
If ConsoleHandle <> IntPtr.Zero Then
SendMessage(ConsoleHandle, WM_SETTEXT, 0, "Hello")
End If
End Sub
End Class
Sï, probé el code de seba123neo y funciona bien, lo que hace es emular el teclado, yo lo que intentaba era mandarle el texto completo. xD
Buena idea seba!
Saludos!
Cita de: CH4ØZ en 8 Agosto 2010, 11:59 AM
no anda seba, a pesar de que cambie el "Dim vHwnd As Integer" por "As Long" me sigue diciendo que se proboca un desbordamiento en:
"PostMessage(vHwnd, WM_CHAR, Asc(Mid(vTexto, i, 1)), 0&)"
y no termino de entender porque.
alguien tiene otra idea?
mira a mi me funciona bien, no cambies las declaraciones ni nada porque asi como estan , estan bien, As Long ya no es necesario ahora lo que antes era Long en visual basic 6 se pones As Integer ya que cambiaron los tipos de datos, lo mismo para las api's...por curiosidad que windows tenes?
saludos.
XP 9.5, lo probe en una aplicacion de 0 y funciona perfecto, asi que voy a ver que puedo tener mal en la otra. gracias seba.
solo me quedo una duda, cual es la diferencia entre SendMessage y PostMessage
Usando SendMessage se espera hasta que la ventana a donde enviaste el mensaje lo procese. En cambio PostMessage no espera a que procesen el mensaje.
Saludos.
serian iguales, solo que cuando envias un mensaje con Sendmessage este no retorna el valor hasta que la ventana procesa el mensaje y entonces ahi te devuelve el resultado, en cambio PostMesaage envia el mensaje dejandolo en la cola de mensajes y no espera por la respuesta del mensaje lo retorna inmediatamente.
lo podes ver todo en la MSDN:
SendMessage Function (http://msdn.microsoft.com/en-us/library/ms644950)
PostMessage Function (http://msdn.microsoft.com/en-us/library/ms644944)
saludos.
muchas gracias a todos por su ayuda. pueden cerrar el topic si quieren.