Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Urgente: confinare il cursore in un form.

Ho urgente bisogno di risolvere un problema.
Devo fare in modo che, all'apertura di un certo form, il puntatore del mouse
rimanga confinato al suo interno fino alla chiusura.
Tutto ciň SENZA usare il rilevamento periodico (timer) del puntatore con
GetCursorPos per poi spostarlo ad es. al centro con SetCursorPos.
Tempo fa avevo un esempio di come confinarlo in un controllo, ma ora non lo
trovo piů.
Grazie a chi mi risponderŕ.

 GetCursorPos per poi spostarlo ad es. al centro con SetCursorPos.
puoi usare l'API ClipCursor, passandogli il RECT in cui vuoi confinare il
puntatore. la dichiarazione la trovi nell'API Viewer, la documentazione su
MSND o su MSND OnLine (
http://msdn.microsoft.com
)
Ciao
Faber




> Guarda anche sul sito comune, che c'č proprio l'esempio che fa per te
Grazie, ma non l'ho trovato!  :o(
Sono orbo ?

 End Sub
potresti fare cosě:
(non l'ho provato ma credo proprio che funzioni)
Private Declare Function GetWindowRect Lib "user32" Alias _
GetWindowRect" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Sub cmdImprigiona_Click()
    Dim Rettangolo As Rect
    GetWindowRect Me.hWnd, Rettangolo
    ClipCursor Rettangolo
End Sub
Ciao
Faber
P.S.: per l'ultima parte, puoi usare la divisione intera (\) invece di
quella normale (/)

 puntatore
Grazie !
Devo dire che l'MSDN non mi è sembrato molto chiaro in proposito, però me la
sono cavata.
Per chi fosse interessato, nel seguito c'è il codice per un esempietto
"presto fatto".
E' sufficiente fare un piccolo form con un pulsante di nome cmdImprigiona e
un pulsante di nome cmdLibera, quindi copiare il seguente codice:
Option Explicit
Private Declare Function ClipCursor Lib "user32" (lpRect As Any) As Long
Private Type Rect
    left As Long
    top As Long
    right As Long
    bottom As Long
End Type
Private Sub cmdImprigiona_Click()
    Dim Rettangolo As Rect
    Rettangolo.left = Me.left / Screen.TwipsPerPixelX
    Rettangolo.top = Me.top / Screen.TwipsPerPixelY
    Rettangolo.right = (Me.left + Me.Width) / Screen.TwipsPerPixelX
    Rettangolo.bottom = (Me.top + Me.Height) / Screen.TwipsPerPixelY
    ClipCursor Rettangolo
End Sub
Private Sub cmdLibera_Click()
    Dim Rettangolo As Rect
    Rettangolo.left = 0
    Rettangolo.top = 0
    Rettangolo.right = Screen.Width / Screen.TwipsPerPixelX
    Rettangolo.bottom = Screen.Height / Screen.TwipsPerPixelY
    ClipCursor Rettangolo
End Sub
ALOHA !
Rogis
* ANTI-SPAM:
Rimuovi "ABC" dall'indirizzo per rispondermi
Remove "ABC" from my address to reply.


Dunque, la tua "variante" non mi funziona. Mi dà il seguente messaggio di
errore:
"Impossibile trovare il punto di ingresso della DLL GetWindowRect in
User32".
La divisione "\" funziona.
In generale: non capisco perchè, se sposto il form dopo aver imprigionato il
cursore, quest'ultimo risulta di nuovo "libero"!!!
Ciao.

 cursore, quest'ultimo risulta di nuovo "libero"!!!
è vero, l'ho notato anch'io... succede anche se clicchi sul bordo del form.
funziona bene, invece, se il rettangolo lo imposti
+ in giù
+ a destra
- largo
- alto
(in modo da impedire al puntatore di arrivare ai bordi)
Ciao
Faber

 - alto
Con questo codice (meno alto di 22 pixel, per escludere la barra del
titolo):
Private Sub cmdImprigiona_Click()
    Dim Rettangolo As Rect
    Rettangolo.left = Me.left \ Screen.TwipsPerPixelX
    Rettangolo.top = Me.top \ Screen.TwipsPerPixelY + 22
    Rettangolo.right = (Me.left + Me.Width) \ Screen.TwipsPerPixelX
    Rettangolo.bottom = (Me.top + Me.Height) \ Screen.TwipsPerPixelY
    ClipCursor Rettangolo
End Sub
ho risolto il problema. Naturalmente cosě facendo non si puň utilizzare
l'istruzione piů semplice "GetWindowRect Me.hwnd, Rettangolo" che mi hai
suggerito.
Perň non ho capito cosa intendi con
+ in giů
+ a destra
 - largo
Ciao!

  - largo
con "+ in giů" intendo proprio ciň che hai fatto tu: aggiungere alla
proprietŕ Top del rettangolo un valore  :)
ma funziona anche se clicchi sul bordo destro o sinistro?
Ciao
Faber

suggerito.
AAArrrgghh!! Orrore! e se io ho la barra impostata a 20 o 24? non mi
funziona piů???
Usa la GetClientRect() cosě otterrai il rettangolo della sola client-area,
senza bordi.
Ciao.

> ma funziona anche se clicchi sul bordo destro o sinistro?
Sì, funziona benissimo.
L'unico ulteriore accorgimento da prendere e l'eliminazione del ControlBox,
altrimenti l'utente può aprire il menù con i comandi dalla tastiera.
Peccato che la proprietà "Moveable" non sia modificabile in runtime.
Ciao.

 senza bordi.
UUUrrrgghh!!!
La funzione "GetClientRect" dell'API restituisce le coordinate dell'area
client di una finestra, ma le riferisce all'area client stessa, col
risultato che il rettangolo ottenuto č piazzato nell'angolo in alto a
sinistra dello schermo.
Bastava leggersi "Win32 Programmer's Reference"............
"The GetClientRect function retrieves the coordinates of a window's client
area. GetClientRect fills a RECT structure with the coordinates of the upper
left and lower right corners of the client area, but the coordinates are
relative to the client area itself. This means the coordinates of a client
area's upper left corner are always (0,0), and the coordinates of the lower
right corner are the width and height of the client area. "
......ma puň darsi che mi sbagli!
Ciao     :o)

Usa il subclassing, se sai come si fa. Sennň dillo e te lo spoego

> Usa il subclassing, se sai come si fa. Sennò dillo e te lo spoego
Me lo spiegheresti?
:o)

Bastava leggersi "Win32 Programmer's Reference"............
Ok, ho dato una risposta affrettata, ma questo non č una scusa per scrivere
del cattivo codice.
Usa l'API GetSystemMetrics() con
SM_CXBORDER,
SM_CYBORDER,
SM_CYCAPTION
per conoscere le dimensioni di bordo e caption.
Ciao