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

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

 


Código para VB .NET

 

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

 


Código para C#

//-----------------------------------------------------------------------------
// 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: 8F02C5D9F5AE88793881BFD1F711F979

El proyecto para Visual C# .NET 2003: enumWindowsCS.zip - 12.90 KB

MD5 checksum: D4267587477446AEB1C2FDE77FBB84CA

 

Lee esto para saber de qué va lo del MD5 checksum.

 


ir arriba

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