Individuare ed estrarre l'ID della finestra di un programma

Da Gambas-it.org - Wikipedia.

Vi sono diverse modalità per trovare il numero identificativo (ID) della finestra di un'applicazione.


Uso delle Classi di Gambas

Potremo utilizzare varie Classi e risorse di Gambas.


Individuare l'ID della finestra del programma Gambas principale

Per individuare l'ID della finestra del programma gambas principale potremo utilizzare la Classe FMain o la parola Me, oppure la funzione ActiveWindow della Classe Application.


Uso della Classe FMain o la parola Me

L'uso della Classe FMain o della parola Me è senz'altro il metodo più veloce per conoscere l'ID della finestra del programma principale:

Public Sub Button2_Click()

 With FMain
' L'ID della "finestra" del programma principale viene mostrato in decimale ed in esadecimale:
   Print .Id, Hex(.Id)
 End With

End


Uso della funzione ActiveWindow della Classe Application

Public Sub Button1_Click()

 Dim w As Window

 w = Application.ActiveWindow

 Print w.Id, hex(w.Id)
 
End

o più velocemente:

Public Sub Button1_Click()

 Print Application.ActiveWindow.Id

End


Individuare l'ID della finestra che contiene un Controllo

Per individuare l'ID della finestra che contiene un Controllo, possiamo usare la proprietà Window del Controllo medesimo.

Poniamo per esempio di avere un applicativo con due Form: uno principale (FMain) ed uno secondario (Form1). Sul Form secondario, Form1, è posto un Button. Supponiamo di voler individuare l'ID della finestra del Form secondario, ove è posto il Button, al fine di conoscere il nome della finestra e di gestirla. Nel codice della Classe, alla quale appartiene il Form secondario, avremo:

Public Sub aperturaFormSecondario()

 Form1.Show()

 With Button1.Window
' Otteniamo l'ID ed il nome della finestra del Form secondario...:
   Print Hex(.Id), .Name
' ...inoltre, la spostiamo e la ridimensioniamo:
   .Move(200, 500, 50, 300)
 End With

End


Uso della Classe DesktopWindow

In tal caso sarà necessario caricare il componente gb.desktop.


Individuare l'ID di tutte le finestre aperte nella scrivania

Se si intende individuare e raccogliere l'ID di tutte le finestre aperte in quel momento sulla scrivania, si potrà procedere con il seguente algoritmo:

Public Sub Button1_Click()

 Dim i As Integer
 Dim dw As DesktopWindow

' Otteniamo gli ID di tutte le "finestre" aperte sulla scrivania:
 For Each i In Desktop.FindWindow(Null, Null, Null)
   With dw = New DesktopWindow(i)
' La console mostra il nome visibile della finestra ed il suo ID:
     Print .VisibleName, Hex(i), i
   End With
 Next

End


Individuare l'ID di una finestra di nome conosciuto

Se vogliamo conoscere l'ID di una finestra di cui conosciamo il nome, possiamo fare come segue:

Public Sub Button1_Click()

 Dim dWin As DesktopWindow

 For Each dWin In Desktop.Windows
' cerca la finestra avente titolo "titolo_finestra_programma"...
   If dWin.VisibleName = "titolo_finestra_programma" Then      |2|
' ...per estrarne l'Id:
     Print dWin.Id, Hex(dWin.Id)
   Endif

 Next

End


Individuare l'ID di una finestra di indice array conosciuto

Se, invece, vogliamo conoscere l'ID di una finestra di cui conosciamo il numero dell'elemento dell'array di tipo integer, nella quale è posta, possiamo fare come segue:

Public Sub Button1_Click()

 Dim i As Integer
 Dim dw As DesktopWindow

' Ottengo l'ID della finestra, aperta nella scrivania, contenuto nel tot elemento dell'array:
 With dw = New DesktopWindow(Desktop.FindWindow(Null, Null, Null)[num_Index])
' La console mostra il nome visibile della finestra ed il suo ID:
   Print .VisibleName, Hex(i), i
 End With

End


Individuare l'ID di una finestra cliccandoci sopra con il mouse

Se vogliamo conoscere l'ID della finestra di un qualsiasi programma semplicemente cliccandoci sopra con il puntatore del mouse, possiamo utilizzare un codice come il seguente (è necessario porre un Timer):

Public Sub Form_Open()

 With Timer1
   .Delay = 100
   .Start
 End With

End
 

Public Sub Timer1_Timer()

 Dim dw As DesktopWindow
 Dim i As Integer
 
 i = Desktop.ActiveWindow

 With dw = New DesktopWindow(i)
   TextArea1.Text = .VisibleName & " = " & Hex(.Id)
 End With

End


Uso della Classe Desktop

Con la Classe Desktop, richiamabile attivando il componente gb.desktop, si potranno utilizzare la funzione: ".FindWindow" e la proprietà: "ActiveWindow".

Uso della funzione Desktop.FindWindow

Il metodo .FindWindow ritorna un array di identificatori delle finestre X11 presenti sul desktop dell'utente. Con tale metodo si potrà usare il titolo della finestra oppure il nome dell'applicazione che ha generato la propria finestra. Si potrà procedere con il seguente algoritmo:

Public Sub Button1_Click()

 Dim aHandle As Integer[]
 Dim id As Integer

'  Cerca il numero identificativo della finestra dal titolo della finestra medesima, come memorizzato nella proprietà "WM_NAME" del sistema x11:
 aHandle = Desktop.FindWindow("titolo_finestra_programma", Null, Null)
