Equivalencia con el API de Windows
Ejemplo de EnumWindows y EnumChildWindows, GetWindowText y los delegados EnumWindowsProc y EnumChildProc |
Publicado el 10/Ene/2005
Actualizado el 07/Oct/2007
07/Oct/2007: He puesto los proyectos con el código de ejemplo en ZIP.
Aquí tienes un ejemplo en el que se usan las funciones del API EnumWindows, EnumChildWindows y los delegados usados por estas dos funciones, además de GetWindowText.
Esta aplicación utiliza este formulario con dos listViews (lvTop y lvChild) y dos botones (btnTop y btnChild).
Para enumerar las ventanas principales (todas), pulsa en el botón de la izquierda (Mostrar ventanas Top) y una vez mostrado en el listView superior las ventanas principales, selecciona una de ellas y pulsa en el botón de la derecha (Mostrar ventans hijas) para mostrar todas las ventanas "hijas".
El formulario en tiempo de diseño
'------------------------------------------------------------------------------ ' formulario de prueba para enumerar ventanas (10/Ene/05) ' ' ©Guillermo 'guille' Som, 2005 '------------------------------------------------------------------------------ Imports System Imports System.Windows.Forms Public Class fEnumWindows Inherits System.Windows.Forms.Form ' #Region " Código generado por el Diseñador de Windows Forms " '... código de diseño del formualrio ... #End Region ' ' Private Delegate Function EnumWindowsDelegate _ (ByVal hWnd As System.IntPtr, ByVal parametro As Integer) As Boolean ' <System.Runtime.InteropServices.DllImport("user32.dll")> _ Private Shared Function EnumWindows( _ ByVal lpfn As EnumWindowsDelegate, _ ByVal lParam As Integer) As Boolean End Function ' <System.Runtime.InteropServices.DllImport("user32.dll")> _ Private Shared Function EnumChildWindows _ (ByVal hWndParent As System.IntPtr, _ ByVal lpEnumFunc As EnumWindowsDelegate, _ ByVal lParam As Integer) As Integer End Function ' ' <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 ' ' Private Sub fEnumWindows_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.btnChild.Enabled = False End Sub ' Private Sub btnTop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTop.Click ' mostrar las ventanas Top btnChild.Enabled = False EnumerarVentanas() End Sub ' Private Sub btnChild_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnChild.Click ' mostrar las ventanas hijas de la seleccionada Dim s As String = lvTop.SelectedItems(0).Text Dim hParent As System.IntPtr = System.IntPtr.op_Explicit(CInt(s)) Me.enumerarVentanasHijas(hParent) End Sub ' ' ' Para EnumWindows Private colWin As New System.Collections.Specialized.StringDictionary ' Private Function EnumWindowsProc(ByVal hWnd As System.IntPtr, ByVal parametro As Integer) As Boolean ' Esta función "callback" se usará con EnumWindows y EnumChildWindows Dim titulo As New System.Text.StringBuilder(New String(" "c, 256)) Dim ret As Integer Dim nombreVentana As String ' ret = GetWindowText(hWnd, titulo, titulo.Length) If ret = 0 Then Return True ' nombreVentana = titulo.ToString.Substring(0, ret) If nombreVentana <> Nothing AndAlso nombreVentana.Length > 0 Then colWin.Add(hWnd.ToString, nombreVentana) End If ' Return True End Function ' Private Sub EnumerarVentanas() ' Enumera las ventanas principales (TopWindows) colWin.Clear() EnumWindows(AddressOf EnumWindowsProc, 0) ' lvTop.Items.Clear() For Each s As String In colWin.Keys Dim lvi As ListViewItem = lvTop.Items.Add(s) lvi.SubItems.Add(colWin(s)) Next If lvTop.Items.Count > 0 Then btnChild.Enabled = True End If End Sub ' Private Sub enumerarVentanasHijas(ByVal handleParent As System.IntPtr) ' Enumera las ventanas hijas del handle indicado colWin.Clear() EnumChildWindows(handleParent, AddressOf EnumWindowsProc, 0) ' lvChild.Items.Clear() For Each s As String In colWin.Keys Dim lvi As ListViewItem = lvChild.Items.Add(s) lvi.SubItems.Add(colWin(s)) Next End Sub End Class
//----------------------------------------------------------------------------- // formulario de prueba para enumerar ventanas (10/Ene/05) // // ©Guillermo 'guille' Som, 2005 //----------------------------------------------------------------------------- using System; using System.Windows.Forms; /// <summary> /// Descripción breve de Form1. /// </summary> public class fEnumWindows : System.Windows.Forms.Form { internal System.Windows.Forms.Button btnTop; internal System.Windows.Forms.ListView lvChild; internal System.Windows.Forms.ColumnHeader ColumnHeader3; internal System.Windows.Forms.ColumnHeader ColumnHeader4; internal System.Windows.Forms.Button btnChild; internal System.Windows.Forms.ListView lvTop; internal System.Windows.Forms.ColumnHeader ColumnHeader1; internal System.Windows.Forms.ColumnHeader ColumnHeader2; /// <summary> /// Variable del diseñador requerida. /// </summary> private System.ComponentModel.Container components = null; public fEnumWindows() { // // Necesario para admitir el Diseñador de Windows Forms // InitializeComponent(); // // TODO: agregar código de constructor después de llamar a InitializeComponent // // Los eventos de la aplicación this.btnTop.Click += new System.EventHandler(this.btnTop_Click); this.btnChild.Click += new System.EventHandler(this.btnChild_Click); this.Load += new System.EventHandler(this.fEnumWindows_Load); } /// <summary> /// Limpiar los recursos que se estén utilizando. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Código generado por el Diseñador de Windows Forms // ... código del diseñador de Windows ... #endregion /// <summary> /// Punto de entrada principal de la aplicación. /// </summary> [STAThread] static void Main() { Application.Run(new fEnumWindows()); } // // // private delegate bool EnumWindowsDelegate (System.IntPtr hWnd, int parametro); // [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static bool EnumWindows(EnumWindowsDelegate lpfn, int lParam); // [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static int EnumChildWindows (System.IntPtr hWndParent, EnumWindowsDelegate lpEnumFunc, int lParam); // // [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static int GetWindowText(System.IntPtr hWnd, System.Text.StringBuilder lpString, int cch); // private void fEnumWindows_Load(System.Object sender, System.EventArgs e) { this.btnChild.Enabled = false; } // private void btnTop_Click(System.Object sender, System.EventArgs e) { // mostrar las ventanas Top btnChild.Enabled = false; EnumerarVentanas(); } // private void btnChild_Click(System.Object sender, System.EventArgs e) { // mostrar las ventanas hijas de la seleccionada string s = lvTop.SelectedItems[0].Text; System.IntPtr hParent = (System.IntPtr)Convert.ToInt32(s); this.enumerarVentanasHijas(hParent); } // // // Para EnumWindows private System.Collections.Specialized.StringDictionary colWin = new System.Collections.Specialized.StringDictionary(); // private bool EnumWindowsProc(System.IntPtr hWnd, int parametro) { // Esta función "callback" se usará con EnumWindows y EnumChildWindows System.Text.StringBuilder titulo = new System.Text.StringBuilder(new string(' ', 256)); int ret; string nombreVentana; // ret = GetWindowText(hWnd, titulo, titulo.Length); if( ret == 0 ) return true; // nombreVentana = titulo.ToString().Substring(0, ret); if( nombreVentana != null && nombreVentana.Length > 0 ) { colWin.Add(hWnd.ToString(), nombreVentana); } // return true; } // private void EnumerarVentanas() { // Enumera las ventanas principales (TopWindows) colWin.Clear(); EnumWindows(new EnumWindowsDelegate(this.EnumWindowsProc), 0); // lvTop.Items.Clear(); foreach(string s in colWin.Keys) { ListViewItem lvi = lvTop.Items.Add(s); lvi.SubItems.Add(colWin[s]); } if( lvTop.Items.Count > 0 ) { btnChild.Enabled = true; } } // private void enumerarVentanasHijas(System.IntPtr handleParent) { // Enumera las ventanas hijas del handle indicado colWin.Clear(); EnumChildWindows(handleParent, new EnumWindowsDelegate(this.EnumWindowsProc), 0); // lvChild.Items.Clear(); foreach(string s in colWin.Keys) { ListViewItem lvi = lvChild.Items.Add(s); lvi.SubItems.Add(colWin[s]); } } }
El código comprimido
Aquí tienes los dos proyectos para Visual Studio 2003 (publicados el 07/Oct/07)
En el de Visual Basic, hay más cosas de las mostradas aquí, pero también está todo este código, lo que ocurre es que no puedo modificar el proyecto para dejarlo como estaba, pero como tienes el código fuente, puedes ver todo lo aquí explicado.
El código de C# es tal como se muestra en el artículo.
El proyecto para Visual Basic .NET 2003: equivalenciasAPI_VB.zip - 22.2 KB
MD5 checksum: 8F02C5D9F5AE88793881BFD1F711F979El proyecto para Visual C# .NET 2003: enumWindowsCS.zip - 12.90 KB
MD5 checksum: D4267587477446AEB1C2FDE77FBB84CA