使用cl.exe编译游戏宏程序触发双显示器关闭的问题求助
cl.exe编译游戏宏程序触发显示器关闭问题排查与解决
我正在开发一款游戏宏程序,仅在使用cl.exe编译时,按下宏启用按键会导致笔记本屏幕和HDMI外接显示器同时关闭;用g++编译则完全正常。我希望保留cl.exe编译方式,避免用户额外安装MinGW。
已尝试的操作:
- 移除鉴权代码(问题最初是添加鉴权后出现,但移除后仍未解决)
- 注释功能模块,问题依旧存在
核心代码片段
虚拟按键/鼠标模拟函数
// 虚拟按键模拟(宏核心驱动) // 模拟按键按下 void PressKey(int key) { INPUT input; input.type = INPUT_KEYBOARD; input.ki.wScan = MapVirtualKey(key, MAPVK_VK_TO_VSC); input.ki.time = 0; input.ki.dwExtraInfo = 0; input.ki.wVk = key; input.ki.dwFlags = 0; SendInput(1, &input, sizeof(INPUT)); // 释放按键 input.ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, &input, sizeof(INPUT)); } // 模拟鼠标点击 void SimulateMouseClick(bool isRight = true) { INPUT input; input.type = INPUT_MOUSE; input.mi.dwFlags = isRight ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN; SendInput(1, &input, sizeof(INPUT)); input.mi.dwFlags = isRight ? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP; SendInput(1, &input, sizeof(INPUT)); } // 相对移动鼠标 void MoveMouse(int dx, int dy) { INPUT input; input.type = INPUT_MOUSE; input.mi.dx = dx; input.mi.dy = dy; input.mi.dwFlags = MOUSEEVENTF_MOVE; SendInput(1, &input, sizeof(INPUT)); }
主函数与消息循环
// 主函数与循环 int main() { // Auth::init("redacted :) (its a pastebin auth lmfao)"); WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T(" "), NULL }; ::RegisterClassEx(&wc); HWND hwnd = ::CreateWindow(wc.lpszClassName, NULL, WS_OVERLAPPEDWINDOW ^ WS_CAPTION ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX, 100, 100, width, height, NULL, NULL, wc.hInstance, NULL); // 初始化Direct3D if (!CreateDeviceD3D(hwnd)) { CleanupDeviceD3D(); ::UnregisterClass(wc.lpszClassName, wc.hInstance); return 1; } // 显示窗口 ::ShowWindow(hwnd, SW_SHOWDEFAULT); ::UpdateWindow(hwnd); IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; SetupImGuiStyle(); LoadSystemFont(); ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); MSG msg; ZeroMemory(&msg, sizeof(msg)); while (msg.message != WM_QUIT) { if (PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); continue; } ImGui_ImplDX11_NewFrame(); ImGui_ImplWin32_NewFrame(); ImGui::NewFrame(); RenderMenu(); Update(); ImGui::Render(); const float clear_color_with_alpha[4] = { 0.45f, 0.55f, 0.60f, 1.00f }; g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr); g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); g_pSwapChain->Present(1, 0); } ImGui_ImplDX11_Shutdown(); ImGui_ImplWin32_Shutdown(); ImGui::DestroyContext(); CleanupDeviceD3D(); DestroyWindow(hwnd); UnregisterClass(wc.lpszClassName, wc.hInstance); return 0; }
编译命令
cl.exe 编译命令
cl /std:c++17 /EHsc /FeYourProgramName.exe main.cpp imgui.cpp imgui_draw.cpp imgui_widgets.cpp imgui_tables.cpp imgui_impl_dx11.cpp imgui_impl_win32.cpp /link d3d11.lib d3dcompiler.lib user32.lib Dwmapi.lib
g++ 编译命令
g++ main.cpp imgui.cpp imgui_draw.cpp imgui_widgets.cpp imgui_tables.cpp imgui_impl_dx11.cpp imgui_impl_win32.cpp -o your_program -lgdi32 -ld3d11 -ld3dcompiler
排查方向与解决方案
1. 修复INPUT结构体初始化问题
cl.exe与g++的结构体默认初始化规则不同,原代码中未完全初始化INPUT结构体,未赋值的字段可能携带随机内存值,导致SendInput执行异常。修改为全零初始化:
INPUT input = {0}; // 替换原代码中仅声明的INPUT input;
2. 统一结构体对齐规则
cl.exe默认对齐可能与g不一致,添加编译选项强制对齐为8字节(匹配g默认):
cl /std:c++17 /EHsc /Zp8 /FeYourProgramName.exe main.cpp imgui.cpp imgui_draw.cpp imgui_widgets.cpp imgui_tables.cpp imgui_impl_dx11.cpp imgui_impl_win32.cpp /link d3d11.lib d3dcompiler.lib user32.lib Dwmapi.lib
3. 检查按键模拟的类型安全
对MapVirtualKey的返回值强制类型转换为WORD,避免因类型不匹配导致内存溢出:
input.ki.wScan = static_cast<WORD>(MapVirtualKey(key, MAPVK_VK_TO_VSC));
4. 排查系统快捷键冲突
确认宏启用按键是否与系统显示器控制快捷键(如Win+P、Fn组合键)冲突。cl编译下可能因按键模拟的细微差异误触发系统指令,可在Update()函数中添加日志输出按键值,验证触发逻辑:
// 示例:检测F1键触发宏时输出日志 if (GetAsyncKeyState(VK_F1) & 0x8000) { OutputDebugStringA("Macro activated: VK_F1\n"); // 宏执行逻辑 }
通过DebugView工具查看输出,确认是否有意外按键被发送。
5. 禁用编译优化排查
添加/Od选项禁用cl.exe的优化,排查是否是优化导致代码逻辑异常:
cl /std:c++17 /EHsc /Zp8 /Od /FeYourProgramName.exe main.cpp imgui.cpp imgui_draw.cpp imgui_widgets.cpp imgui_tables.cpp imgui_impl_dx11.cpp imgui_impl_win32.cpp /link d3d11.lib d3dcompiler.lib user32.lib Dwmapi.lib
内容的提问来源于stack exchange,提问作者Aspis
相关产品推荐
相关产品推荐

