Individuare ed estrarre l'ID della finestra di un programma
Vi sono diverse modalità per trovare il numero identificativo (ID) della finestra di un'applicazione.
Indice
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("") 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("")[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 c As Integer c = Desktop.ActiveWindow With dw = New DesktopWindow(c) 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 iHandle As Integer aHandle = Desktop.FindWindow("titolo_finestra_programma", Null, Null) ' oppure: aHandle = Desktop.FindWindow(Null, "nome_applicazione", Null) ' o anche: aHandle = Desktop.FindWindow(Null, Null, "Window_Role") If aHandle.Count = 0 Then Message.Warning("Finestra non trovata !") Return Endif iHandle = aHandle[0] ' ...che va a mostrare in console: Print iHandle End
Da rcordare 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 j As Byte For j = 0 To Desktop.FindWindow("").Max With Desktop Print .FindWindow("")[j], Hex(.FindWindow("")[j]) 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: Sleep 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
Con la Classe X11, richiamabile attivando il componente gb.desktop.x11, si potrà utilizzare il metodo ".FindWindow()" in modo identico all'omonimo metodo visto prima per la Classe Desktop. Si rinvia, pertanto, al relativo paragrafo sopra.
Uso di comandi bash
Si potrà fare uso anche di alcuni comandi bash:
Uso del comando wmctrl
Questo è un comando che normalmente viene lanciato da terminale, e che pertanto in Gambas si potrà lanciare con Shell o Exec. Esempio: Shell "wmctrl -p -l".
Private h As Process Public Sub Form_Open() h = Shell "nome_programma" End Public Sub Button1_Click() Dim a, b, decInt As Integer Dim lista As String Dim aStr As String[] ' inserisce nella variabile stringa tutto il risultato del comando "wmctrl"... Shell " wmctrl -p -l" To lista ' ...e lo "spezzetta" nelle sue parole componenti, ' che inserisce in piu variabili stringhe[]: aStr = Split(lista, " ") For a = 0 To aStr.Count - 1 If aStr[a] Like "nome_finestra*" Then For b = a - 1 To a - 10 Step - 1 If Right(aStr[b], 10) Like "0x*" Then ' Viene mostrato, quindi, il numero esadecimale e quello decimale dell'ID: Print Right(aStr[b], 8), Val("&" & Right(aStr[b], 8)) Endif Next Endif Next End Public Sub Button2_Click() ' Chiude "nome_programma" e poi il programma Gambas: h.Kill Me.Close End
Uso del comando xwininfo
Anche questo è un comando che normalmente viene lanciato da terminale, ma bisogna indicare il titolo della finestra dell'applicazione che si vuole inglobare, e che pertanto in Gambas si potrà lanciare con Shell o Exec.
Esempio: Shell "xwininfo -name " & "\titolo_finestra_programma\" | grep " & "\titolo_finestra_programma\".
Private h As Process Public Sub Form_Open() h = Shell "nome_programma" End Public Sub Button1_Click() Dim decInt As Integer Dim lista As String Dim aStr As String[] ' inserisce nella variabile stringa tutto il risultato del comando "xwininfo"... Shell "xwininfo -name " & "\"titolo_finestra_programma\" | grep " & "\"titolo_finestra_programma\"" To lista ' ...e lo "spezzetta" nelle sue parole componenti, ' che inserisce in piu variabili stringhe[]: aStr = Split(lista, " ") ' prende il contenuto della variabile stringa[] contenente il numero dell'ID (in esadecimale); ' lo converte in esadecimale compresibile da Gambas; poi in decimale... decInt = Val("&" & Mid$(aStr[3], 3)) ' ...e lo mostra in console: Print decInt End Public Sub Button2_Click() ' Chiude "nome_programma" e poi il programma Gambas: h.Kill Me.Close End
Uso del comando xprop | grep -i window
Questa linea di comando, anch'essa normalmente lanciata da terminale, consentirà di individuare con il mouse la finestra, della quale ottenere l'ID. In particolare, una volta lanciata questa riga di comando, il puntatore del mouse modificherà il proprio aspetto in quello a forma di croce, si procederà quindi a cliccare sulla finestra interessata.
Esempio:
Public Sub Button1_Click() Dim pr As Process Dim ss, x As New String[] Dim s, y As String Dim j As Byte Dim i As Integer pr = Shell "xprop | grep -i window" For Read While Not Eof(pr) Input #pr, s If s < Chr(40) Then Continue ss.Add(s) Wend For j = 0 To ss.Max If ss[j] = "_NET_WM_USER_TIME_WINDOW(WINDOW):" Then ' Dividiamo la stringa in modo tale da ottenere la seconda parte priva della “x”: x = Split(ss[j + 3], "x") ' Prendiamo del valore esadecimale soltanto i primi due valori più a destra: y = Right(ss[j + 7], 2) ' Individua il valore esadecimale preciso della finestra, lo trasforma in decimale... i = Val("&" & x[1]) - Val("&" & y) Endif Next ' ...e lo mostra in console: Print i End
Se si tratta di raccogliere l'ID della finestrina di un MessageBox, generato da un programma, allora il codice sarà un po' diverso:
Public Sub Form_Open() Dim pr As Process Dim x As New String[] Dim s As String Dim i As Integer pr = Shell "xprop | grep XKLAVIER_STATE" For Read While Not Eof(pr) Input #pr, s ' Individua il valore decimale della finestra del "MessageBox": If Eof(pr) Then i = CInt(s) Wend ' ...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...