0

これは私の最初の質問の続き です。DX11 ゲーム中に D3D10SDKLayers.dll が読み込まれるのはなぜですか? 私は DX11 ゲームを作成しており、低レベルの Windows キー フックを使用して Alt+Enter をキャプチャしているため、必然的に問題が発生する Windows に自動的に行わせるのではなく、独自の方法を使用してフルスクリーンを切り替えることができます。このプロセスの説明と詳細は、リンクされた質問で入手できます。私の問題は、なんらかの理由で 6 回目の Alt+Enter の後、キーフックが一貫して機能しなくなることです。私は自分で登録を解除していません。

キーフックのコードは次のとおりです。


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 );
    }
}

さらに情報が必要な場合は、必要なものを教えてください。なぜこれが起こっているのかわからないので、どのような情報を提供する必要があるのか​​ わかりません. 私の知る限り、キーフックを明示的に登録解除する以外にキーフックを取り除く唯一の方法は、Windows がタイムアウトした場合です。すべての MyClassVar メソッドはインラインで可能な限り高速になり、Alt+Enter は別のスレッドから処理されます。

4

2 に答える 2

2

私の知る限り、キーフックを明示的に登録解除する以外にキーフックを取り除く唯一の方法は、Windows がタイムアウトした場合です。

それは正しく、レジストリ キーを一時的に増やすことで、LowLevelHooksTimeoutタイムアウトしていることを確認できる場合があります。

それも可能ですが、フックが呼び出される前に別のキーボードフックが最初にそこに到達し、すべての入力を飲み込んでいる可能性は非常に低いです (これは、フックが特定のキーの組み合わせでやろうとしていることとまったく同じです)。

あなたのコメントから、DXGI がフルスクリーンに切り替わるときにフルスクリーン解像度を選択したいようです。

以下は、 DirectX Graphics Infrastructure (DXGI): Best Practicesからの抜粋です。この情報は役立つかもしれないし、役に立たないかもしれませんWM_SIZE

前述の説明の方法論は、非常に特殊な道をたどります。DXGI は、デフォルトで全画面解像度をデスクトップ解像度に設定します。ただし、多くのアプリケーションは、推奨される全画面解像度に切り替えます。そのような場合、DXGI は を提供しますIDXGISwapChain::ResizeTarget。これは、 を呼び出す前に呼び出す必要がありますSetFullscreenState。これらのメソッドは逆の順序で呼び出すこともできますが (SetFullscreenState最初にを呼び出し、次に を呼び出しますResizeTarget)、そうすると余分なWM_SIZEメッセージがアプリケーションに送信されます。(そうすると、ちらつきが発生する可能性もあります。DXGI は 2 つのモード変更を強制的に実行する可能性があるためです。) を呼び出した後、メンバーをゼロにして再度SetFullscreenState呼び出すことをお勧めします。これは、DXGI では無操作命令に相当しますが、次に説明するリフレッシュ レートの問題を回避できます。ResizeTargetRefreshRate

DXGIの概要には、この問題に関する詳細情報がいくつかありResizeTargetますが、期待するほど役に立たない可能性があります。

既定では、DXGI は、ウィンドウのクライアント領域の大部分を含む出力を選択します。これは、alt-enter に応答して DXGI 自体が全画面表示になったときに DXGI で使用できる唯一のオプションです。

ただし、サイズはウィンドウのクライアント領域によって決定されることに言及しています。おそらく、キーボードフックをインストールする代わりに、クライアント領域を制限したいですか?

于 2012-01-26T22:10:38.707 に答える