低级鼠标钩子(WH_MOUSE_LL)修复按键检测: GetAsyncKeyState 在管理员环境检测不到鼠标键, 新建 Input 模块

This commit is contained in:
kedou 2026-08-05 22:49:17 +08:00
parent a56de0ef13
commit 2c44ebb9e8
8 changed files with 78 additions and 10 deletions

View File

@ -160,6 +160,7 @@
<ClCompile Include="Framework\ImGui\imgui_impl_win32.cpp" />
<ClCompile Include="Framework\ImGui\imgui_tables.cpp" />
<ClCompile Include="Framework\ImGui\imgui_widgets.cpp" />
<ClCompile Include="Framework\Input\Input.cpp" />
<ClCompile Include="Framework\Memory\Memory.cpp" />
<ClCompile Include="Framework\Overlay\Overlay.cpp" />
<ClCompile Include="Framework\Overlay\OverlayUserFunctions.cpp" />

View File

@ -111,6 +111,9 @@
<ClCompile Include="Framework\Overlay\OverlayUserFunctions.cpp">
<Filter>Framework\Overlay</Filter>
</ClCompile>
<ClCompile Include="Framework\Input\Input.cpp">
<Filter>Framework</Filter>
</ClCompile>
<ClCompile Include="Framework\Memory\Memory.cpp">
<Filter>Framework\Memory</Filter>
</ClCompile>

View File

@ -1,4 +1,5 @@
#include "Framework.h"
#include "../Framework/Input/Input.h"
#include <cmath>
#include <cstdio>
#include <cstring>
@ -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)
{

View File

@ -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();

View File

@ -1,4 +1,5 @@
#include "Framework.h"
#include "../Framework/Input/Input.h"
#include <cstdio>
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);

View File

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

View File

@ -0,0 +1,11 @@
#pragma once
#include <Windows.h>
// 低级输入钩子模块
// 问题: GetAsyncKeyState 在管理员权限/整合包环境下检测不到鼠标按键(左/右键)
// 方案: WH_MOUSE_LL 低级钩子全局捕获鼠标按下/释放, IsKeyDown 优先读钩子状态
// 键盘键仍然走 GetAsyncKeyState (菜单 INSERT 切换已验证有效)
bool IsKeyDown(int vk);
void InstallInputHook();
void RemoveInputHook();

View File

@ -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;