''e ne comunica all'utente titolo e indirizzo di memoria (handle).
''
''Sorgente preso dal sito http://www.pierotofy.it/pages/members/profile.php?nickname=Totem e riadattato all'utilizzo di questo esempio
''Ringrazio l'autore Totem
''
''Il sorgente è stato riadattato per uso di esercizio.
Imports System.Runtime.InteropServices
Module Funzioni
Public ArrayListEvent As New List(Of String)
'Le funzioni che risiedono nelle librerie di sistema lavorano
'a basso livello, come già detto, perciò i tipi
'più frequentemente incontrati sono IntPtr (puntatore
'intero) e Int32 (intero a 32 bit). Nonostante ciò, esse
'possono anche richiedere tipi di dato molto più complessi,
'come in questo caso. La funzione che useremo necessita di
'un delegate come parametro.
Public Delegate Function EnumCallback(ByVal Handle As IntPtr, _
ByVal lParam As Int32) As Boolean
'La funzione EnumDesktopWindows è definita nella libreria
'C:WINDOWSsystemsystem32user32.dll. Dato che si tratta di una
'libreria di sistema, possiamo omettere il percorso e scrivere solo
'il nome (provvisto di estensione). Come vedete, il nome con cui
'è dichiarata è lo stesso dl metodo definito
'in user32.dll. Per importarla correttamente, però, anche
'i parametri usati devono essere identici, almeno per tipo.
'Infatti, per identificare univocamente un metodo che potrebbe
'essere provvisto di overloads, è necessario sapere solo
'il nome del metodo e la quantità e il tipo di parametri.
'Anche cambiando il nome a un parametro, la signature non
'cambia, quindi mi sono preso la libertà di scrivere
'dei parametri più "amichevoli", poiché la
'dichiarazione originale - come è tipico del C -
'prevede dei nomi assurdi e difficili da ricordare.
<DllImport("user32.dll")> _
Public Function EnumDesktopWindows(ByVal DesktopIndex As IntPtr, _
ByVal Callback As EnumCallback, ByVal lParam As Int32) As Boolean
'Notare che il corpo non viene definito
End Function
'Questa funzione ha il compito di ottenere il titolo di
'una finestra provvisto in input il suo indirizzo (handle).
'Notare che non restituisce una stringa, ma un Int32.
'Infatti, la maggiore parte dei metodi definiti nelle librerie
'di sistema sono funzioni che restituiscono interi, ma questi
'interi sono inutili. Anche se sono funzioni, quindi, le si
'può trattare come banali procedure. In questo caso,
'tuttavia, l'intero restituito ha uno scopo, ed equivale
'alla lunghezza del titolo della finestra.
'GetWindowText, dopo aver identificato la finestra,
'ne deposita il titolo nello StringBuilder, che, essendo
'un tipo reference, viene sempre passato per indirizzo.
'Capacity indica invece il massimo numero di caratteri
'accettabili.
<DllImport("user32.dll")> _
Public Function GetWindowText(ByVal Handle As IntPtr, _
ByVal Builder As System.Text.StringBuilder, ByVal Capacity As Int32) As Int32
End Function
Public Function GetWindowTitle(ByVal Handle As IntPtr)
'Crea un nuovo string builder, con una capacità
'di 255 caratteri
Dim Builder As New System.Text.StringBuilder(255)
'Richiama la funzione di sistema per ottenere il
'titolo della finestra
GetWindowText(Handle, Builder, Builder.Capacity)
'Dopo la chiamata a GetWindowText, Builder conterrà
'il titolo: lo restituisce alla funzione
Return Builder.ToString
End Function
Public Function FoundWindow(ByVal Handle As IntPtr, _
ByVal lParam As Int32) As Boolean
'Ottiene il titolo della finestra
Dim Title As String = GetWindowTitle(Handle)
'Scrive a schermo le informazioni sulla finestra
If Title <> "" Then
Debug.WriteLine("Handle " & Handle.ToInt32 & " - Titolo: " & Title)
ArrayListEvent.Add("Handle " & Handle.ToInt32 & " - Titolo: " & Title)
End If
'Restituisce sempre True: come già detto, i
'risultati delle funzioni di sistema non sono sempre
'utili, se non al sistema operativo stesso
Return True
End Function
'Enumera tutte le finestra
Public Sub EnumerateWindows()
'Inizializza il metodo callback
Dim Callback As New EnumCallback(AddressOf FoundWindow)
Dim Success As Boolean
'Richiama la funzione di sistema. IntPtr.Zero come primo
'parametro indica che il desktop da considerare è
'quello correntemente aperto. Il secondo parametro
'fornisce l'indirizzo del metodo callback, che verrà
'chiamato ogni volta che sia stata trovata una nuova finestra
Success = EnumDesktopWindows(IntPtr.Zero, Callback, 0)
'Se la funzione non ha successo, restituisce un errore
If Success = False Then
Debug.WriteLine("Si è verificato un errore nell'applicazione!")
End If
End Sub
Sub Main()
Debug.WriteLine("Questo programma enumera tutte le finestre aperte.")
EnumerateWindows()
End Sub
End Module