Aggancia il mouse per catturare eventi all'esterno di un'applicazione

Scopri come tenere traccia dell'attività del mouse anche quando l'applicazione Delphi non è attiva, si trova nella barra delle applicazioni o non ha alcuna interfaccia utente.

Installando un hook di sistema (o globale) a livello di sistema è possibile monitorare ciò che l'utente sta facendo con il mouse e agire di conseguenza.

Cos'è un gancio e come funziona?

In breve, un hook è una funzione (callback) che puoi creare come parte di una DLL (libreria di collegamento dinamico) o della tua applicazione per monitorare gli "avvenimenti" all'interno del sistema operativo Windows.
Esistono 2 tipi di hook: globale e locale. Un hook locale monitora le cose che accadono solo per un programma specifico (o thread). Un hook globale monitora l'intero sistema (tutti i thread).

Per creare un hook globale sono necessari 2 progetti, 1 per creare il file eseguibile e 1 per creare una DLL contenente la procedura hook.

Il nostro articolo su come lavorare con gli hook di tastiera di Delphi spiega come intercettare l'input da tastiera per i controlli che non possono ricevere lo stato attivo (come TImage).

Agganciare il mouse

In base alla progettazione, il movimento del mouse è limitato dalle dimensioni dello schermo del desktop (inclusa la barra delle applicazioni di Windows). Quando si sposta il mouse sul bordo sinistro / destro / superiore / inferiore, il mouse si "fermerà" - come previsto (se non si dispone di più di un monitor).

Ecco un'idea per l'hook del mouse a livello di sistema: se, ad esempio, vuoi spostare il mouse sul lato destro dello schermo quando si sposta verso il bordo sinistro (e "lo tocca"), potresti scrivere un hook globale del mouse per riposizionare il puntatore del mouse.

Si inizia creando un progetto di libreria a collegamento dinamico. La DLL dovrebbe esportare due metodi: "HookMouse" e "UnHookMouse".

La procedura HookMouse chiama il SetWindowsHookEx API che passa "WH_MOUSE" per il primo parametro, installando così una procedura hook che monitora i messaggi del mouse. Uno dei parametri di SetWindowsHookEx è la funzione di richiamata che Windows chiamerà quando è necessario elaborare un messaggio del mouse:

SetWindowsHookEx (WH_MOUSE, @HookProc, HInstance, 0);

L'ultimo parametro (valore = 0) in SetWindowsHookEx definisce che stiamo registrando un hook globale.

HookProc analizza i messaggi relativi al mouse e invia un messaggio personalizzato ("MouseHookMessage") al nostro progetto di test:

 funzione HookProc (nCode: Integer; MsgID: WParam; Dati: LParam): LResult; stdcall;

var

    mousePoint: TPoint;

    notifyTestForm: booleano;

    MouseDirection: TMouseDirection;

 inizio

    mousePoint: = PMouseHookStruct (Data) ^. pt;

 

    notifyTestForm: = false;

 

    Se (mousePoint.X = 0) poi

    inizio

      Windows.SetCursorPos (-2 + Screen.Width, mousePoint.y);

      notifyTestForm: = true;

      MouseDirection: = mdRight;

    fine;

...
  
Se notifyTestForm poi

    inizio

      PostMessage (FindWindow ('TMainHookTestForm', zero), MouseHookMessage, MsgID, Integer (MouseDirection));

    fine;

   Risultato: = CallNextHookEx (Hook, nCode, MsgID, Data);
fine;

Mancia: Leggi i file della Guida dell'SDK Win32 per scoprire il record PMouseHookStruct e la firma della funzione HookProc.

Nota: Una funzione hook non deve inviare nulla da nessuna parte - la chiamata PostMessage viene utilizzata solo per indicare che la DLL può comunicare con il mondo "esterno".

Gancio per mouse "Listener"

Il messaggio "MouseHookMessage" viene pubblicato nel progetto di test, un modulo denominato "TMainHookTestForm". Sostituirai il metodo WndProc per ottenere il messaggio e agire come necessario:

 procedura TMainHookTestForm.WndProc (var Messaggio: TMessage);

inizio

    ereditato WndProc (messaggio);

  
Se Message.Msg = HookCommon.MouseHookMessage poi

    inizio

      // implementazione trovata nel codice di accompagnamento

      Signal (TMouseDirection (Message.LParam));

    fine;

fine;

Naturalmente, quando viene creato il modulo (OnCreate) si chiama la procedura HookMouse dalla DLL, quando viene chiuso (OnDestroy) si chiama la procedura UnHookMouse.

Nota: gli hook tendono a rallentare il sistema perché aumentano la quantità di elaborazione che il sistema deve eseguire per ciascun messaggio. È necessario installare un gancio solo quando necessario e rimuoverlo il prima possibile.