Question

Ceci est une continuation de ma question initialePourquoi d3d10sdklayers.dll est-il chargé pendant mon jeu DX11? Je crée un jeu DX11 et j'utilise un crochet de touche Windows de bas niveau pour capturer ALT + Entrer afin que je puisse basculer le plein écran en utilisant mes propres méthodes au lieu que Windows le fasse automatiquement, ce qui cause inévitablement des problèmes. Une description de ce processus et des détails est disponible dans la question liée. Mon problème est que le crochet clé cesse de fonctionner régulièrement après le 6ème alt + entre pour une raison quelconque. Je ne le désinscrivez pas moi-même.

Voici le code de crochet clé:


LRESULT _stdcall MyClass::WindowsKeyHook( s32 nCode, WPARAM wParam, LPARAM lParam ) {
    printf("Key hook called, nCode: %d. ", nCode);
    if( nCode < 0 || nCode != HC_ACTION )  { // do not process message 
        return CallNextHookEx( MyClassVar.GetWindowsKeyHook(), nCode, wParam, lParam );
    }
    printf(" Key hook status ok.\n");

    BOOL bEatKeystroke = FALSE;
    KBDLLHOOKSTRUCT* p = ( KBDLLHOOKSTRUCT* )lParam;
    switch( wParam ) {
        //NOTE: Alt seems to be a system key when it is PRESSED, but a regular key when it is released...
        case WM_SYSKEYDOWN:
            if(p->vkCode == VK_MENU || p->vkCode == VK_LMENU || p->vkCode == VK_RMENU) {
                MyClassVar.SetAltPressed(TRUE);
            }
            if(MyClassVar.IsAltPressed() && p->vkCode == VK_RETURN) {
                bEatKeystroke = TRUE;
                MyClassVar.SetAltEnterUsed(TRUE);
                printf("Alt+Enter used.\n");
            }
            break;
        case WM_SYSKEYUP:
            //NOTE: releasing alt+enter causes a SYSKEYUP message with code 0x13: PAUSE key...
            break;
        case WM_KEYDOWN:
            break;
        case WM_KEYUP: {
            if(p->vkCode == VK_MENU || p->vkCode == VK_LMENU || p->vkCode == VK_RMENU) {
                MyClassVar.SetAltPressed(FALSE);
            }
            bEatKeystroke = ( !MyClassVar.IsShortcutKeysAllowed() &&
                                ( p->vkCode == VK_LWIN || p->vkCode == VK_RWIN ) );
            break;
        }
    }

    if( bEatKeystroke ) {
        return 1;
    }
    else {
        return CallNextHookEx( MyClassVar.GetWindowsKeyHook(), nCode, wParam, lParam );
    }
}

Si vous avez besoin de plus d'informations, dites-moi simplement ce qui est nécessaire. Je ne sais pas pourquoi cela se produit, donc je ne sais pas quel type d'informations je dois fournir. La seule façon de se débarrasser d'un crochet clé en plus de la désinscrire explicitement est si Windows le lance, pour autant que je sache. Toutes les méthodes MyClassvar sont en ligne aussi rapidement que possible, et Alt + Entrée est gérée à partir d'un thread séparé.

Était-ce utile?

La solution

La seule façon de se débarrasser d'un crochet clé en plus de la désinscrire explicitement est si Windows le lance, pour autant que je sache.

Ce serait correct, et vous pourriez peut-être confirmer que c'est le chronométrage en augmentant le LowLevelHooksTimeout clé d'enregistrement temporairement.

Il est également possible, mais il est peu probable qu'un autre crochet de clavier soit arrivé en premier et avale toutes les entrées avant que votre crochet ne soit appelé (ce qui est exactement ce que votre crochet essaie de faire avec certaines combinaisons de clés).

D'après votre commentaire, il semble que vous souhaitiez choisir une résolution complète lorsque DXGI passe à l'écran complet pour vous.

Ce qui suit est un extrait de Infrastructure graphique DirectX (DXGI): meilleures pratiques. Ces informations peuvent ou non aider, tout comme le contenu que j'ai éliminé avant cet extrait qui parle de WM_SIZE.

La méthodologie de l'explication précédente suit un chemin très particulier. DXGI définit la résolution complète sur la résolution de bureau par défaut. De nombreuses applications, cependant, passent à une résolution préférée en plein écran. Dans un tel cas, DXGI fournit IDXGISwapChain::ResizeTarget. Cela devrait être appelé avant d'appeler SetFullscreenState. Bien que ces méthodes puissent être appelées dans l'ordre inverse (SetFullscreenState Tout d'abord, suivi de ResizeTarget), cela provoque un supplément WM_SIZE Message à envoyer à la demande. (Cela peut également provoquer un scintillement, car DXGI pourrait être obligé d'effectuer deux modifications de mode.) Après avoir appelé SetFullscreenState, il est conseillé d'appeler ResizeTarget encore avec le RefreshRate le membre a été zéro. Cela équivaut à une instruction de non-opération dans DXGI, mais cela peut éviter les problèmes avec le taux de rafraîchissement, qui sont discutés ensuite.

La Présentation DXGI a plus d'informations sur la question, que ResizeTarget pourrait ne pas être aussi utile que l'on l'espérerait: ce serait:

Par défaut, DXGI choisit la sortie qui contient la majeure partie de la zone client de la fenêtre. Il s'agit de la seule option disponible pour DXGI lorsqu'elle va elle-même en réponse à Alt-Enter.

Cependant, il mentionne que la taille est déterminée par la zone client de la fenêtre. Peut-être que tu veux Limiter la zone client, au lieu d'installer un crochet clavier?

Autres conseils

Avez-vous essayé de désactiver le crochet de DXGI?

IDXGISwapChain::MakeWindowAssociation( DXGI_MWA_NO_WINDOW_CHANGES )

Aussi, créer le swapchain avec DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH Fongera DXGI à trouver le mode d'affichage qui correspond le mieux à la taille de votre fenêtre. Si vous avez déjà resizetarget () ed à 640x480, et qu'il y a au moins un mode 640x480 disponible, vous devriez l'obtenir. Vous obtiendrez alors un WM_Size à 640x480, c'est votre opportunité d'appeler ResizeBuffers. Si ResizeBuffers est appelé comme celui-ci, après le commutateur de mode, il permettra de filiser la page (les nouveaux dossiers doivent être associés au moniteur, ou le système ne peut pas dire directement). Si le flux de page n'est pas activé comme celui-ci, tous les appels actuels invoqueront une opération BLT qui sucera la bande passante que vous n'avez pas besoin de dépenser.

Notez que vous pouvez ou non obtenir 640x480. Si l'affichage est tourné, par exemple, vous obtiendrez probablement le prochain mode qui contiendra 640x480 qui sera probablement 768x1024. Si vous voulez bien travailler sur des écrans tournés, vous pouvez surveiller vous-même et la boîte aux lettres vous-même dans le rapport d'aspect 4x3 que vous souhaitez.

Mais il est généralement la meilleure pratique de laisser DXGI choisir le mode d'affichage, car il existe de nombreuses raisons pour lesquelles le mode de bureau pourrait être le meilleur. L'utilisateur pourrait avoir connecté le Puter à un projecteur qui ne peut faire que ce seul mode. Certains LCD présenteront le 640x480 à la résolution native, c'est-à-dire un teint tampon postal au milieu du moniteur. Idéalement, vous devez coder votre application pour pouvoir regarder assez essentiellement n'importe quelle résolution, mais au moins à des rapports d'aspect 4x3, 3x4, 6x9 et 9x6.

Happy Coding -Jeff

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top