diff --git a/CFramework/CFramework.vcxproj b/CFramework/CFramework.vcxproj index 852acea..4dbd883 100644 --- a/CFramework/CFramework.vcxproj +++ b/CFramework/CFramework.vcxproj @@ -160,6 +160,7 @@ + diff --git a/CFramework/CFramework.vcxproj.filters b/CFramework/CFramework.vcxproj.filters index 5e9c712..16ef923 100644 --- a/CFramework/CFramework.vcxproj.filters +++ b/CFramework/CFramework.vcxproj.filters @@ -111,6 +111,9 @@ Framework\Overlay + + Framework + Framework\Memory diff --git a/CFramework/Cheat/Aim.cpp b/CFramework/Cheat/Aim.cpp index 65a71da..1b37132 100644 --- a/CFramework/Cheat/Aim.cpp +++ b/CFramework/Cheat/Aim.cpp @@ -1,4 +1,5 @@ #include "Framework.h" +#include "../Framework/Input/Input.h" #include #include #include @@ -35,10 +36,8 @@ namespace return a; } - bool IsKeyDown(int vk) - { - return (GetAsyncKeyState(vk) & 0x8000) != 0; - } + // IsKeyDown は Framework/Input/Input.h のグローバル関数を使用 + // (GetAsyncKeyState はマウスボタンを検知できない環境があるため、WH_MOUSE_LL フックで捕捉) void SendMouseMove(long dx, long dy) { diff --git a/CFramework/Cheat/Menu.cpp b/CFramework/Cheat/Menu.cpp index fa3b154..b5d74f7 100644 --- a/CFramework/Cheat/Menu.cpp +++ b/CFramework/Cheat/Menu.cpp @@ -1,4 +1,5 @@ #include "Framework.h" +#include "../Framework/Input/Input.h" // ImGui::Combo/ImGui::List等で使う文字列群 const char* BoxTypeList[] = { "简单", "棱角" }; @@ -193,9 +194,7 @@ void CFramework::RenderMenu() ImGui::Text("扫描 : %d 实体 / %d 血量 / %d 跳过", m_diagTotal, m_diagHealth, m_diagSkipped); ImGui::Text("目标 : %s (距 %0.fpx)", m_diagBestAddr ? "锁定" : "无", m_diagBestDist); { - bool k0 = (GetAsyncKeyState(g.g_AimKey0) & 0x8000) != 0; - bool k1 = (GetAsyncKeyState(g.g_AimKey1) & 0x8000) != 0; - ImGui::Text("按键 : %s", (k0 || k1) ? "按住" : "---"); + ImGui::Text("按键 : %s", (IsKeyDown(g.g_AimKey0) || IsKeyDown(g.g_AimKey1)) ? "按住" : "---"); } ImGui::EndChild(); diff --git a/CFramework/Cheat/Visual.cpp b/CFramework/Cheat/Visual.cpp index 0b136a6..afc423a 100644 --- a/CFramework/Cheat/Visual.cpp +++ b/CFramework/Cheat/Visual.cpp @@ -1,4 +1,5 @@ #include "Framework.h" +#include "../Framework/Input/Input.h" #include bool InScreen(const Vector2& vIn) @@ -32,14 +33,12 @@ void CFramework::RenderInfo() // --- 自瞄实时状态 (关菜单也能看) --- // Aim = 自瞄开关; M = 方式(MEM内存/MOU鼠标); Key = 触发键是否按住 // Tgt = 是否锁定目标; d = 目标离屏幕中心距离px - bool k0 = (GetAsyncKeyState(g.g_AimKey0) & 0x8000) != 0; - bool k1 = (GetAsyncKeyState(g.g_AimKey1) & 0x8000) != 0; char aim[192]{}; snprintf(aim, sizeof(aim), "Aim:%s M:%s Key:%s Tgt:%s d=%.0fpx", g.g_Aim ? "ON" : "OFF", g.g_AimMethod == 0 ? "MEM" : "MOU", - (k0 || k1) ? "HOLD" : "--", + (IsKeyDown(g.g_AimKey0) || IsKeyDown(g.g_AimKey1)) ? "HOLD" : "--", m_diagBestAddr ? "LOCK" : "NONE", m_diagBestDist); StringEx(ImVec2(8.f, 42.f), ImColor(1.f, 0.f, 0.f, 1.f), ImGui::GetFontSize(), aim); diff --git a/CFramework/Framework/Input/Input.cpp b/CFramework/Framework/Input/Input.cpp new file mode 100644 index 0000000..3d5490e --- /dev/null +++ b/CFramework/Framework/Input/Input.cpp @@ -0,0 +1,51 @@ +#include "Input.h" + +namespace +{ + volatile bool g_mouseL = false; // 左键按下状态 (低级钩子捕获) + volatile bool g_mouseR = false; // 右键按下状态 + HHOOK g_mouseHook = nullptr; + + // 低级鼠标钩子回调: 在安装线程的消息循环中触发 (OverlayLoop 的 PeekMessage) + LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) + { + if (nCode >= 0) + { + switch (wParam) + { + case WM_LBUTTONDOWN: g_mouseL = true; break; + case WM_LBUTTONUP: g_mouseL = false; break; + case WM_RBUTTONDOWN: g_mouseR = true; break; + case WM_RBUTTONUP: g_mouseR = false; break; + } + } + return CallNextHookEx(NULL, nCode, wParam, lParam); + } +} + +void InstallInputHook() +{ + if (!g_mouseHook) + g_mouseHook = SetWindowsHookExW(WH_MOUSE_LL, MouseProc, GetModuleHandleW(NULL), 0); +} + +void RemoveInputHook() +{ + if (g_mouseHook) + { + UnhookWindowsHookEx(g_mouseHook); + g_mouseHook = nullptr; + } +} + +bool IsKeyDown(int vk) +{ + // 鼠标键: 钩子状态优先, GetAsyncKeyState 兜底 + if (vk == VK_LBUTTON) + return g_mouseL || ((GetAsyncKeyState(vk) & 0x8000) != 0); + if (vk == VK_RBUTTON) + return g_mouseR || ((GetAsyncKeyState(vk) & 0x8000) != 0); + + // 键盘键: GetAsyncKeyState (已验证有效) + return (GetAsyncKeyState(vk) & 0x8000) != 0; +} diff --git a/CFramework/Framework/Input/Input.h b/CFramework/Framework/Input/Input.h new file mode 100644 index 0000000..c21dd16 --- /dev/null +++ b/CFramework/Framework/Input/Input.h @@ -0,0 +1,11 @@ +#pragma once +#include + +// 低级输入钩子模块 +// 问题: GetAsyncKeyState 在管理员权限/整合包环境下检测不到鼠标按键(左/右键) +// 方案: WH_MOUSE_LL 低级钩子全局捕获鼠标按下/释放, IsKeyDown 优先读钩子状态 +// 键盘键仍然走 GetAsyncKeyState (菜单 INSERT 切换已验证有效) + +bool IsKeyDown(int vk); +void InstallInputHook(); +void RemoveInputHook(); diff --git a/CFramework/main.cpp b/CFramework/main.cpp index c3b2bab..1ad92d6 100644 --- a/CFramework/main.cpp +++ b/CFramework/main.cpp @@ -1,5 +1,6 @@ #include "Cheat/Framework.h" #include "Framework/Overlay/Overlay.h" +#include "Framework/Input/Input.h" #pragma comment(lib, "freetype.lib") /* @@ -49,6 +50,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if (!overlay->InitOverlay("EscapeFromTarkov", InitMode::WINDOW_TITLE)) // MemoryInitModeと同様 return 2; + // 低级输入钩子 (GetAsyncKeyState 检测不到鼠标键的环境用) + InstallInputHook(); + // ImGui io setting ImGuiIO& io = ImGui::GetIO(); (void)io; io.IniFilename = nullptr; @@ -88,6 +92,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine overlay->OverlayLoop(); overlay->DestroyOverlay(); + RemoveInputHook(); m.DetachProcess(); g.process_active = false;