2017-10-16 5 views
1

Je tente de ne pas désactiver une fenêtre sous certaines conditions d'utilisation EnableWindow(hWnd, false);EnableWindow (hWnd, false) ne désactive l'entrée du clavier

Selon the documentation, cela devrait « désactiver l'entrée de la souris et du clavier à la fenêtre spécifiée ». Le problème que je vois est que, en fait, il est désactivé comme il le dit, sauf si le curseur est actuellement à l'intérieur d'une zone de texte dans la fenêtre et que la fenêtre a le focus qui n'est pas désactivé. Je pensais à faire une sorte de code pour enlever l'attention de la fenêtre.

Existe-t-il une meilleure façon de procéder?

Remarque: La fenêtre désactivée est une ligne binaire exécutée via _spawnl().

+0

Je pense que vous devrez utiliser '' EnumChildWindows' appeler EnableWindow' sur chaque fenêtre enfant – stackptr

+4

Non, vous ne besoin de désactiver chaque fenêtre enfant, la désactivation d'une fenêtre parent désactive l'entrée pour toutes les fenêtres enfants. Toutefois, l'utilisation de 'EnableWindow()' à travers les limites de processus n'est pas une bonne chose à faire en général. –

Répondre

2

Je ne suis pas sûr si c'est une fonctionnalité de Windows ou un bogue. De toute façon, désactiver la fenêtre de premier plan n'est pas une bonne idée.

Si vous êtes en mesure de modifier le programme vous commencez par _spawnl() alors c'est une meilleure solution. Vous pourriez le faire répondre à WM_APP ou quelque chose comme ça quand vous avez besoin de le contrôler.

S'il s'agit d'une application tierce, il vous reste des hacks.

Vous pouvez essayer de modifier la fenêtre de premier plan avec SetForegroundWindow mais cela ne fonctionnera que si vous le faites très rapidement après _spawnl() avant que votre thread ne perde le verrou de premier plan. En utilisant LockSetForegroundWindow avant _spawnl() pourrait être en mesure de vous aider à garder le verrou plus longtemps. Il y a aussi d'autres hacks pour changer l'avant-plan avec AttachThreadInput etc.

Si vous ne voulez pas changer l'avant-plan, j'ai pu trouver une solution de contournement:

ShellExecute(NULL, NULL, TEXT("Notepad"), NULL, NULL, SW_SHOW); 
    Sleep(2000); 
    HWND hNP = FindWindow(TEXT("Notepad"), NULL); 
    Sleep(2000); // Start typing in Notepad now... 
    if (hNP) 
    { 
    DWORD tid = GetWindowThreadProcessId(hNP, NULL); 
    GUITHREADINFO gti; 
    gti.cbSize = sizeof(gti); 
    if (tid && GetGUIThreadInfo(tid, &gti)) 
    { 
     HWND hChild = NULL; 
     if (gti.hwndFocus != hNP && gti.hwndFocus) 
     { 
     EnableWindow(hChild = gti.hwndFocus, false); 
     } 
     if (GetForegroundWindow() == hNP) 
     { 
     SendNotifyMessage(hNP, WM_ACTIVATE, WA_INACTIVE, NULL); 
     SendNotifyMessage(hNP, WM_ACTIVATE, WA_ACTIVE, NULL); 
     SendNotifyMessage(hNP, WM_SETFOCUS, NULL, NULL); 
     // SendNotifyMessage(hNP, WM_NCACTIVATE, false, NULL); // Uncomment to make it look like it is inactive 
     } 
     EnableWindow(hNP, false); 
     if (hChild) 
     { 
     EnableWindow(hChild, true); 
     } 
    } 
    MessageBox(NULL, TEXT("Done?"), NULL, MB_TOPMOST); 
    SetForegroundWindow(hNP); 
    PostMessage(hNP, WM_CLOSE, 0, 0); 
    } 

Ceci est certainement pas optimale , il laisse Notepad dans un état où il semble être activé mais ce n'est vraiment pas le cas. L'idée est de désactiver la fenêtre enfant ciblée et de déclencher un faux changement d'activation et de forcer le focus à changer. Il pourrait ne pas fonctionner avec d'autres applications, qui sait.

Si vous êtes prêt à risquer une impasse, vous pouvez le faire à la place:

DWORD tid = GetWindowThreadProcessId(hNP, NULL); 
    GUITHREADINFO gti; 
    gti.cbSize = sizeof(gti); 
    if (tid && GetGUIThreadInfo(tid, &gti)) 
    { 
     if (GetForegroundWindow() == hNP) 
     { 
     if (AttachThreadInput(GetCurrentThreadId(), tid, true)) 
     { 
      SetFocus(NULL); 
      AttachThreadInput(GetCurrentThreadId(), tid, false); 
     } 
     } 
     EnableWindow(hNP, false); 
    } 
+0

Donc, cette deuxième partie a bien fonctionné, je suis curieux de savoir pourquoi vous risquez une impasse. –

+1

@RyanBoykin https://blogs.msdn.microsoft.com/oldnewthing/20130607-00/?p=4143/# https://blogs.msdn.microsoft.com/oldnewthing/20130619-00/?p=4043# etc. – Anders