Modificare l'aspetto del cursore del mouse

Da Gambas-it.org - Wikipedia.

E' possibile modificare l'aspetto del cursore (o anche detto puntatore) del mouse sia quando il cursore è all'interno di una finestra dell'applicazione Gambas, sia quando esso è al di fuori.


Modificare l'aspetto del cursore del mouse quando esso è all'interno di una finestra dell'applicazione Gambas

Quando il cursore del mouse è all'interno di una finestra dell'applicazione Gambas, ne può essere modificato l'aspetto mediante le risorse di Gambas medesimo.

Vi sono almeno due modalità.


Uso della proprietà .Mouse di un oggetto

Vi sono vari oggetti che posseggono la proprietà .Mouse, alla quale va assegnato un valore che rappresenta un particolare aspetto grafico del puntatore del Mouse.
Se il puntatore del Mouse entra all'interno di quell'oggetto, esso muta il suo aspetto in quello stabilito dal valore assegnato alla proprietà .Mouse .


Esempio:

Public Sub Open_Form()

' Se il puntatore del Mouse entra all'interno del Form, muta il suo aspetto in una "croce":
  Me.Mouse = Mouse.Cross

End


Uso della Classe Cursor

La Classe Cursor consente di attribuire al puntatore del Mouse un'immagine.

In particolare, in fase di creazione della variabile di tipo Cursor, va assegnata ad essa una Picture contenente l'immagine che si utilizzerà per il nuovo aspetto del cursore del mouse. Tale variabile, poi, sarà assegnata alla proprietà .Cursor di quegli oggetti, che la supportano, passando con il mouse sui quali, si desidera che l'aspetto del cursore muti.


Poniamo come esempio il caso in cui si vuole che l'aspetto del puntatore muti quando si passa con esso su una TextLabel:

Private cu As Cursor


Public sub Form_Open()

 Dim pc As New Picture
 
' Viene caricata l'immagine da utilizzare per mutare l'aspetto del cursore del mouse:
   pc = pc.Load("/percorso/dell'immagine")  
 
' Viene istanziata la variabile di tipo "Cursor":
   cu = New Cursor(pc)
    
' Viene assegnata la variabile di tipo "Cursor" alla proprietà ".Cursor della "Textlabel",
' per attribuire la nuova immagine al puntatore, quando si passerà con esso sulla "TextLabel":
   TextLabel1.Cursor = cu
 
End

o più brevemente:

Public sub Form_Open()

 Dim pc As New Picture

  TextLabel1.Cursor = New Cursor(pc.Load("/percorso/dell'immagine"))

End


Modificare l'aspetto del cursore del mouse quando esso è all'esterno di qualsiasi finestra dell'applicazione Gambas

Quando il cursore del mouse è all'esterno di una qualsiasi finestra dell'applicazione Gambas, il suo aspetto può essere modificato mediante le funzioni esterne del API di X11.

In questo caso abbiamo due possibilità: impostare un aspetto scelto fra quelli indicati nel file header ".../X11/cursorfont.h" e visibili nella pagina "http://tronche.com/gui/x/xlib/appendix/b/", oppure un aspetto da noi liberamente disegnato.


Impostare un aspetto fra quelli indicati nel file header ".../X11/cursorfont.h"

Il file ".../X11/cursorfont.h" contiene 76 modelli di puntatori di mouse, a ciascuno dei quali è assegnato un numero (sempre di valore pari). E' possibile vedere quale aspetto tali modelli posseggono, accedendo ad esempio alla pagina WEB "http://tronche.com/gui/x/xlib/appendix/b/".


Il cambio dell'aspetto del puntatore del mouse deve sempre far riferimento ad una qualunque finestra presente sulla Scrivania (Desktop). Ciò vuol dire che la modifica del puntatore del mouse può avvenire solo se tale puntatore si trova all'interno della finestra prescelta dal programmatore. Sarà quindi necessario individuare il numero identificativo della finestra prescelta.


Mostriamo di seguito un esempio pratico, nel quale sarà possibile cambiare l'aspetto del puntatore del mouse solo se esso si trova direttamente al di sopra della Scrivania (Desktop). Se esso si troverà al di sopra della finestra di un programma, l'aspetto tornerà ad essere quello di default.

Come già detto, saranno utilizzate le funzioni esterne del API del sistema grafico X11.

L'esempio funziona sia da console che da Terminale dopo aver creato l'eseguibile. In entrambi i casi nell'pposito spazio sottostante la console, dopo aver avviato il progetto, si deve scrivere il numero che si riferisce al modello di cursore di mouse prescelto stando ovviamente con il cursore medesimo direttamente al di sopra del Desktop.
Se invece è stato creato l'eseguibile per farlo funzionare da Terminale, si dovrà nel Terminale scrivere il percorso dell'eseguibile seguito dal numero corrispondente al disegno di cursore prescelto, come visibile in "http://tronche.com/gui/x/xlib/appendix/b/". Esempio: ~ $ '/percorso/dell'/eseguibile.gambas' 14

Ad ogni modo, è sempre possibile cambiare aspetto del puntatore del mouse durante l'esecuzione dell'applicazione inviando da console, o da Terminale, un altro numero.

