Differenze tra le versioni di "Simulare il tasto premuto del mouse usando le funzioni esterne del API di X11"
(Creata pagina con "La simulazione del tasto premuto (ossia generare un "_MouseDown()" e "_MouseUp()" o un "_Click()" automaticamente senza l'intervento manuale dell'utente) del mouse su un Contr...") |
|||
(26 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
− | La simulazione del tasto premuto (ossia generare un "_MouseDown()" e "_MouseUp()" o un "_Click()" automaticamente senza l'intervento manuale dell'utente) | + | La simulazione del tasto sinistro premuto del mouse (ossia generare un "_MouseDown()" e "_MouseUp()" o un "_Click()" automaticamente senza l'intervento manuale dell'utente) su un Controllo grafico o comunque su una qualsiasi finestra/superficie (desktop compreso), è un Evento a volte richiesto dai programmatori, ma di difficilissima realizzazione in Gambas. |
− | Una soluzione può essere il richiamo diretto | + | Una soluzione può essere il richiamo diretto - mediante l'istruzione "Extern" - e indiretto - mediante una libreria esterna appositamente realizzata - di alcune funzioni esterne del sistema grafico X11, e contenute in particolare nella libreria condivisa: "''libX11.so.6.4.0'' ". |
− | Mostriamo un semplice esempio, nel quale si cliccherà automaticamente su un ''Button'' posto sul ''Form''. | + | Mostriamo un semplice esempio, nel quale - simulando la pressione sul tasto sinistro del mouse - si cliccherà automaticamente su un ''Button'' posto sul ''Form''. |
− | |||
Private Button1 As Button | Private Button1 As Button | ||
− | Library "libX11:6. | + | Library "libX11:6.4.0" |
<FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)'' | <FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)'' | ||
Riga 21: | Riga 20: | ||
Private Extern XCloseDisplay(display As Pointer) As Integer | Private Extern XCloseDisplay(display As Pointer) As Integer | ||
− | <FONT Color=gray>' ''void XButtonClick(Display * | + | <FONT Color=gray>' ''void XButtonClick(Display * dpy, unsigned int button, Bool is_press, unsigned long delay)''</font> |
− | Private Extern XButtonClick( | + | Private Extern XButtonClick(dpy As Pointer, button As Integer, is_press As Boolean, delay As Long) In "/tmp/mouse" |
− | + | Public Sub _new() | |
− | |||
− | |||
+ | With Me | ||
+ | .X = 100 | ||
+ | .Y = 150 | ||
+ | End With | ||
With Button1 = New Button(Me) As "Button1" | With Button1 = New Button(Me) As "Button1" | ||
− | .X = | + | .X = 70 |
− | .Y = | + | .Y = 120 |
.W = 100 | .W = 100 | ||
.H = 50 | .H = 50 | ||
End With | End With | ||
− | + | ||
− | + | Me.Show | |
− | + | ||
− | <FONT Color=gray>' ''Va a generare la libreria esterna condivisa ad hoc per la gestione di | + | <FONT Color=gray>' ''Va a generare la libreria esterna condivisa ad hoc per la gestione di una particolarissima funzione di X11:''</font> |
creaso() | creaso() | ||
− | Mouse.Move(Button1.ScreenX + 20, Button1.ScreenY + (Button1.H * 0. | + | <FONT Color=gray>' ''Le istruzioni interne al ciclo assicurano che il puntatore del mouse si venga a trovare sul "Button" posto sul "Form":''</font> |
+ | Dim g As Single | ||
+ | Repeat | ||
+ | g += 0.1 | ||
+ | <FONT Color=gray>' ''Sposta il puntatore del mouse sul "Button" posto sul "Form":''</font> | ||
+ | Mouse.Move(Button1.ScreenX + 20, Button1.ScreenY + (Button1.H * g)) | ||
+ | Wait 0.1 | ||
+ | Until Mouse.Inside(Button1) | ||
− | dsp = XOpenDisplay(0) | + | Dim dsp As Pointer = XOpenDisplay(0) |
− | If dsp == 0 Then Error.Raise(" | + | If dsp == 0 Then Error.Raise("Errore !") |
− | XButtonClick(dsp, 1, CByte(True), | + | XButtonClick(dsp, 1, CByte(True), 500) |
XFlush(dsp) | XFlush(dsp) | ||
− | XButtonClick(dsp, 1, CByte(False), | + | Wait 0.7 |
+ | XButtonClick(dsp, 1, CByte(False), 0) | ||
XFlush(dsp) | XFlush(dsp) | ||
+ | |||
XCloseDisplay(dsp) | XCloseDisplay(dsp) | ||
+ | <FONT Color=gray>' ''Assicura che il Puntatore non punti a un indirizzo rilevante di memoria:''</font> | ||
dsp = 0 | dsp = 0 | ||
− | + | End | |
− | + | ||
+ | Private Procedure Creaso() | ||
File.Save("/tmp/mouse.c", "#include <X11/Xlib.h>\n" & | File.Save("/tmp/mouse.c", "#include <X11/Xlib.h>\n" & | ||
"#include <X11/extensions/XTest.h>\n" & | "#include <X11/extensions/XTest.h>\n" & | ||
− | "void XButtonClick(Display * disp, int | + | "void XButtonClick(Display * disp, unsigned int xbutton, Bool press, unsigned long rit) {\n" |
− | " XTestFakeButtonEvent(disp, | + | " XTestFakeButtonEvent(disp, xbutton, press, rit);\n}") |
− | + | ||
Shell "gcc -o /tmp/mouse.so /tmp/mouse.c -shared -lX11 -lXtst" Wait | Shell "gcc -o /tmp/mouse.so /tmp/mouse.c -shared -lX11 -lXtst" Wait | ||
+ | |||
+ | End | ||
+ | |||
+ | |||
+ | Public Sub Button1_Click() | ||
+ | |||
+ | Print "Tasto premuto !" | ||
+ | |||
+ | End | ||
+ | In questa variante del codice precedente si cliccherà automaticamente prima sul ''Button'' posto sul ''Form'' e successivamente sul tastino "X" di chiusura - posto nell'angolo alto a destra del ''Form'' medesimo: | ||
+ | Private Button1 As Button | ||
+ | |||
+ | Library "libX11:6.4.0" | ||
+ | |||
+ | <FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)'' | ||
+ | ' ''Opens a connection to the X server that controls a display.''</font> | ||
+ | Private Extern XOpenDisplay(display_name As Pointer) As Pointer | ||
+ | |||
+ | <FONT Color=gray>' ''int XFlush(Display *display)'' | ||
+ | ' ''Flushes the output buffer.''</font> | ||
+ | Private Extern XFlush(display As Pointer) | ||
+ | |||
+ | <FONT Color=gray>' ''int XCloseDisplay(Display *display)'' | ||
+ | ' ''Closes the connection to the X server for the display specified in the Display structure and destroys all windows.''</font> | ||
+ | Private Extern XCloseDisplay(display As Pointer) As Integer | ||
+ | |||
+ | <FONT Color=gray>' ''void XButtonClick(Display * dpy, unsigned int button, Bool is_press, unsigned long delay)''</font> | ||
+ | Private Extern XButtonClick(display As Pointer, xbutton As Integer, is_press As Boolean, delay As Long) In "/tmp/mouse" | ||
+ | |||
+ | |||
+ | Public Sub _new() | ||
+ | |||
+ | With Me | ||
+ | .X = 100 | ||
+ | .Y = 150 | ||
+ | End With | ||
+ | With Button1 = New Button(Me) As "Button1" | ||
+ | .X = 70 | ||
+ | .Y = 120 | ||
+ | .W = 100 | ||
+ | .H = 50 | ||
+ | End With | ||
+ | |||
+ | Me.Show | ||
+ | |||
+ | <FONT Color=gray>' ''Va a generare la libreria esterna condivisa ad hoc per la gestione di una particolarissima funzione di X11:''</font> | ||
+ | creaso() | ||
+ | |||
+ | <FONT Color=gray>' ''Le istruzioni interne al ciclo assicurano che il puntatore del mouse si venga a trovare sul "Button" posto sul "Form":''</font> | ||
+ | Dim g As Single | ||
+ | Repeat | ||
+ | g += 0.1 | ||
+ | <FONT Color=gray>' ''Sposta il puntatore del mouse sul "Button" posto sul "Form":''</font> | ||
+ | Mouse.Move(Button1.ScreenX + 20, Button1.ScreenY + (Button1.H * g)) | ||
+ | Wait 0.1 | ||
+ | Until Mouse.Inside(Button1) | ||
+ | |||
+ | TastoPremuto() | ||
+ | |||
+ | End | ||
+ | |||
+ | |||
+ | Private Procedure Creaso() | ||
− | ''' | + | File.Save("/tmp/mouse.c", "#include <X11/Xlib.h>\n" & |
+ | "#include <X11/extensions/XTest.h>\n" & | ||
+ | "void XButtonClick(Display * disp, unsigned int xbutton, Bool press, unsigned long rit) {\n" | ||
+ | " XTestFakeButtonEvent(disp, xbutton, press, rit);\n}") | ||
+ | |||
+ | Shell "gcc -o /tmp/mouse.so /tmp/mouse.c -shared -lX11 -lXtst" Wait | ||
+ | |||
+ | End | ||
+ | |||
+ | |||
+ | Private Procedure TastoPremuto() | ||
+ | |||
+ | Dim dsp As Pointer = XOpenDisplay(0) | ||
+ | If dsp == 0 Then Error.Raise("Errore !") | ||
+ | XButtonClick(dsp, 1, CByte(True), 500) | ||
+ | XFlush(dsp) | ||
+ | Wait 0.7 | ||
+ | XButtonClick(dsp, 1, CByte(False), 0) | ||
+ | XFlush(dsp) | ||
+ | |||
+ | XCloseDisplay(dsp) | ||
+ | <FONT Color=gray>' ''Assicura che il Puntatore non punti a un indirizzo rilevante di memoria:''</font> | ||
+ | dsp = 0 | ||
+ | |||
+ | End | ||
+ | |||
− | + | Public Sub Button1_Click() | |
Print "Tasto premuto !" | Print "Tasto premuto !" | ||
− | ''' | + | <FONT Color=gray>' ''Pone un'attesa di 1 secondo, per mostrare più chiaramente il successivo spostamento del puntatore del mouse:''</font> |
+ | Wait 1 | ||
+ | |||
+ | <FONT Color=gray>' ''Sposta il puntatore del mouse sul tastino "X" in alto a destra di chiusura del "Form":''</font> | ||
+ | Mouse.Move(Me.ScreenX + Me.W - 12, Me.Y + 12) | ||
+ | |||
+ | TastoPremuto() | ||
+ | |||
+ | End |
Versione attuale delle 13:52, 7 gen 2024
La simulazione del tasto sinistro premuto del mouse (ossia generare un "_MouseDown()" e "_MouseUp()" o un "_Click()" automaticamente senza l'intervento manuale dell'utente) su un Controllo grafico o comunque su una qualsiasi finestra/superficie (desktop compreso), è un Evento a volte richiesto dai programmatori, ma di difficilissima realizzazione in Gambas.
Una soluzione può essere il richiamo diretto - mediante l'istruzione "Extern" - e indiretto - mediante una libreria esterna appositamente realizzata - di alcune funzioni esterne del sistema grafico X11, e contenute in particolare nella libreria condivisa: "libX11.so.6.4.0 ".
Mostriamo un semplice esempio, nel quale - simulando la pressione sul tasto sinistro del mouse - si cliccherà automaticamente su un Button posto sul Form.
Private Button1 As Button Library "libX11:6.4.0" ' Display *XOpenDisplay(char *display_name) ' Opens a connection to the X server that controls a display. Private Extern XOpenDisplay(display_name As Pointer) As Pointer ' int XFlush(Display *display) ' Flushes the output buffer. Private Extern XFlush(display As Pointer) ' int XCloseDisplay(Display *display) ' Closes the connection to the X server for the display specified in the Display structure and destroys all windows. Private Extern XCloseDisplay(display As Pointer) As Integer ' void XButtonClick(Display * dpy, unsigned int button, Bool is_press, unsigned long delay) Private Extern XButtonClick(dpy As Pointer, button As Integer, is_press As Boolean, delay As Long) In "/tmp/mouse" Public Sub _new() With Me .X = 100 .Y = 150 End With With Button1 = New Button(Me) As "Button1" .X = 70 .Y = 120 .W = 100 .H = 50 End With Me.Show ' Va a generare la libreria esterna condivisa ad hoc per la gestione di una particolarissima funzione di X11: creaso() ' Le istruzioni interne al ciclo assicurano che il puntatore del mouse si venga a trovare sul "Button" posto sul "Form": Dim g As Single Repeat g += 0.1 ' Sposta il puntatore del mouse sul "Button" posto sul "Form": Mouse.Move(Button1.ScreenX + 20, Button1.ScreenY + (Button1.H * g)) Wait 0.1 Until Mouse.Inside(Button1) Dim dsp As Pointer = XOpenDisplay(0) If dsp == 0 Then Error.Raise("Errore !") XButtonClick(dsp, 1, CByte(True), 500) XFlush(dsp) Wait 0.7 XButtonClick(dsp, 1, CByte(False), 0) XFlush(dsp) XCloseDisplay(dsp) ' Assicura che il Puntatore non punti a un indirizzo rilevante di memoria: dsp = 0 End Private Procedure Creaso() File.Save("/tmp/mouse.c", "#include <X11/Xlib.h>\n" & "#include <X11/extensions/XTest.h>\n" & "void XButtonClick(Display * disp, unsigned int xbutton, Bool press, unsigned long rit) {\n" " XTestFakeButtonEvent(disp, xbutton, press, rit);\n}") Shell "gcc -o /tmp/mouse.so /tmp/mouse.c -shared -lX11 -lXtst" Wait End Public Sub Button1_Click() Print "Tasto premuto !" End
In questa variante del codice precedente si cliccherà automaticamente prima sul Button posto sul Form e successivamente sul tastino "X" di chiusura - posto nell'angolo alto a destra del Form medesimo:
Private Button1 As Button Library "libX11:6.4.0" ' Display *XOpenDisplay(char *display_name) ' Opens a connection to the X server that controls a display. Private Extern XOpenDisplay(display_name As Pointer) As Pointer ' int XFlush(Display *display) ' Flushes the output buffer. Private Extern XFlush(display As Pointer) ' int XCloseDisplay(Display *display) ' Closes the connection to the X server for the display specified in the Display structure and destroys all windows. Private Extern XCloseDisplay(display As Pointer) As Integer ' void XButtonClick(Display * dpy, unsigned int button, Bool is_press, unsigned long delay) Private Extern XButtonClick(display As Pointer, xbutton As Integer, is_press As Boolean, delay As Long) In "/tmp/mouse" Public Sub _new() With Me .X = 100 .Y = 150 End With With Button1 = New Button(Me) As "Button1" .X = 70 .Y = 120 .W = 100 .H = 50 End With Me.Show ' Va a generare la libreria esterna condivisa ad hoc per la gestione di una particolarissima funzione di X11: creaso() ' Le istruzioni interne al ciclo assicurano che il puntatore del mouse si venga a trovare sul "Button" posto sul "Form": Dim g As Single Repeat g += 0.1 ' Sposta il puntatore del mouse sul "Button" posto sul "Form": Mouse.Move(Button1.ScreenX + 20, Button1.ScreenY + (Button1.H * g)) Wait 0.1 Until Mouse.Inside(Button1) TastoPremuto() End Private Procedure Creaso() File.Save("/tmp/mouse.c", "#include <X11/Xlib.h>\n" & "#include <X11/extensions/XTest.h>\n" & "void XButtonClick(Display * disp, unsigned int xbutton, Bool press, unsigned long rit) {\n" " XTestFakeButtonEvent(disp, xbutton, press, rit);\n}") Shell "gcc -o /tmp/mouse.so /tmp/mouse.c -shared -lX11 -lXtst" Wait End Private Procedure TastoPremuto() Dim dsp As Pointer = XOpenDisplay(0) If dsp == 0 Then Error.Raise("Errore !") XButtonClick(dsp, 1, CByte(True), 500) XFlush(dsp) Wait 0.7 XButtonClick(dsp, 1, CByte(False), 0) XFlush(dsp) XCloseDisplay(dsp) ' Assicura che il Puntatore non punti a un indirizzo rilevante di memoria: dsp = 0 End Public Sub Button1_Click() Print "Tasto premuto !" ' Pone un'attesa di 1 secondo, per mostrare più chiaramente il successivo spostamento del puntatore del mouse: Wait 1 ' Sposta il puntatore del mouse sul tastino "X" in alto a destra di chiusura del "Form": Mouse.Move(Me.ScreenX + Me.W - 12, Me.Y + 12) TastoPremuto() End