Enumerando Ventanas
Buscar una ventana en ejecución y lista de todas las ventanas

 

Fecha: 23/May/987
Autor: Nacho Cassou
Ignacio.Cassou@wl.com


Hola Guille,

Aquí te mando una colaboración sencilla pero que puede ser muy útil.

- Obtener la lista de todas las ventanas activas en Windows (y de paso, comprobar si existe alguna en concreto)
Es para 32 bits y sólo para VB5 debido a que hay que utilizar el operador 'AddressOf', que no está disponible en versiones anteriores.
No la he probado en Windows NT pero seguro que funciona.

La verdad es que el trabajo lo hace todo una función del API (EnumWindows). Lo que hace esta función es enumerar todas las ventanas existentes en Windows (visibles o no) y, por cada una que encuentra, llamar a la función 'Callback' que le hayamos dicho.

¿Cómo le decimos cuál es la función que queremos que se ejecute?. Muy sencillo, utilizando el operador 'AddressOf', que lo que hace es, ni más ni menos que pasarle a EnumWindows la dirección en memoria (puntero) a nuestra función.

Así pues, tenemos que por cada ventana que encuentre, invocará una función de nuestro programa (que debe estar en un módulo 'bas' y ser pública) y pasarle dos parámetros, uno el hWnd (handler) de la ventana encontrada así como un parámetro que nosotros le hayamos pasado a EnumWindows (aunque yo no lo estoy usando en este caso).

Dentro de nuestra función, tan sólo nos queda llamar a otra función del API llamada 'GetWindowText' usando el hWnd que hemos recibido y ya tenemos el título de la ventanita de marras, con lo cual, si queremos comprobar si una determinada ventana existe, lo único que hay que hacer es comparar dos strings (ojo porque el título obtenido viene relleno de 'nulls')
Así pues, en cuanto detectamos que la ventana que nos interesa existe,
le damos como valor de retorno a nuestra función 'False' y así EnumWindows deja de rastrear.

Nos vemos,

Nacho.

Nota: He modificado un poco el código y he añadido la opción de "mostrar" todas las ventanas disponibles, si has visto el código que puse en la utilidad ListVentanas, verás que usando la subclasificación (gracias a AddressOf) es mucho más simple.

Aquí tienes una "foto" del form de prueba y el código usado:

 

'
'Módulo EnumWMod.bas
'
'Original de Nacho Cassou,
'modificado por Guillermo 'guille' Som                  (24/May/98)
'
Option Explicit


'Declare Function EnumWindows Lib "user32" _
        (ByVal lpfn As Long, ByVal lParam As Long) As Boolean

'Si se quiere usar lParam como parámetro de retorno
Declare Function EnumWindows Lib "user32" _
        (ByVal lpfn As Long, lParam As Any) As Boolean

Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
        (ByVal hWnd As Long, ByVal lpString As String, _
        ByVal cch As Long) As Long

Public TituloABuscar As String
Public SWEncontrado As Boolean

Public Function FuncRetNombres(ByVal hWnd As Long, Parametro As Long) As Boolean
    Dim Titulo As String * 256
    Dim Ret As Long
    Dim NombreVentana As String
    
    DoEvents
    
    Ret = GetWindowText(ByVal hWnd, ByVal Titulo, ByVal Len(Titulo))
    NombreVentana = Left$(Titulo, Ret)
    If Len(NombreVentana) Then
        Form1.List1.AddItem NombreVentana
    End If
    
    FuncRetNombres = True
End Function

Public Function FuncionRetorno(ByVal hWnd As Long, Parametro As Long) As Boolean
    Dim Titulo As String * 256
    Dim Ret As Long
    
    Parametro = Parametro + 1
    DoEvents
    
    Ret = GetWindowText(ByVal hWnd, ByVal Titulo, ByVal Len(Titulo))
    If Left$(Titulo, Len(TituloABuscar)) = TituloABuscar Then
        SWEncontrado = True
        FuncionRetorno = False
    Else
        FuncionRetorno = True
    End If

End Function
'Form EnumWForm.frm
'
'Original de Nacho Cassou,
'modificado por Guillermo 'guille' Som                  (24/May/98)
'
Option Explicit

Private Sub Command1_Click()
    Dim bRet As Boolean
    Dim Parametro As Long
    
    TituloABuscar = Text1
    SWEncontrado = False
    
    bRet = EnumWindows(AddressOf FuncionRetorno, Parametro)
    
    If SWEncontrado Then
        MsgBox "Encontrado, se ha buscado en " & Parametro & " ventanas"
    Else
        MsgBox "No encontrado, se ha buscado en " & Parametro & " ventanas"
    End If
End Sub

Private Sub Command2_Click()
    Dim bRet As Boolean
    
    List1.Clear
    bRet = EnumWindows(AddressOf FuncRetNombres, ByVal 0&)
    
End Sub

Private Sub Form_Load()
    Text1 = "Autoexec.bat - WordPad"
    
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set Form1 = Nothing
End Sub

Pulsa este link para bajarte los listados de ejemplo (EnumWnd_nc.zip 2.20 KB)


ir al índice