L'esempio che segue prevede che, qualora si intenda terminare l'esecuzione dell'applicazione, per tornare al classico aspetto predefinito del puntatore del mouse - quello di una freccia bianca che punta verso l'alto a sinistra - si dovrà, prima di terminare l'applicazione inviare il numero 2 . In caso di dimenticanza si potrà riavviare l'applicazione e così far tornare manualmente l'aspetto predefinito del puntatore del mouse, tenendo comunque presente che, ad ogni modo, la modifica del cursore dura per il solo durare della corrente sessione di sistema.

Va da sé, che anche durante l'esecuzione dell'esempio che segue, per ottenere nuovamente l'aspetto predefinito della freccia, si dovrà inviare il valore 2.

Il codice che segue è redatto per sistemi a 64-bit.

Private s As String


Library "libX11:6.3.0"

Private Const XA_CARDINAL As Integer = 6
Private Const XA_WINDOW As Integer = 33
Private Const MAX_PROPERTY_VALUE_LEN As Integer = 4096

' Display *XOpenDisplay(char *display_name)
' Opens a connection to the X server that controls a display.
Private Extern XOpenDisplay(display$ As String) As Pointer

' Window XDefaultRootWindow(Display *display)
' Return the root window for the default screen.
Private Extern XDefaultRootWindow(displayP As Pointer) As Integer

' Atom XInternAtom(Display *display, char *atom_name, Bool only_if_exists)
' Returns the atom identifier associated with the specified atom_name string.
Private Extern XInternAtom(displayP As Pointer, atom_name As String, only_if_exists As Boolean) As Integer

' int XGetWindowProperty(Display *display, Window w, Atom property, long long_offset, long long_length, Bool delete, Atom req_type, Atom *actual_type_return, int *actual_format_return, unsigned long *nitems_return, unsigned long *bytes_after_return, unsigned char **prop_return)
' Returns the actual type of the property; the actual format of the property.
Private Extern XGetWindowProperty(displayP As Pointer, wL As Long, py As Integer, lo As Long, ll As Long, d As Boolean, rt As Integer, at As Pointer, af As Pointer, ni As Pointer, ba As Pointer, pr As Pointer) As Integer

' Status XGetWMName(Display *display, Window w, XTextProperty *text_prop_return)
' Calls XGetTextProperty() to obtain the WM_NAME property.
Private Extern XGetWMName(displayP As Pointer, wL As Long, text_prop_return As Pointer) As Integer

' Cursor XCreateFontCursor(Display *display, unsigned int shape)
' Provides a set of standard cursor shapes in a special font named cursor.
Private Extern XCreateFontCursor(displayP As Pointer, shape As Integer) As Integer

' XDefineCursor(Display *display, Window w, Cursor cursor)
' If a cursor is set, it will be used when the pointer is in the window.
Private Extern XDefineCursor(displayP As Pointer, w As Long, cursorI As Integer) As Integer

' 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(displayP As Pointer)


Public Sub Main()

 Dim disp As Pointer
 Dim escritorio, cursor As Integer
 
  s = Application.Args[1]
  If IsNull(s) Then s = "2"
  
' Connessione al server X ed impostazione di default:
  disp = XOpenDisplay(Null)
  If IsNull(disp) Then Error.Raise("Impossibile connettersi al Server X !")
  
  escritorio = IDEscritorio(disp)
  
  While True
    Wait 0.01
    If IsNumber(s) Then
' Entrando il cursore del mouse nella finestra, esso cambia aspetto, impostando quello
' che nel file header "X11/cursorfont.h" ha il valore 2 tra quelli visibili nella pagina "http://tronche.com/gui/x/xlib/appendix/b/":
      cursor = XCreateFontCursor(disp, Val(s))
      XDefineCursor(disp, escritorio, cursor)
    Endif
    If s = "quit" Then
      cursor = XCreateFontCursor(disp, 2)
      XDefineCursor(disp, escritorio, cursor)
      Exit
    Endif
  Wend
  
' Chiude la libreria:
  XCloseDisplay(disp)
  Quit
  
End


Public Sub Application_Read()
 
  Input #File.In, s
 
End


Private Function IDEscritorio(ds As Pointer) As Integer

 Dim datID, p As Pointer
 Dim x_num_Atom, tipo, formato As Integer
 Dim err, n_fin, bytes_succ, i As Integer
 Dim rootW As Long
 Dim stId As Stream
 Dim b As Byte
  
  rootW = XDefaultRootWindow(ds)
  
  x_num_Atom = XInternAtom(ds, "_NET_CLIENT_LIST", False)
  
  err = XGetWindowProperty(ds, rootW, x_num_Atom, 0, MAX_PROPERTY_VALUE_LEN / 4, False, XA_WINDOW, VarPtr(tipo), VarPtr(formato), VarPtr(n_fin), VarPtr(bytes_succ), VarPtr(datID))
  If err <> 0 Then Error.Raise("Impossibile ottenere dati dalla funzione 'XGetWindowProperty' !")
  
  If XA_WINDOW <> tipo Then Error.Raise("Tipo invalido di proprietà '_NET_CLIENT_LIST' !")
  
  p = Alloc(32)
  
  stId = Memory datID For Read
  
  For b = 1 To n_fin * 2
    Read #stId, i
    If i > 0 Then
      XGetWMName(ds, i, p)
      If String@(Pointer@(p)) = "Scrivania" Then Exit
    Endif
  Next
  
' Va in chiusura:
  stId.Close
  Free(p)
 
  Return i
  
End


Impostare un aspetto da noi liberamente disegnato

Paragrafo in costruzione