- 3
- 1
Подскажите, пожалуйста, почему курсор не скрывается после закрытия ImGui-меню в SAMP.
entry.cpp:
#include "include.h"
kthook::kthook_simple<CTimer__UpdateSignature> CTimerHook{};
kthook::kthook_signal<PresentSignature> PresentHook{};
kthook::kthook_signal<ResetSignature> ResetHook{};
kthook::kthook_simple<WndProcSignature> WndProcHook{};
bool ImGuiEnable;
char ImGuiInputBuffer[256];
DWORD dwSAMP = 0;
DWORD SAMP_GAME_PTR = 0;
DWORD SAMP_FUNC_TOGGLECURSOR = 0;
DWORD SAMP_FUNC_CURSORUNLOCKACTORCAM = 0;
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
bool ToggleCursor(bool state) {
if (dwSAMP && SAMP_GAME_PTR && SAMP_FUNC_TOGGLECURSOR && SAMP_FUNC_CURSORUNLOCKACTORCAM) {
void* obj = *(void**)(dwSAMP + SAMP_GAME_PTR);
reinterpret_cast<void(__thiscall*)(void*, int, bool)>(dwSAMP + SAMP_FUNC_TOGGLECURSOR)(obj, state ? 3 : 0, !state);
if (!state)
reinterpret_cast<void(__thiscall*)(void*)>(dwSAMP + SAMP_FUNC_CURSORUNLOCKACTORCAM)(obj);
}
return state;
}
HRESULT WndProc(const decltype(WndProcHook)& hook, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (uMsg == WM_KEYUP && wParam == VK_INSERT) {
ImGuiEnable = !ImGuiEnable;
ToggleCursor(ImGuiEnable);
}
if (ImGui_ImplWin32_WndProcHandler(hwnd, uMsg, wParam, lParam))
return 1;
return hook.get_trampoline()(hwnd, uMsg, wParam, lParam);
}
std::optional<HRESULT> D3D9Present(
const decltype(PresentHook)& hook,
IDirect3DDevice9* pDevice,
const RECT* pSrcRect,
const RECT* pDestRect,
HWND hDestWindow,
const RGNDATA* pDirtyRegion)
{
static bool ImGuiInit = false;
if (!ImGuiInit) {
ImGui::CreateContext();
ImGui_ImplWin32_Init(**reinterpret_cast<HWND**>(0xC17054));
ImGui_ImplDX9_Init(pDevice);
ImGui::GetIO().IniFilename = nullptr;
std::string font = std::string(getenv("WINDIR")) + "\\Fonts\\arial.ttf";
ImGui::GetIO().Fonts->AddFontFromFileTTF(font.c_str(), 14.0f, nullptr, ImGui::GetIO().Fonts->GetGlyphRangesCyrillic());
auto latest_wndproc_ptr = GetWindowLongPtrW(**reinterpret_cast<HWND**>(0xC17054), GWLP_WNDPROC);
WndProcHook.set_dest(latest_wndproc_ptr);
WndProcHook.set_cb(&WndProc);
WndProcHook.install();
ImGuiInit = true;
}
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
ImGui::GetIO().MouseDrawCursor = ImGuiEnable;
if (ImGuiEnable) {
ImGui::SetNextWindowPos(ImVec2(250.f, 250.f), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(300.f, 100.f), ImGuiCond_FirstUseEver);
ImGui::Begin("ImGuiTemplate", &ImGuiEnable);
ImGui::Text("Text");
ImGui::InputText("Input text", ImGuiInputBuffer, sizeof(ImGuiInputBuffer));
if (ImGui::Button("Touch button"))
MessageBoxA(**reinterpret_cast<HWND**>(0xC17054), ImGuiInputBuffer, "", MB_OK);
ImGui::End();
}
ImGui::EndFrame();
ImGui::Render();
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
return std::nullopt;
}
std::optional<HRESULT> D3D9Lost(const decltype(ResetHook)& hook, LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentParams) {
ImGui_ImplDX9_InvalidateDeviceObjects();
return std::nullopt;
}
void D3D9Reset(const decltype(ResetHook)& hook, HRESULT& return_value, IDirect3DDevice9* device_ptr, D3DPRESENT_PARAMETERS* parameters) {
ImGui_ImplDX9_InvalidateDeviceObjects();
}
void setD3D9Hooks() {
DWORD pDevice = *reinterpret_cast<DWORD*>(0xC97C28);
void** vTable = *reinterpret_cast<void***>(pDevice);
PresentHook.set_dest(vTable[17]);
PresentHook.before.connect(&D3D9Present);
PresentHook.install();
ResetHook.set_dest(vTable[16]);
ResetHook.before.connect(&D3D9Lost);
ResetHook.after.connect(&D3D9Reset);
ResetHook.install();
}
void CTimer__Update(const decltype(CTimerHook)& hook) {
static bool init = false;
if (!init) {
setD3D9Hooks();
init = true;
}
hook.get_trampoline()();
}
using namespace plugin;
struct Main {
Main() {
Events::gameProcessEvent += [] {
auto hSAMP = GetModuleHandle(L"samp.dll");
if (hSAMP) {
dwSAMP = reinterpret_cast<DWORD>(hSAMP);
SAMP_GAME_PTR = 0x21A10C;
SAMP_FUNC_TOGGLECURSOR = 0x9BD30;
SAMP_FUNC_CURSORUNLOCKACTORCAM = 0x9BC10;
}
CTimerHook.set_dest(0x561B10);
CTimerHook.set_cb(&CTimer__Update);
CTimerHook.install();
};
}
} gInstance;
include.h:
#pragma once
#include <plugin.h>
#include <d3d9.h>
#include <Windows.h>
#include <string>
#include <optional>
#include "src/kthook/include/kthook/kthook.hpp"
#include "src/imgui/imgui.h"
#include "src/imgui/imgui_impl_dx9.h"
#include "src/imgui/imgui_impl_win32.h"
using CTimer__UpdateSignature = void(__cdecl*)();
using PresentSignature = HRESULT(__stdcall*)(IDirect3DDevice9*, const RECT*, const RECT*, HWND, const RGNDATA*);
using ResetSignature = HRESULT(__stdcall*)(IDirect3DDevice9*, D3DPRESENT_PARAMETERS*);
using WndProcSignature = HRESULT(__stdcall*)(HWND, UINT, WPARAM, LPARAM);
extern kthook::kthook_simple<CTimer__UpdateSignature> CTimerHook;
extern kthook::kthook_signal<PresentSignature> PresentHook;
extern kthook::kthook_signal<ResetSignature> ResetHook;
extern kthook::kthook_simple<WndProcSignature> WndProcHook;
extern bool ImGuiEnable;
extern char ImGuiInputBuffer[256];
extern DWORD dwSAMP;
extern DWORD SAMP_GAME_PTR;
extern DWORD SAMP_FUNC_TOGGLECURSOR;
extern DWORD SAMP_FUNC_CURSORUNLOCKACTORCAM;
bool ToggleCursor(bool state);
void setD3D9Hooks();
Последнее редактирование: