Índice de la sección dedicada a .NET (en el Guille) - Migrar de VB6 a .NET

Capturar el texto (y el handle) de la ventana activa

Usando API de Windows



 

Equivalencia con el API de Windows

 

Publicado el 28/Feb/2005
Actualizado 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)

 


Código para VB .NET

 

'------------------------------------------------------------------------------
' 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

 


Código para C#

 

//-----------------------------------------------------------------------------
// 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();
   }  
}

 


ir arriba

la Luna del Guille o... el Guille que está en la Luna... tanto monta...