' oppure dal nome della classe della finestra del programma, come memorizzato nella proprietà "WM_CLASS" del sistema x11:
' aHandle = Desktop.FindWindow(Null,"nome_classe_della_finestra", Null)
' o anche dal nome della funzione svolta dalla finestra, come memorizzata nella proprietà "WM_WINDOW_ROLE X11" del sistema x11:
' aHandle = Desktop.FindWindow(Null, Null, "ruolo_della_finestra")

 If aHandle.Count = 0 Then 
   Message.Warning("Finestra non trovata !")
   Return
 Endif

 id = aHandle[0]

' ...che va a mostrare in console:
 Print id

End

Da ricordare che negli argomenti del metodo Desktop.FindWindow() è possibile utilizzare il metacarattere dell'asterisco * come con Like.

Si potrà utilizzare, però, anche il metodo Windows della classe Desktop:

Public Sub Button1_Click()

' Se si conosce a quale indice corrisponde la finestra del programma da inglobare:
 Print Desktop.Windows[n].Id

End

Individuare l'ID di tutte le finestre aperte nella scrivania

Se si intende individuare e raccogliere, mediante la funzione Desktop.FindWindow, l'ID di tutte le finestre aperte in quel momento sulla scrivania, si potrà fare così:

Public Sub Button1_Click()

 Dim b As Byte

 For b = 0 To Desktop.FindWindow(Null, Null, Null).Max
   With Desktop
     Print .FindWindow(Null, Null, Null)[b], Hex(.FindWindow(Null, Null, Null)[b])
   End With
 Next

End 

oppure:

Public Sub Button1_Click()
 
 For Each i As Integer In Desktop.FindWindow(Null, Null, Null)
   With Desktop
     Print Hex(i), .Windows.FromHandle(i).VisibleName
   End With
 Next

End


Uso della proprietà Desktop.ActiveWindow

Per individuare l'ID della "finestra" corrente attiva di primo livello, si può utilizzare anche la proprietà "ActiveWindow" della classe Desktop.

Esempio:

Public Sub Button1_Click()

 Desktop.OpenTerminal

' Diamo il tempo alla "finestra" del Terminale di aprirsi:
 Wait 1 1

' Essendo la finestra del Terminale quella attiva in risalto, sarà restituito l'ID di tale finestra:
 Print Desktop.ActiveWindow

End


Uso della proprietà Desktop.Windows

La proprietà .Windows della Classe 'Desktop ritorna un array di tipo DesktopWindows che rappresenta le finestre di primo livello attive sulla scrivania.

Volendo, ad esempio, individuare l'ID di tutte le finestre aperte nella scrivania con detta proprietà, si potrà procedere nel modo che segue:

Public Sub Button1_Click()

 Dim dw As DesktopWindow

 For Each dw In Desktop.Windows
   Print Hex(dw2.id)
 Next

End

Ovviamente si potrà individuare una singola finestra in base all'indice dell'array restituito dalla proprietà .Windows:

dw = Desktop.Windows[n]

oppure sulla base del numero dell'handle (che è un Integer) della finestra che si intende individuare:

dw = Desktop.Windows.FromHandle(handle_della_finestra)


Uso della Classe X11

Per l'uso della Classe X11, richiamabile attivando il componente gb.desktop.x11, si rimanda alla segute pagina della Wiki:
Individuare ID e nome delle finestre attive, nonché il PID dei loro programmi con le risorse del Componente gb.desktop.x11


Uso delle funzioni esterne del API di X11

Per individuare l'ID, nonché il nome, della finestra di un programma, sia di quello Gambas principale che di altro esterno, si potrà fare uso delle funzioni della libreria X11.

Per analogia di argomento rinviamo a questa pagina della Wiki:
Individuare l'ID ed il nome di una finestra nonché il PID del programma mediante le funzioni del API di X11


Uso di comandi bash

Si potrà fare uso anche di alcuni comandi bash:

Uso del comando wmctrl

wmctrl è un comando che in Gambas potrà essere lanciato con Shell o Exec.
Esempio:

Public Sub Button1_Click()

 Dim i As Integer
 Dim lista As String
 Dim llss As String[]

' Inserisce nella variabile stringa tutto il risultato del comando "wmctrl"...
 Shell "wmctrl -p -l" To lista
 
 llss = Split(lista, Chr(10))
 
 For i = 0 To llss.Max
' Si inserirà il nome, anze parzialmente, della finestra del programma, di cui conoscere l'ID:
   If llss[i] Like "*Nome_anche_parziale_della_finestra_di_un_programma*" Then Print Scan(llss[i], "*x* *")[1]
 Next

End

Uso del comando xwininfo

Usando xwininfo, bisogna indicare il preciso titolo della finestra dell'applicazione.

Public Sub Button1_Click()

 Dim i As Integer
 Dim lista, s As String
 Dim ss As String[]

' Inserisce nella variabile stringa tutto il risultato del comando "xwininfo"...
 Shell "xwininfo -name " & "\"titolo_esatto_finestra_programma\"" To lista

' Prende il contenuto vettore di tipo "stringa[]" contenente il numero dell'ID (in esadecimale) e lo converte in esadecimale compresibile da Gambas e lo mostra:
 s = Scan(lista, "*0x* *")[1]
 Print s

' Poi lo converte in un valore di tipo di dato numerico "Integer"...</i>
 i = Val("&" & s))
' ...e lo mostra in console:
 Print i
 
End


Note

[1] E' possibile usare anche il metacarattere * sostituendo il segno = con LIKE.
Esempio:

If dWin.name Like "titolo_finestra_prog*" Then...