Ho la neccessità di utilizzare in un progetto Gambas3 una tastiera virtuale su un touchscreen,
la prima cosa che mi è venuta in mente è richiamare quella disponibile in Ubuntu, perchè realizzarne
una con Gambas (presumo fattibile) credo sia un pò complicato.
Con la seguente istruzione
Public Sub BtnKeyb_Click()
Shell "onboard"
End
ho richiamato come detto quella di Ubuntu, che va benissimo come tastiera per le mie esigenze,
ma ho un problema, mi spiego:
Quando richiamata vorrei visulizzarla all'interno di un form con delle dimensioni ben precise posizionandola
in un punto prefissato dello schermo.
Non ho idea di come fare è se la cosa è fattibile.
"all'interno di un form" io direi con l'Embedder ed il metodo Embed.
Se vuoi, invece, semplicemente visualizzarla sullo schermo:
Public Sub BtnKeyb_Click()
Shell "onboard" Wait
' la tastierina virtuale viene posta in basso al centro dello schermo:
Shell "wmctrl -r onboard -e 0,500,800,600,300"
End
Note:
1) Con il comando bash wmctrl la tastierina virtuale (in realtà: la finestra del programma da gestire) deve essere ovviamente aperta prima che operi il comando wmctrl (perché appunto questo agirà sulla sua finestra);
2) riguardo ai valori dell'esempio precedente:- 500 = coordinate x;
- 800 = coordinate y;
- 600 = lunghezza della finestra;
- 300 = altezza della finestra.
Quindi, volendo, puoi anche far modificare la grandezza della tastierina virtuale. Se non vuoi, i due ultimi parametri dovrebbero essere posti a -1.
Ho la soluzione per te
(necessita ancora ;D la presenza nel sistema del programmino wmctrl):
Private h As Process
Public Sub Form_Open()
'....va be', metto qui a fini esemplificativi l'avvio di "onboard"
h = Shell "onboard"
End
Public Sub Button1_Click()
Dim id As Integer
Dim listaId, s As String
Dim ss As String[]
Dim j As Byte
Shell "wmctrl -p -l" To listaId
' per estrapolare l'ID di "onboard" raccolgo tutte le righe della variabile "listaId"
' distinguendole sulla base del carattere "nuova riga a capo":
ss = Split(listaId, "\n")
For j = 0 To ss.Max
' Se nella riga presa in considerazione è presente la parola "onboard"...
If ss[j] Like "*onboard" Then
'...allora ne raccogliamo i caratteri che indicano l'Id in esadecimale della sua finestra...
s = Replace(Split(ss[j], " ")[0], "0x", Null)
' ...e lo convertiamo in decimale:
id = Val("&" & s)
' Per curiosità vediamo l'Id in console:
Print id
Endif
Next
' Inserisco l'Id della finestra di "onboard" in "Embed":
Embedder1.Embed(id)
End
Public Sub Button2_Click() ' con questo puoi anche eliminare la tastierina
h.kill
End
:rolleyes:
Io l'ho provato con la calcolatrice KCalc su Kubuntu-KDE, e funziona perfettamente.
Fammi sapere. :ciao:
...ma ho elaborato una strada molto più breve e veloce: :coder:
(qui non è più necessario wmctrl, né useremo più la Classe Process. Bisogna però attivare il componente: gb.desktop)
Private dw As DesktopWindow
Public Sub Form_Open()
Shell "onboard"
End
Public Sub Button1_Click()
Dim a As Integer
' Fra le finestre aperte sul Desktop...
For Each dw In Desktop.Windows
'...cerca quella avente nome "onboard"...
If dw.name = "onboard" Then
' ...per estrarne l'Id (già in decimale !)...
a = dw.Id
Endif
Next
' ...che va ad inserire in Embed:
Embedder1.Embed(a)
End
Public Sub Button2_Click() ' chiude "onboard"
' La finestra di "onboard" viene liberata dall'inglobamento:
Embedder1.Discard()
' Viene nuovamente individuata...
For Each dw In Desktop.Windows
If dw.name = "onboard" Then
' e quindi viene chiusa:
dw.Close
Endif
Next
End
...... di più "nin zò" ! ;D
..ad ogni modo... mi ha incuriosito il programmino EMBED.tar.gz, che hai inserito in un tuo messaggio sopra, e gli ho dato uno sguardo. E' vero, le spiegazioni scritte dall'autore sono in tedesco, però ho cercato di capirne il funzionamento e soprattutto di individuare i passaggi più importanti e salienti.
...e ho lì trovato un terzo modo di individuare l'ID della finestra di un programma ;D . L'algoritmo lo puoi vedere all'interno della subroutine "WindowIDErmitteln()" (che infatti in tedesco insomma significa sostanzialmente "determina l'Id di una finestra).
Allora, il comando essenziale usato per ricavare l'ID è xwininfo:
xwininfo -name "nome_finestra_programma" | grep "nome_finestra_programma"
Ti riporto dunque il mio codice precedente, come sarebbe inserendo però il metodo di identificazione ed estrapolazione dell'ID della finestra utilizzato nel programma dell'autore tedesco:
Private h as Process
Public Sub Form_Open()
h = Shell "onboard"
End
Public Sub Button1_Click()
Dim iWinId_Dezimal As Integer
Dim sXWinInfoListe As String
Dim aMatrix As String[]
' inserisce nella variabile stringa tutto il risultato del comando "xwininfo"...
Shell "xwininfo -name " & "\"onboard\" | grep " & "\"onboard\"" To sXWinInfoListe
' ... e lo "spezzetta" nelle sue parole componenti,
' che inserisce in piu variabili stringhe[]:
aMatrix = Split(sXWinInfoListe, " ")
' prende il contenuto della variabile stringa[] contenente il numero dell'ID (in esadecimale);
' lo converte in esadecimale compresibile da Gambas; poi in decimale....
iWinId_Dezimal = Val("&" & Mid$(aMatrix[3], 3))
' ...che va ad inserire in Embed:
Embedder1.Embed(iWinId_Dezimal)
End
Public Sub Button2_Click() ' chiude "onboard" e poi il programma
h.Kill
Me.Close
End
Tra gli esempi di gambas c'è anche quello dell'embed. Quello ti funziona?
Buon suggerimento quello di Ceskho.
Ecco, Tornu, anche l'esempio di Gambas, suggerito da Ceskho, a me funziona regolarmente ! :-\
Ad ogni modo, l'unica cosa che mi pare cambi rispetto agli esempi precedenti, da me segnalati, è semplicemente e sostanzialmente la modalità di individuazione ed estrazione del PID, che comunque è già presente in questo forum:
http://www.gambas-it.org/smf/index.php?topic=163.0
http://www.gambas-it.org/smf/index.php?topic=1791.msg20424#msg20424
e che vorrei qui riportare dall'esempio di Gambas, ricordato sopra da Ceskho, per completare il quadro delle possibilità, con questo quarto modo.
E' necessario avere attivato il componente gb.desktop:
Public Sub btnEmbed_Click()
Dim sTitle as String
Dim aHandle As Integer[]
Dim iHandle As Integer
sTitle = txtTitle.Text
' se nel campo del titolo è stato inserito direttamente
' il numero esadecimale dell'ID della finestra del programma aperto,
' lo muta nella sua versione comprensibile da Gambas,
' poi lo converte in decimale:
If Left(sTitle, 2) = "0x" Then
iHandle = Val("&" & Mid$(sTitle, 3))
' se, invece, è stato inserito il numero esadecimale dell'ID
' della finestra del programma aperto, già nella sua versione
' comprensibile da Gambas, lo converte direttamente in decimale:
Else If Left(sTitle) = "&" Then
iHandle = Val(sTitle)
' se, invece, è stato inserito il "titolo" della finestra del programma aperto,
' ne ricava il suo ID (avendo anche l'accortezza di eliminare ogni eventuale
' spazio presente all'inizio o alla fine del titolo inserito):
Else
aHandle = Desktop.FindWindow(Trim(txtTitle.Text))
If aHandle.Count = 0 Then
Message.Warning(("Window not found!"))
Return
Else If aHandle.Count >= 2 Then
Message(("Several windows found. I take the first one!"))
Endif
iHandle = aHandle[0]
Endif
Try embEmbedder.Embed(iHandle)
If Error Then Message.Warning(Error.Text)
End
Forse la finestra di QSynth prevede alla fine qualche sorta di metacarattere.... :-\
Ho raccontato tutta questa storia per confermare, come ha già ricordato e ben sottolineato da Milio, l'importanza del riportare il nome corretto del titolo della finestra da inglobare,...
Ho risolto questo problema, relativo a titoli un po' particolari delle finestre, mediante LIKE ed il metacarattere * nel modo seguente.
Prendo come esempio ancora una volta la finestra di QSynth, che ha per titolo: Qsynth - A fluidsynth Qt GUI Interface [Qsynth1] (...insomma, una cosa terribile ! ;D ):
Public Sub Button1_Click()
Dim dWindow As DesktopWindow
Dim a As Integer
For Each dWindow In Desktop.Windows
' cerca la finestra avente il titolo che inizia con "Qsynth"
' e continua con i restanti caratteri, dei quali è eventualmente costituito...
If dWindow.name Like "Qsynth*" Then
' ...per estrarne l'Id (già in decimale !)...
a = dWindow.Id
Endif
Next
' ...che va ad inserire in Embed:
Embedder1.Embed(a)
End