Differenze tra le versioni di "Simulare il tasto premuto del mouse usando le funzioni esterne del API di X11"

Da Gambas-it.org - Wikipedia.
 
(20 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
----
 
 
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.
 
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.3.0'' ".
+
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''.
 
Mostriamo un semplice esempio, nel quale - simulando la pressione sul tasto sinistro del mouse - si cliccherà automaticamente su un ''Button'' posto sul ''Form''.
Private dsp As Pointer
 
 
  Private Button1 As Button
 
  Private Button1 As Button
 
   
 
   
  Library "libX11:6.3.0"
+
  Library "libX11:6.4.0"
 
   
 
   
 
  <FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)''
 
  <FONT Color=gray>' ''Display *XOpenDisplay(char *display_name)''
Riga 23: Riga 20:
 
  Private Extern XCloseDisplay(display As Pointer) As Integer
 
  Private Extern XCloseDisplay(display As Pointer) As Integer
 
   
 
   
   <FONT Color=gray>' ''void XButtonClick(Display * disp, int button, int is_press, int delay)''</font>
+
   <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 Integer) In "/tmp/mouse"
+
  Private Extern XButtonClick(dpy As Pointer, button As Integer, is_press As Boolean, delay As Long) In "/tmp/mouse"
 
   
 
   
 
   
 
   
  '''Public''' Sub _new()
+
  Public Sub _new()
 
  Me.Show
 
 
   
 
   
 +
  With Me
 +
    .X = 100
 +
    .Y = 150
 +
  End With
 
   With Button1 = New Button(Me) As "Button1"
 
   With Button1 = New Button(Me) As "Button1"
     .X = 0
+
     .X = 70
     .Y = 20
+
     .Y = 120
 
     .W = 100
 
     .W = 100
 
     .H = 50
 
     .H = 50
 
   End With
 
   End With
 
+
   Wait 0.3
+
   Me.Show
 
+
  <FONT Color=gray>' ''Va a generare la libreria esterna condivisa ad hoc per la gestione di alcune particolarissime funzioni di X11:''</font>
+
  <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.5))
+
<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("Error !")
+
   If dsp == 0 Then Error.Raise("Errore !")
   XButtonClick(dsp, 1, CByte(True), 1000)
+
   XButtonClick(dsp, 1, CByte(True), 500)
 
   XFlush(dsp)
 
   XFlush(dsp)
   XButtonClick(dsp, 1, CByte(False), 1000)
+
  Wait 0.7
 +
   XButtonClick(dsp, 1, CByte(False), 0)
 
   XFlush(dsp)
 
   XFlush(dsp)
 
   
 
   
Riga 56: Riga 63:
 
   dsp = 0
 
   dsp = 0
 
    
 
    
  '''End'''
+
  End
 
   
 
   
  '''Private''' Procedure Creaso()
+
   
 +
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 button, int is_press, int delay) {\n"
+
                             "void XButtonClick(Display * disp, unsigned int xbutton, Bool press, unsigned long rit) {\n"
                             "  XTestFakeButtonEvent(disp, button, is_press, delay);\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"
 +
 +
<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
 
   Shell "gcc -o /tmp/mouse.so /tmp/mouse.c -shared -lX11 -lXtst" Wait
 
   
 
   
  '''End'''
+
  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()
+
  Public Sub Button1_Click()
 
   
 
   
 
   Print "Tasto premuto !"
 
   Print "Tasto premuto !"
 
   
 
   
  '''End'''
+
  <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