2016-09-24 2 views
-2

j'ai un processus qui établit une SetWindowsHookEx (WH_MOUSE_LL,,,) crochet clic droit. Mon processus est réglé sur le système DPI sur la fenêtre 10.0.10586 avec une mise à l'échelle de 150% sur les deux moniteurs. Cela a été défini en appelant SetProcessDpiAwareness (PROCESS_SYSTEM_DPI_AWARE).mise à l'échelle haute DPI, crochets de souris et WindowFromPoint

Mon scénario de problème est par exemple Office 2007 n'est pas reconnu par DPI, plaçons MS Word dans le bon quart de l'écran. Clic droit juste au-dessus de la barre des tâches en bas à droite et le crochet de la souris envoie les coordonnées de 1279, 675 - mis à l'échelle de Word. Ensuite, je fais un clic droit sur Visual Studio (DPI), près des trois quarts à travers l'écran et le crochet de la souris m'envoie des coordonnées de par exemple. 1279, 1008 de Visual Studio. Donc, si je cliquais plus haut sur l'écran, j'aurais potentiellement le même 1279, 675.

Mon processus tente de déterminer quelle fenêtre est au point en appelant l'API WindowFromPoint, mais cela échouera clairement dans ce scénario comme deux les applications "partagent" le même point.

Est-il possible de forcer le crochet de la souris pour toujours envoyer les coordonnées physiques brutes au lieu de ceux mis à l'échelle de l'application pas au courant DPI? et si oui, comment? Alternativement, existe-t-il un autre moyen de déterminer le hWnd ou processID à partir des crochets de la souris?

Répondre

-1

Parce que le processus est conscient DPI, appelant GetCursorPos() dans le gestionnaire de rappel du crochet de la souris récupère toujours coordonnées physiques brut à la place de coordonnées logiques mises à l'échelle de l'application. Il suffit de rejeter les coordonnées transmises au rappel de la souris.

Ajouté 30/09/2016

Il ne vaut rien que si GetMessagePos semble probable, le candidat ne retourne que les coordonnées correctes si le processus ne résolution ppp virtualisé.

par exemple.

VOID MessagePump() 
{ 
    MSG  messageGet = { 0 }; 
    DWORD dwPos; 
    POINTS p; 

    while (GetMessage(&messageGet,NULL,0,0)) 
    { 
     dwPos = GetMessagePos(); 
     p = MAKEPOINTS(dwPos); 
     TranslateMessage(&messageGet); 
     DispatchMessage(&messageGet); 
    } 
} 

Le gestionnaire de rappel de la souris est appelée pendant l'appel GetMessage(), mais cela ne va pas chercher les coordonnées physiques correctes DPI où la virtualisation est active pour le processus. par exemple. physique x = 1909, y = 1072 revient à 1091, 612 avec une mise à l'échelle de 175%, ce qui, bien qu'arithmétiquement correct, n'est pas ce qui était requis.

+0

Cela ressemble à une mauvaise idée. Le curseur peut être ailleurs au moment où vous appelez GetCursorPos. –

+0

C'est le meilleur que je peux penser jusqu'à présent, et semble être presque instantané, mais je suis ouvert à de meilleures suggestions. – birdwes

+1

[GetMessagePos] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms644938.aspx) est probablement un meilleur ajustement. – IInspectable