Equivalencia con el API de Windows
Publicado el 28/Feb/2005
|
En este ejemplo tenemos un formulario con un ListView, una etiqueta, un botón y un Timer.
Al pulsar en el botón se iniciará la captura de los textos de las ventanas activas y se añadirán al ListView, indicando el texto de la ventana activa, la hora en que se ha capturado y el handle de dicha ventana, (no se comprueba si el texto ya está o es el mismo handle, pero eso no tiene demasiada complicación... sobre todo si en lugar de usar un ListView usas una colección de tipo Hashtable).
Si haces doble-click en la etiqueta te muestra el texto de la ventana activa de la aplicación... no es algo para tirar cohetes ya que siempre se mostrará el de la ventana principal (que es la que está activa), pero es para que veas cómo funciona GetActiveWindow, que sería el equivalente a ActiveForm de VB6.Aquí tienes una captura del programa en ejecución (después de haber capturado unas cuantas ventanas):
Captura de la aplicación de ejemplo en plena ejecución
Aquí tienes el ZIP con el código fuente para VB .NET y C#: capturarTextoVentanaActiva.zip 21 KB
Espero que te sea de utilidad... y úsala de forma "no maliciosa" ;-)
Nos vemos.
Guillermo
Nerja, 28 de Febrero de 2005 (día de Andalucía)
'------------------------------------------------------------------------------ ' Capturar el texto de las ventanas activas (28/Feb/05) ' ' ©Guillermo 'guille' Som, 2005 '------------------------------------------------------------------------------ Option Strict On Option Explicit On Imports System Imports Microsoft.VisualBasic Imports System.Windows.Forms Imports System.Drawing Imports System.Runtime.InteropServices Public Class Form1 Inherits System.Windows.Forms.Form ' Private mTotal As Integer ' #Region " Declaraciones del API de Win32 " ' <System.Runtime.InteropServices.DllImport("user32.dll")> _ Private Shared Function GetWindowText( _ ByVal hWnd As System.IntPtr, _ ByVal lpString As System.Text.StringBuilder, _ ByVal cch As Integer) As Integer End Function ' <System.Runtime.InteropServices.DllImport("user32.dll")> _ Private Shared Function GetActiveWindow() As System.IntPtr End Function ' <System.Runtime.InteropServices.DllImport("user32.dll")> _ Private Shared Function GetForegroundWindow() As System.IntPtr End Function ' #End Region ' #Region " Código generado por el Diseñador de Windows Forms " #End Region ' Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load With Me.lvVentanasActivas .View = View.Details .FullRowSelect = True .GridLines = True .MultiSelect = True .LabelEdit = False .HideSelection = False ' .Columns.Clear() .Columns.Add("Titulo", 320, HorizontalAlignment.Left) .Columns.Add("Fecha", 70, HorizontalAlignment.Right) .Columns.Add("Handle", 60, HorizontalAlignment.Right) ' .Items.Clear() End With Timer1.Interval = 20 * 1000 Timer1.Enabled = False Me.Tag = Me.Text ' End Sub Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick ' revisar cada 20 segundos la ventana que está activa Dim titulo As New System.Text.StringBuilder(New String(" "c, 256)) Dim ret As Integer Dim nombreVentana As String ' The GetForegroundWindow function returns a handle to the foreground window ' (the window with which the user is currently working). ' The system assigns a slightly higher priority to the thread that creates ' the foreground window than it does to other threads. Dim hWnd As IntPtr = GetForegroundWindow() ' If hWnd.Equals(IntPtr.Zero) Then Return ' ret = GetWindowText(hWnd, titulo, titulo.Length) If ret = 0 Then Return ' nombreVentana = titulo.ToString.Substring(0, ret) If nombreVentana <> Nothing AndAlso nombreVentana.Length > 0 Then ' añadirla al listview Dim it As ListViewItem = Me.lvVentanasActivas.Items.Add(nombreVentana) it.SubItems.Add(DateTime.Now.ToString("HH:mm:ss")) it.SubItems.Add(hWnd.ToString) ' ' incrementar el número de ventanas capturadas mTotal += 1 Me.Text = mTotal.ToString & " - " & nombreVentana LabelInfo.Text = Me.Text ' "Total ventanas capturadas en esta sesión: " & mTotal.ToString End If ' End Sub Private Sub btnIniciar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIniciar.Click ' iniciar la "captura" de la ventana activa If btnIniciar.Text = "Iniciar" Then mTotal = 0 Me.lvVentanasActivas.Items.Clear() btnIniciar.Text = "Detener" Me.WindowState = FormWindowState.Minimized Timer1.Enabled = True Else btnIniciar.Text = "Iniciar" Timer1.Enabled = False Me.Text = Me.Tag.ToString LabelInfo.Text = "Total ventanas capturadas en esta sesión: " & mTotal.ToString End If End Sub ' Private Function activeFormText() As String Dim titulo As New System.Text.StringBuilder(New String(" "c, 256)) Dim ret As Integer Dim nombreVentana As String ' GetActiveWindows devuelve el handle de la ventana activa ' pero si está en el mismo hilo que la nuestra, ' sería el equivalente (más o menos) a ActiveForm de VB6 Dim hWnd As IntPtr = GetActiveWindow() ' If hWnd.Equals(IntPtr.Zero) Then Return "" ' ret = GetWindowText(hWnd, titulo, titulo.Length) If ret = 0 Then Return "" ' nombreVentana = titulo.ToString.Substring(0, ret) If nombreVentana <> Nothing AndAlso nombreVentana.Length > 0 Then ' añadirla al listview Dim it As ListViewItem = Me.lvVentanasActivas.Items.Add(nombreVentana) it.SubItems.Add(DateTime.Now.ToString("HH:mm:ss")) it.SubItems.Add(hWnd.ToString) End If ' Return nombreVentana End Function ' Private Sub LabelInfo_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles LabelInfo.DoubleClick ' para probar GetActiveWindow LabelInfo.Text = activeFormText() End Sub End Class
//----------------------------------------------------------------------------- // Capturar el texto de las ventanas activas (28/Feb/05) // // ©Guillermo 'guille' Som, 2005 //----------------------------------------------------------------------------- using System; using System.Windows.Forms; using System.Drawing; using System.Runtime.InteropServices; public class Form1:System.Windows.Forms.Form { // private int mTotal; // #region Declaraciones del API de Win32 // [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static int GetWindowText(System.IntPtr hWnd, System.Text.StringBuilder lpString, int cch); // [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static System.IntPtr GetActiveWindow(); // [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static System.IntPtr GetForegroundWindow(); // #endregion // #region Código generado por el Diseñador de Windows Forms #endregion // public Form1() : base() { //El Diseñador de Windows Forms requiere esta llamada. InitializeComponent(); //Agregar cualquier inicialización después de la llamada a InitializeComponent() base.Load += new System.EventHandler(Form1_Load); btnIniciar.Click += new System.EventHandler(btnIniciar_Click); LabelInfo.DoubleClick += new System.EventHandler(LabelInfo_DoubleClick); timer1.Tick += new System.EventHandler(timer1_Tick); } // /// <summary> /// Punto de entrada principal de la aplicación. /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } // private void Form1_Load(System.Object sender, System.EventArgs e) { this.lvVentanasActivas.View = View.Details; this.lvVentanasActivas.FullRowSelect = true; this.lvVentanasActivas.GridLines = true; this.lvVentanasActivas.MultiSelect = true; this.lvVentanasActivas.LabelEdit = false; this.lvVentanasActivas.HideSelection = false; // this.lvVentanasActivas.Columns.Clear(); this.lvVentanasActivas.Columns.Add("Titulo", 320, HorizontalAlignment.Left); this.lvVentanasActivas.Columns.Add("Fecha", 70, HorizontalAlignment.Right); this.lvVentanasActivas.Columns.Add("Handle", 60, HorizontalAlignment.Right); // this.lvVentanasActivas.Items.Clear(); timer1.Interval = 20 * 1000; timer1.Enabled = false; this.Tag = this.Text; // } // private void timer1_Tick(object sender, System.EventArgs e) { // revisar cada 20 segundos la ventana que está activa System.Text.StringBuilder titulo = new System.Text.StringBuilder(new string(' ', 256)); int ret; string nombreVentana; // The GetForegroundWindow function returns a handle to the foreground window // (the window with which the user is currently working). // The system assigns a slightly higher priority to the thread that creates // the foreground window than it does to other threads. IntPtr hWnd = GetForegroundWindow(); // if( hWnd.Equals(IntPtr.Zero) ) return; // ret = GetWindowText(hWnd, titulo, titulo.Length); if( ret == 0 ) return; // nombreVentana = titulo.ToString().Substring(0, ret); if( nombreVentana != null && nombreVentana.Length > 0 ) { // añadirla al listview ListViewItem it = this.lvVentanasActivas.Items.Add(nombreVentana); it.SubItems.Add(DateTime.Now.ToString("HH:mm:ss")); it.SubItems.Add(hWnd.ToString()); // // incrementar el número de ventanas capturadas mTotal += 1; this.Text = mTotal.ToString() + " - " + nombreVentana; LabelInfo.Text = this.Text; } } // private void btnIniciar_Click(System.Object sender, System.EventArgs e) { // iniciar la "captura" de la ventana activa if( btnIniciar.Text == "Iniciar" ) { mTotal = 0; this.lvVentanasActivas.Items.Clear(); btnIniciar.Text = "Detener"; this.WindowState = FormWindowState.Minimized; timer1.Enabled = true; } else { btnIniciar.Text = "Iniciar"; timer1.Enabled = false; this.Text = this.Tag.ToString(); LabelInfo.Text = "Total ventanas capturadas en esta sesión: " + mTotal.ToString(); } } // private string activeFormText() { System.Text.StringBuilder titulo = new System.Text.StringBuilder(new string(' ', 256)); int ret; string nombreVentana; // GetActiveWindows devuelve el handle de la ventana activa // pero si está en el mismo hilo que la nuestra, // sería el equivalente (más o menos) a ActiveForm de VB6 IntPtr hWnd = GetActiveWindow(); // if( hWnd.Equals(IntPtr.Zero) ) return ""; // ret = GetWindowText(hWnd, titulo, titulo.Length); if( ret == 0 ) return ""; // nombreVentana = titulo.ToString().Substring(0, ret); if( nombreVentana != null && nombreVentana.Length > 0 ) { // añadirla al listview ListViewItem it = this.lvVentanasActivas.Items.Add(nombreVentana); it.SubItems.Add(DateTime.Now.ToString("HH:mm:ss")); it.SubItems.Add(hWnd.ToString()); } return nombreVentana; } // private void LabelInfo_DoubleClick(object sender, System.EventArgs e) { // para probar GetActiveWindow LabelInfo.Text = activeFormText(); } }