2009-08-25 17 views
6

Ho problemi a far funzionare un hook di sistema globale. Voglio essere avvisato ogni volta che una finestra si muove, il prima possibile, e cambiare le dimensioni della finestra. Ciò significa che il gancio CBT HCBT_MOVESIZE non lo taglierà, succede solo dopo che la finestra è stata spostata. Voglio agganciare il movimento effettivo della finestra e poter modificare le dimensioni della finestra durante lo spostamento.Intercettazione globale movimento finestra

Gli hook sono impostati da una DLL e la funzione di callback si trova all'interno di tale DLL. Questo è quello che ho provato.

  • WH_CALLWNDPROC. Mi avvisa quando viene spostata una finestra (WM_MOVING viene ricevuta per Windows da altre applicazioni), ma non posso modificare il contenuto del messaggio.
  • WH_CALLWNDPROCRET Uguale a WH_CALLWNDPROC.
  • gancio CBT HCBT_MOVESIZE. L'evento accade fino a tardi.
  • WH_GETMESSAGE. Mai ricevere WM_MOVE, WM_MOVING o WM_WINDOWPOSCHANGING. Questo hook mi permetterebbe di cambiare i messaggi.

Aggiornamento: ganci eventi di Windows sembrano consentire me per catturarlo:

hWinEventHook = SetWinEventHook(EVENT_SYSTEM_MOVESIZESTART,  
    EVENT_SYSTEM_MOVESIZEEND, NULL, WinEventProc, 
    0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); 

Tuttavia, questo crea un problema diverso: la modifica della dimensione della finestra utilizzando SetWindowPos() non funziona (cambia dimensione va bene, ma torna immediatamente alla sua dimensione precedente), anche se io uso SWP_NOSENDCHANGING. Idee?

Aggiornamento 2: la sottoclasse sembra funzionare, tuttavia Visual Studio si arresta in modo anomalo dopo l'esecuzione di ciascun programma (analogamente a molte altre finestre). Funziona bene se metto dei punti di interruzione e percorro il "disassociato", ma non quando lascio girare il programma da solo. Idee?

Ho un gancio CBT (che c'era da prima), e quando HCBT_ACTIVATE viene inviato per una nuova finestra, rimuovere eventuali sottoclassi precedente mediante SetWindowLongPtr() (questo deve funzionare su 64 bit pure), e quindi sottoclasse la nuova finestra Se metto un breakpoint ovunque e riprendo immediatamente la sessione quando si rompe, tutto funziona correttamente. Tuttavia, quando non ho alcun punto di interruzione, Visual Studio si arresta in modo anomalo quando il programma viene chiuso.

risposta

1

Hm, avrei pensato che HCBT_MOVESIZE è esattamente ciò che si vuole, dato che il MSDN dice questo circa CBT ganci:

The system calls this function before activating, creating, destroying, 
minimizing, maximizing, moving, or sizing a window.

ed in particolare:

HCBT_MOVESIZE 
    A window is about to be moved or sized.

(queste citazioni sono stati presi da http://msdn.microsoft.com/en-us/library/ms644977%28VS.85%29.aspx)

... quindi avrei pensato di ottenere la chiamata HCBT_MOVESIZE in tempo. La funzione hook che gestisce HCBT_MOVESIZE è anche in grado di restituire un intero in modo che il sistema possa determinare se l'operazione è consentita o deve essere impedita. Quindi, dato che l'hook HCBT_MOVESIZE dovrebbe avere un'opzione per impedire l'operazione, direi che viene chiamata prima che si verificasse l'evento move.

Sei davvero sicuro che la funzione di aggancio si chiami dopo l'evento di spostamento?Se si esegue una chiamata GetWindowRect sull'handle specifico all'interno della funzione hook, il valore restituito è uguale al rettangolo passato alla funzione hook?

+0

Cosa succede con "HCBT_MOVESIZE' è che l'utente può iniziare a trascinare la finestra, continuare a trascinarla e la notifica non arriva prima che lasci andare la finestra. Tuttavia, ricevi la notifica prima che la finestra venga spostata tecnicamente, ma è comunque abbastanza inutile. –

1

Gli ami sono piuttosto pesanti. Vuoi solo usarli quando devi assolutamente.

Detto questo, è possibile utilizzare uno dei ganci di base semplicemente come un modo per entrare nel processo. Una volta nel processo, potresti sottoclassi la finestra che ti interessa e gestire i messaggi di dimensionamento nella proc della sottoclasse piuttosto che cercare di catturare tutto a livello di hook.

A seconda di ciò che si desidera fare in risposta al ridimensionamento, potrebbe essere necessaria una comunicazione interprocesso.

+0

La sottoclasse sembra essere il modo per andare qui. Tuttavia, Visual Studio si blocca sempre quando non eseguo la rimozione effettiva della sottoclasse. –

Problemi correlati