PDA

View Full Version : [VB 6] Spostare il puntatore del mouse


wingman87
28-04-2006, 22:37
Ciao, vorrei sapere se è possibile spostare il puntatore del mouse da codice e come fare. Grazie!

mynos79
29-04-2006, 09:07
Certo che si può spostare il cursore del mouse tramite codice.

Innanzitutto bisogna inserire nel form oppure meglio in un modulo la seguente dichiarazione:

Declare Sub SetCursorPos Lib "User32" (ByVal X As Integer, ByVal Y As Integer)

Mentre nel form basta inserire la seguente chiamata:

SetCursorPos 20, 20

che sposterà il mouse alle coordinate (20, 20) a partire dall' angolo in alto a sinistra dello schermo.




Per spostare invece il mouse con le coordinate riferite alla finestra form o a un controllo particolare, bisogna dichiarare in un modulo le seguenti dichiarazioni:

Type POINTAPI
x As Long
y As Long
End Type
Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long
Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long

Mentre nel progetto:

Private Sub Command1_Click()
MoveMouse 300, 450
End Sub

Sub MoveMouse(x As Single, y As Single)
Dim pt As POINTAPI
pt.x = x
pt.y = y
ClientToScreen hwnd, pt
SetCursorPos pt.x, pt.y
End Sub

La funzione ClientToScreen serve per ancorare le coordinate al controllo passato tramite la proprietà hwnd (in questo caso il form).

wingman87
29-04-2006, 19:55
Grazie mille! Adesso non ho tempo, ma domani lo provo! :)

wingman87
30-04-2006, 19:24
Ce l'ho fatta, non pensavo fosse così semplice, grazie!
Ora xò vorrei chiederti un'altra cosa, come faccio a far vedere che il programma è in esecuzione ed eventualmente dare la possibilità di chiuderlo mettendo un'iconcina tipo quella della connessione in basso a destra? In pratica voglio che abbia un'iconcina a fianco dell'orologio..
So che non c'entra col resto ma mi serve x lo stesso programma.. Grazie!

wingman87
30-04-2006, 19:31
Mi è venuta in mente anche un'altra cosa, c'è un evento mouse_move che viene attivato quando muovo il mouse anche all'esterno del form? X ora uso un timer x rilevare dove si trova il mouse e poi faccio di conseguenza quello che mi serve ma non so se è la soluzione ottimale.. Il massimo è che fosse attivato l'evento solo quando il mouse si trova in un certo punto ma non so se è possibile..

mynos79
30-04-2006, 20:20
Icona nella system tray

Non è difficile ma un po' lungo da fare ...
Innanzitutto bisogna dichiarare delle dichiarazioni di costanti e della funzione Shell_NotifyIcon in un modulo:

Public Const WM_LBUTTONDBLCLICK = &H203
Public Const WM_RBUTTONUP = &H205
Public Const WM_MOUSEMOVE = &H200
Public Const NIM_ADD = &H0
Public Const NIM_MODIFY = &H1
Public Const NIM_DELETE = &H2
Public Const NIF_MESSAGE = &H1
Public Const NIF_ICON = &H2
Public Const NIF_TIP = &H4

Public Type NOTIFYICONDATA
cbSize As Long
hwnd As Long
uId As Long
uFlags As Long
ucallbackMessage As Long
hIcon As Long
szTip As String * 64
End Type

Public VBGTray As NOTIFYICONDATA

