domingo, 4 de octubre de 2009

Obteniendo Handle de una ventana mediante API´s - Windows

Se puede obtener el handle de una ventana mediante su título o nombre de clase a la que pertenece llamando a la función FindWindow contenida en la librería user32.dll.Para poder acceder a la función es necesario agregar la directiva:
using System.Runtime.InteropServices;

Declarar la función aplicando el atributo DllImport(definido en System.Runtime.InteropServices).Ademas, notar el modificador extern:

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowTitle);


Ahora podemos llamarla.Por ejemplo, abrimos el Bloc de notas, nos fijamos en el título de la ventana:
Sin título - Bloc de notas
(Depende en qué idioma esté el S.O)

Para obtener el handle de esta ventana llamamos a la función FindWindow ya declarada mandando como parámetro el titulo del Bloc de notas y al otro parámetro le enviamos un valor null:
IntPtr hWndNotepad = FindWindow(null,"Sin título - Bloc de notas");

Notar que el handle se recibe en un tipo IntPtr.Además, si la función falla retorna un valor Null.

Para comprobar que, efectivamente, hemos obtenido el handle de la ventana requerida haremos una prueba:Cambiar el titulo de la ventana.
Para cambiar el título de una ventana haré uso de la función SetWindowText contenida en la librería user32.dll.Así que la declaro como hice con FindWindow :
[DllImport("user32.dll")]
public static extern bool SetWindowText(IntPtr hWnd, string newTitle);


Ahora ya puedo cambiar el titulo del Bloc de notas, mando como parametro el handle de la ventana y un string con el nuevo titulo:
bool v = SetWindowText(hWndNotepad, "¡¡¡¡¡¡ esto funciona !!!!!!");


Para obtener el handle de la ventana en la que se trabaja; es decir, la activa,es necesario llamar a la función GetForegroundWindow, también contenida en la librería user32.dll.Así que la declaramos como las demás:

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();


Llamamos a la función:

IntPtr hWndActual=GetForegroundWindow();


Al final el código quedaría:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//para llamar a apis:
using System.Runtime.InteropServices;

namespace APIsExamples
{
class Program
{
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowTitle);
[DllImport("user32.dll")]
public static extern bool SetWindowText(IntPtr hWnd, string newTitle);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

static void Main(string[] args)
{
IntPtr hWndNotepad = FindWindow(null, "Sin título - Bloc de notas");
IntPtr hWndActual = GetForegroundWindow();
Console.WriteLine("El handle del Bloc de notas es {0}", hWndNotepad);
Console.WriteLine("El handle de la ventana activa es {0}", hWndActual);
Console.WriteLine("\nCambiando el titulo de ventana del Bloc de notas...");
bool v = SetWindowText(hWndNotepad, "¡¡¡¡¡¡ esto funciona !!!!!!");
Console.WriteLine("\nListo.La opreación ha devuelto un valor {0}",v);

Console.ReadKey();

}
}
}



Se puede recuperar los handle´s de las ventanas abiertas mediante la función GetWindow, aunque es mas eficiente hacerlo mediante la función EnumWindows.Esto se verá en otro post.

No hay comentarios:

Publicar un comentario