这是我原来的问题的延续 Why is D3D10SDKLayers.dll loaded during my DX11 game?我正在创建一个DX11游戏,并使用一个低级别的Windows键来捕获Alt + Enter,这样我就可以使用我自己的方法切换全屏而不是让Windows自动执行它,这不可避免地会导致问题。这个过程和细节的描述可以在链接的问题中找到。我的问题是,由于某种原因,在第6个Alt + Enter之后,钥匙挂钩一直停止工作。我不是自己取消注册。为什么我的低级别Windows键挂钩停止工作?
这是钥匙钩码:
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从单独的线程处理。
“Windows将自动做到这一点,这不可避免地会导致问题,”我很困惑在这里:Windows不会使Windows全屏自动*和您的解决方案有问题*。那么你通过编写自己的键盘钩子避免了什么? –
@ todda.speot当您在DX11游戏中按Alt + Enter时,窗口会自动切换为全屏模式。它将前台缓冲区分辨率设置为桌面分辨率,如果我想让游戏在640x480下运行,这是不正确的。为了避免这种情况,我设置了一个键钩来接收Alt + Enter并运行我自己的ToggleFullscreen()方法,该方法非常完美。 – Darkhydro
我在回答中做了一些散漫的事情,看看是否有帮助。 –