Declare Function Shell_NotifyIcon Lib "shell32" Alias _
"Shell_NotifyIconA" (ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean

Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Poi nel form, nell' esempio che ti sto facendo, ho messo un pulsante Command1 e devi inserire questo codice (faccio prima a scrivertelo che a spiegarti passo per passo, non è difficile da capire comunque):

Private Sub GoSystemTray()
VBGTray.cbSize = Len(VBGTray)
VBGTray.hwnd = Me.hwnd
VBGTray.uId = vbNull
VBGTray.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
VBGTray.ucallbackMessage = WM_MOUSEMOVE

VBGTray.hIcon = Me.Icon
' Tooltip
VBGTray.szTip = Me.Caption & vbNullChar
Call Shell_NotifyIcon(NIM_ADD, VBGTray)
App.TaskVisible = False ' rimuovi applicazione dalla taskbar
Me.Hide
End Sub

Private Sub Command1_Click()
Call GoSystemTray
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Static lngMsg As Long
Static blnFlag As Boolean
Dim result As Long

lngMsg = X / Screen.TwipsPerPixelX
If blnFlag = False Then
blnFlag = True
Select Case lngMsg
' doppio click
Case WM_LBUTTONDBLCLICK
Me.Show
' tasto destro
Case WM_RBUTTONUP
result = SetForegroundWindow(Me.hwnd)
' apertura menù
Me.PopupMenu mnuSystemTray
End Select
blnFlag = False
End If
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
VBGTray.cbSize = Len(VBGTray)
VBGTray.hwnd = Me.hwnd
VBGTray.uId = vbNull
Call Shell_NotifyIcon(NIM_DELETE, VBGTray)
End Sub

Devi quindi creare un menù con l' editor dei menù di nome (proprietà name non caption) mnuSystemTray (puoi cambiarlo, ma ricordati di modificare anche il codice) e impostalo come non visibile (visible = false dall' editor).
Naturalmente puoi inserire tutti gli elementi che vuoi nel menù ... e ricordati quindi di scrivergli anche il relativo codice :D
Per ridurre a icona nella system tray basta chiamare la funzione:

Call GoSystemTray

come ho fatto nel codice del pulsante.

Mi raccomando, quando esci dal programma rimuovi sempre l' icona e scarica tutto :p come ho fatto nella QueryUnload ...

mynos79
30-04-2006, 20:25
MouseMove fuori dai controlli

L' evento MouseMove è proprio dei vari controlli (form incluso) ... al di fuori del form non c'è nessun controllo con quest' evento; quindi per controllare il mouse al di fuori dell' applicazione, l' unico modo (che conosco, posso sbagliarmi) è quello di monitorare il puntatore tramite le sue coordinate e gestire gli spazi in maniera personalizzata.
Oppure, dipende sempre dai casi e da cosa stai facendo, puoi usare la proprietà hwnd dei vari controlli (sia dell' applicazione tua, che di qualsiasi controllo di qualsiasi applicazione attiva presente in windows); in pratica l' hwnd indica il numero del controllo creato in windows (è una proprietà che da windows in fase di creazione del controllo e dell' applicazione; e può essere utile per gestire controlli di altre applicazioni ... ad esempio usanto il SendMessage puoi dal codice della tua applicazione scrivere delle parole nel blocco note e salvare anche, senza mai entrare nel blocco note).

wingman87
01-05-2006, 12:09
Mmm, quindi il metodo che ho usato io, e cioè un timer x monitorare la posizione del mouse dovrebbe andar bene? E' che mi sembra uno spreco tenere in funzione sto timer continuamente.. boh..
Comunque il programma finito (solo grazie a te), è questo in allegato!
E' stupidissimo ma volevo farlo..


Ok, ora non mi picchiare! :D

Ps: se non hai capito cosa fa prova a muovere il mouse un po' dappertutto..

mynos79
01-05-2006, 13:05
Ah ah ah ... impressionante come l' ingegneria del software sia progredita in questi ultimi anni :D :ciapet:

Comunque se volevi fare un programmino "scherzoso" ... potevi aggiungerci la possibilità di nascondere casualmente il pulsante start oppure l' orologio o chissà cos' altro :p con qualche chiamata api fai di tutto.

Cmq l' uso del timer non è uno spreco ... è l' unico modo per avere una funzione indipendente dal flusso del programma ...

wingman87
01-05-2006, 20:43
Ok, è che pensavo che tenere un timer con intervallo così basso consumasse molte risorse.. Grazie ancora!

mynos79
02-05-2006, 08:18
Beh, ma a quanto tieni l' intervallo del timer? per controllare semplicemente il mouse puoi anche metterlo a 250ms (un quarto di secondo), non serve che tieni 1ms ... cmq se il tuo programma non fa altro, anche se lo tieni a 1ms non consuma chissacchè, anche perchè non memorizzi nulla in variabili o array dinamici da consumare chissà quale memoria ... più che altro impegni costantemente un pelino la cpu, ma solo un pelino visto che hai solo un paio di coordinate da controlloare ...

wingman87
02-05-2006, 14:28
Lol, lo tengo proprio a 1 ms.. :D

wingman87
02-05-2006, 14:48
Ho trovato una cosa molto interessante, l'evento mouse!! Guarda qui:
http://www.allapi.net/apilist/mouse_event.shtml
L'ho già provato e funziona alla grande!