diff --git a/src/ProtoInput/ProtoInputHooks/AdjustWindowRectHook.cpp b/src/ProtoInput/ProtoInputHooks/AdjustWindowRectHook.cpp index 0faaebf..ae9ef03 100644 --- a/src/ProtoInput/ProtoInputHooks/AdjustWindowRectHook.cpp +++ b/src/ProtoInput/ProtoInputHooks/AdjustWindowRectHook.cpp @@ -32,12 +32,12 @@ namespace Proto void AdjustWindowRectHook::ShowGuiStatus() { int pos[2] = { posx, posy }; - ImGui::SliderInt2("Position", &pos[0], -5000, 5000); + ImGui::InputInt2("Position", &pos[0]); posx = pos[0]; posy = pos[1]; int size[2] = { width, height }; - ImGui::SliderInt2("Size", &size[0], 0, 5000); + ImGui::InputInt2("Size", &size[0]); width = size[0]; height = size[1]; } diff --git a/src/ProtoInput/ProtoInputHooks/FakeCursor.cpp b/src/ProtoInput/ProtoInputHooks/FakeCursor.cpp index 377962c..9322020 100644 --- a/src/ProtoInput/ProtoInputHooks/FakeCursor.cpp +++ b/src/ProtoInput/ProtoInputHooks/FakeCursor.cpp @@ -9,11 +9,15 @@ namespace Proto { FakeCursor FakeCursor::state{}; +#define WM_MOVE_pointerWindow (WM_APP + 1) LRESULT WINAPI FakeCursorWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { + case WM_MOVE_pointerWindow: + FakeCursor::state.GetWindowDimensions(hWnd); + break; case WM_DESTROY: PostQuitMessage(0); return 0; @@ -40,6 +44,34 @@ BOOL CALLBACK EnumWindowsProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMoni } return true; } + +void FakeCursor::GetWindowDimensions(HWND pointerWindow) +{ + + HWND tHwnd = (HWND)HwndSelector::GetSelectedHwnd(); + if (pointerWindow == tHwnd) + { + SetWindowPos(pointerWindow, /*HWND_TOP*/HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + return; + } + + if (IsWindow(tHwnd)) + { + RECT cRect; + GetClientRect(tHwnd, &cRect); + + POINT topLeft = { cRect.left, cRect.top }; + ClientToScreen(tHwnd, &topLeft); + + SetWindowPos(pointerWindow, /*HWND_TOP*/HWND_TOPMOST, + topLeft.x, + topLeft.y, + cRect.right - cRect.left, + cRect.bottom - cRect.top, + SWP_NOACTIVATE); + } +} + void FakeCursor::DrawCursor() { @@ -139,6 +171,31 @@ DWORD WINAPI FakeCursorDrawLoopThread(LPVOID lpParameter) return 0; } +DWORD WINAPI PointerWindowLoopThread(LPVOID lpParameter) +{ + printf("Pointer window loop thread start"); + FakeCursor::state.UpdatePointerWindowLoopInternal(); + + return 0; +} + +void FakeCursor::UpdatePointerWindowLoopInternal() +{ + while (true) + { + HWND tHwnd = (HWND)HwndSelector::GetSelectedHwnd(); + if (!IsWindow(tHwnd)) + { + Sleep(2000); + continue; + } + + PostMessage(pointerWindow, WM_MOVE_pointerWindow, 0, 0); + + Sleep(5000); + } +} + void FakeCursor::StartDrawLoopInternal() { int tick = 0; @@ -153,17 +210,20 @@ void FakeCursor::StartDrawLoopInternal() //TODO: is this ok? (might eat cpu) Sleep(drawingEnabled ? 12 : 500); - tick = (tick + 1) % 200; + if (!FakeMouseKeyboard::PutMouseInsideWindow) + { + tick = (tick + 1) % 200; - if (tick == 0) - // Nucleus can put the game window above the pointer without this - SetWindowPos(pointerWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE); + if (tick == 0) + // Nucleus can put the game window above the pointer without this + SetWindowPos(pointerWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE); + } } } void FakeCursor::StartInternal() { - Proto::AddThreadToACL(GetCurrentThreadId()); + Sleep(1000); const auto hInstance = GetModuleHandle(NULL); @@ -182,6 +242,13 @@ void FakeCursor::StartInternal() wc.lpszClassName = className; wc.style = CS_OWNDC | CS_NOCLOSE; + DWORD ws_POPUP; + + if (FakeMouseKeyboard::PutMouseInsideWindow) + ws_POPUP = WS_POPUP; + else + ws_POPUP = 0; + if (!RegisterClass(&wc)) { fprintf(stderr, "Failed to open fake cursor window\n"); @@ -190,28 +257,35 @@ void FakeCursor::StartInternal() { pointerWindow = CreateWindowExW(WS_EX_NOACTIVATE | WS_EX_NOINHERITLAYOUT | WS_EX_NOPARENTNOTIFY | WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW | WS_EX_LAYERED, - wc.lpszClassName, classNameStr.c_str(), 0, - 0, 0, 200, 200, - nullptr, nullptr, hInstance, nullptr); + wc.lpszClassName, classNameStr.c_str(), ws_POPUP, + 0, 0, 200, 200, + nullptr, nullptr, hInstance, nullptr); + + if (!FakeMouseKeyboard::PutMouseInsideWindow) + SetWindowLongW(pointerWindow, GWL_STYLE, WS_VISIBLE | WS_DISABLED); - SetWindowLongW(pointerWindow, GWL_STYLE, WS_VISIBLE | WS_DISABLED); SetLayeredWindowAttributes(pointerWindow, transparencyKey, 0, LWA_COLORKEY); - // Nucleus can put the game window above the pointer without this - SetWindowPos(pointerWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE); + if (!FakeMouseKeyboard::PutMouseInsideWindow) + { + // Nucleus can put the game window above the pointer without this + SetWindowPos(pointerWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE); - // ShowWindow(pointerWindow, SW_SHOWDEFAULT); - // UpdateWindow(pointerWindow); - EnableDisableFakeCursor(drawingEnabled); + // ShowWindow(pointerWindow, SW_SHOWDEFAULT); + // UpdateWindow(pointerWindow); + EnableDisableFakeCursor(drawingEnabled); - // Over every screen - EnumDisplayMonitors(nullptr, nullptr, &EnumWindowsProc, 0); - MoveWindow(pointerWindow, fakeCursorMinX, fakeCursorMinY, fakeCursorMaxX - fakeCursorMinX, fakeCursorMaxY - fakeCursorMinY, TRUE); + // Over every screen + EnumDisplayMonitors(nullptr, nullptr, &EnumWindowsProc, 0); + MoveWindow(pointerWindow, fakeCursorMinX, fakeCursorMinY, fakeCursorMaxX - fakeCursorMinX, fakeCursorMaxY - fakeCursorMinY, TRUE); + } hdc = GetDC(pointerWindow); - //TODO: configurable cursor - hCursor = LoadCursorW(NULL, IDC_ARROW); + if (FakeMouseKeyboard::PutMouseInsideWindow) + hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(32512)); + else + hCursor = LoadCursorW(NULL, IDC_ARROW); //TODO: configurable cursor const auto threadHandle = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)FakeCursorDrawLoopThread, GetModuleHandle(0), 0, 0); @@ -219,6 +293,16 @@ void FakeCursor::StartInternal() if (threadHandle != nullptr) CloseHandle(threadHandle); + if (FakeMouseKeyboard::PutMouseInsideWindow) + { + const auto pointerThreadHandle = CreateThread(nullptr, 0, + (LPTHREAD_START_ROUTINE)PointerWindowLoopThread, GetModuleHandle(0), 0, 0); + + if (pointerThreadHandle != nullptr) + CloseHandle(pointerThreadHandle); + FakeCursor::EnableDisableFakeCursor(true); + } + // Want to avoid doing anything in the message loop that might cause it to not respond, as the entire screen will say not responding... MSG msg; ZeroMemory(&msg, sizeof(msg)); @@ -246,7 +330,8 @@ void FakeCursor::EnableDisableFakeCursor(bool enable) { state.drawingEnabled = enable; - ShowWindow(state.pointerWindow, enable ? SW_SHOWDEFAULT : SW_HIDE); + auto showWindow = FakeMouseKeyboard::PutMouseInsideWindow ? SW_SHOWNOACTIVATE : SW_SHOWDEFAULT; + ShowWindow(state.pointerWindow, enable ? showWindow : SW_HIDE); UpdateWindow(state.pointerWindow); } diff --git a/src/ProtoInput/ProtoInputHooks/FakeCursor.h b/src/ProtoInput/ProtoInputHooks/FakeCursor.h index 0574f66..23f4b3a 100644 --- a/src/ProtoInput/ProtoInputHooks/FakeCursor.h +++ b/src/ProtoInput/ProtoInputHooks/FakeCursor.h @@ -43,6 +43,8 @@ class FakeCursor bool DrawFakeCursorFix; void StartInternal(); void StartDrawLoopInternal(); + void UpdatePointerWindowLoopInternal(); // Checks the selected window dimensions. + void GetWindowDimensions(HWND hWnd); // For pointerWindow static bool& GetToggleVisilbityShorcutEnabled() { diff --git a/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.cpp b/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.cpp index 85d18f7..4a88bff 100644 --- a/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.cpp +++ b/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.cpp @@ -59,10 +59,10 @@ void FakeMouseKeyboard::AddMouseDelta(int dx, int dy) { if (!DefaultBottomRightMouseBounds) { - if (int max = mouseState.extendMouseBounds ? HwndSelector::windowWidth * 2 : HwndSelector::windowWidth; mouseState.x > max) + if (int max = mouseState.extendMouseBounds ? HwndSelector::windowWidth * 2 : HwndSelector::windowWidth; mouseState.x >= max) mouseState.x = max - 1; - if (int max = mouseState.extendMouseBounds ? HwndSelector::windowHeight * 2 : HwndSelector::windowHeight; mouseState.y > max) + if (int max = mouseState.extendMouseBounds ? HwndSelector::windowHeight * 2 : HwndSelector::windowHeight; mouseState.y >= max) mouseState.y = max - 1; } else if (DefaultBottomRightMouseBounds) @@ -137,9 +137,9 @@ void FakeMouseKeyboard::SetMousePos(int x, int y) { if (!DefaultBottomRightMouseBounds) { - if (int max = mouseState.extendMouseBounds ? HwndSelector::windowWidth * 2 : HwndSelector::windowWidth; mouseState.x > max) + if (int max = mouseState.extendMouseBounds ? HwndSelector::windowWidth * 2 : HwndSelector::windowWidth; mouseState.x >= max) mouseState.x = max - 1; - if (int max = mouseState.extendMouseBounds ? HwndSelector::windowHeight * 2 : HwndSelector::windowHeight; mouseState.y > max) + if (int max = mouseState.extendMouseBounds ? HwndSelector::windowHeight * 2 : HwndSelector::windowHeight; mouseState.y >= max) mouseState.y = max - 1; } else if (DefaultBottomRightMouseBounds) @@ -255,4 +255,27 @@ bool FakeMouseKeyboard::IsAsyncKeyStatePressed(int vkey) return false; } +bool FakeMouseKeyboard::IsExtendedKeyStatePressed(int vkey) +{ + switch (vkey) + { + case VK_UP: + case VK_DOWN: + case VK_LEFT: + case VK_RIGHT: + case VK_HOME: + case VK_END: + case VK_PRIOR: + case VK_NEXT: + case VK_INSERT: + case VK_DELETE: + case VK_RCONTROL: + case VK_RMENU: + case VK_SEPARATOR: + return true; + default: + return false; + } +} + } diff --git a/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.h b/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.h index f83313c..39f3c48 100644 --- a/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.h +++ b/src/ProtoInput/ProtoInputHooks/FakeMouseKeyboard.h @@ -55,6 +55,7 @@ class FakeMouseKeyboard static void ClearAsyncKeyState(int vkey); static bool IsKeyStatePressed(int vkey); static bool IsAsyncKeyStatePressed(int vkey); + static bool IsExtendedKeyStatePressed(int vkey); //To use the exteended key flag (like arrow keys) // Some games must use the exact window rect to determine the edge of the window. static bool PutMouseInsideWindow; diff --git a/src/ProtoInput/ProtoInputHooks/FocusHook.cpp b/src/ProtoInput/ProtoInputHooks/FocusHook.cpp index 3bc2fea..e3ede4b 100644 --- a/src/ProtoInput/ProtoInputHooks/FocusHook.cpp +++ b/src/ProtoInput/ProtoInputHooks/FocusHook.cpp @@ -1,16 +1,32 @@ #include "FocusHook.h" #include #include "HwndSelector.h" +#include "INISettings.h" namespace Proto { inline HWND GetHwnd() { - if (HwndSelector::GetSelectedHwnd() == 0) - HwndSelector::UpdateMainHwnd(); + if (Proto::fixWindowFocus) + { + HWND current = (HWND)HwndSelector::GetSelectedHwnd(); + + // Check if the handle is 0 OR if the window no longer exists (e.g. after resolution change) + if (current == 0 || !IsWindow(current)) + { + HwndSelector::UpdateMainHwnd(); + current = (HWND)HwndSelector::GetSelectedHwnd(); + } + return current; + } + else // Default + { + if (HwndSelector::GetSelectedHwnd() == 0) + HwndSelector::UpdateMainHwnd(); - return (HWND)HwndSelector::GetSelectedHwnd(); + return (HWND)HwndSelector::GetSelectedHwnd(); + } } HWND WINAPI Hook_GetForegroundWindow() diff --git a/src/ProtoInput/ProtoInputHooks/GuiImpl.cpp b/src/ProtoInput/ProtoInputHooks/GuiImpl.cpp index 473fd36..21106d9 100644 --- a/src/ProtoInput/ProtoInputHooks/GuiImpl.cpp +++ b/src/ProtoInput/ProtoInputHooks/GuiImpl.cpp @@ -11,6 +11,7 @@ #include "RawInput.h" #include "FontData.h" #include "Cleanup.h" +#include "INISettings.h" //TODO: default to hidden constexpr bool defaultGuiToHidden = true; @@ -139,6 +140,9 @@ void Proto::SetConsoleVisible(bool visible) int Proto::ShowGuiImpl() { + if (Proto::DisableGuiWindow) + return 0; + auto hInstance = GetModuleHandle(NULL); WNDCLASS wc = { 0 }; diff --git a/src/ProtoInput/ProtoInputHooks/HwndSelector.cpp b/src/ProtoInput/ProtoInputHooks/HwndSelector.cpp index ab38d6a..8c1df5e 100644 --- a/src/ProtoInput/ProtoInputHooks/HwndSelector.cpp +++ b/src/ProtoInput/ProtoInputHooks/HwndSelector.cpp @@ -2,6 +2,7 @@ #include "HwndSelector.h" #include #include "FakeCursor.h" +#include "INISettings.h" namespace Proto @@ -14,6 +15,8 @@ struct HandleData { unsigned long pid; HWND hwnd; + const char* winName; + const char* winClass; }; BOOL IsMainWindow(HWND handle) @@ -34,19 +37,43 @@ BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam) DWORD pid = 0; GetWindowThreadProcessId(handle, &pid); - if (data.pid != pid || !IsMainWindow(handle)) + if (data.pid != pid) return TRUE; // Keep searching + bool strictMode = (data.winName && data.winName[0] != '\0') || + (data.winClass && data.winClass[0] != '\0'); + + if (strictMode) + { + if (data.winClass && data.winClass[0] != '\0') { + char className[256]; + GetClassNameA(handle, className, sizeof(className)); + if (strcmp(className, data.winClass) != 0) return TRUE; + } + + if (data.winName && data.winName[0] != '\0') { + char windowName[256]; + GetWindowTextA(handle, windowName, sizeof(windowName)); + if (strcmp(windowName, data.winName) != 0) return TRUE; + } + + if (!IsWindowVisible(handle)) return TRUE; + } + else + { + if (!IsMainWindow(handle)) return TRUE; + } + data.hwnd = handle; - + return FALSE; } void HwndSelector::UpdateMainHwnd(bool logOutput) { - // Go through all the top level windows, select the first that's visible & belongs to the process + // If not custom window, go through all the top level windows, select the first that's visible & belongs to the process - HandleData data { GetCurrentProcessId(), nullptr }; + HandleData data = { GetCurrentProcessId(), nullptr, customWindowName, customClassName }; EnumWindows(EnumWindowsCallback, (LPARAM)&data); const auto hwnd = (intptr_t)data.hwnd; @@ -60,7 +87,7 @@ void HwndSelector::UpdateMainHwnd(bool logOutput) } if (data.hwnd != nullptr) - selectedHwnd = (intptr_t)data.hwnd; + selectedHwnd = (intptr_t)data.hwnd; } void HwndSelector::UpdateWindowBounds() diff --git a/src/ProtoInput/ProtoInputHooks/INISettings.cpp b/src/ProtoInput/ProtoInputHooks/INISettings.cpp new file mode 100644 index 0000000..6ed65bb --- /dev/null +++ b/src/ProtoInput/ProtoInputHooks/INISettings.cpp @@ -0,0 +1,29 @@ +#include "INISettings.h" +#include +#include + +namespace Proto +{ + char customWindowName[128] = ""; + char customClassName[128] = ""; + bool DisableGuiWindow = false; + bool fixWindowFocus = false; + + void LoadConfig() + { + char path[MAX_PATH]; + if (GetModuleFileNameA(NULL, path, sizeof(path))) + { + char* lastSlash = strrchr(path, '\\'); + if (lastSlash) *lastSlash = '\0'; + + strcat(path, "\\ProtoInput.ini"); + + DisableGuiWindow = GetPrivateProfileIntA("General", "DisableGuiWindow", 0, path) != 0; + fixWindowFocus = GetPrivateProfileIntA("General", "FixWindowFocus", 0, path) != 0; + + GetPrivateProfileStringA("FindWindow", "WindowName", "", customWindowName, sizeof(customWindowName), path); + GetPrivateProfileStringA("FindWindow", "ClassName", "", customClassName, sizeof(customClassName), path); + } + } +} \ No newline at end of file diff --git a/src/ProtoInput/ProtoInputHooks/INISettings.h b/src/ProtoInput/ProtoInputHooks/INISettings.h new file mode 100644 index 0000000..b7c55cc --- /dev/null +++ b/src/ProtoInput/ProtoInputHooks/INISettings.h @@ -0,0 +1,12 @@ +#pragma once + +namespace Proto +{ + extern bool DisableGuiWindow; + extern bool fixWindowFocus; + + extern char customWindowName[128]; + extern char customClassName[128]; + + void LoadConfig(); +} \ No newline at end of file diff --git a/src/ProtoInput/ProtoInputHooks/MoveWindowHook.cpp b/src/ProtoInput/ProtoInputHooks/MoveWindowHook.cpp index 6754377..7251a73 100644 --- a/src/ProtoInput/ProtoInputHooks/MoveWindowHook.cpp +++ b/src/ProtoInput/ProtoInputHooks/MoveWindowHook.cpp @@ -1,5 +1,6 @@ #include "MoveWindowHook.h" #include +#include "HwndSelector.h" namespace Proto { @@ -25,14 +26,24 @@ namespace Proto void MoveWindowHook::ShowGuiStatus() { int pos[2] = { posx, posy }; - ImGui::SliderInt2("Position", &pos[0], -5000, 5000); + ImGui::InputInt2("Position", &pos[0]); posx = pos[0]; posy = pos[1]; int size[2] = { width, height }; - ImGui::SliderInt2("Size", &size[0], 0, 5000); + ImGui::InputInt2("Size", &size[0]); width = size[0]; height = size[1]; + + ImGui::Separator(); + + if (ImGui::Button("Apply Changes")) + { + if ((HWND)HwndSelector::GetSelectedHwnd() != NULL) + { + ::MoveWindow((HWND)HwndSelector::GetSelectedHwnd(), posx, posy, width, height, TRUE); + } + } } void MoveWindowHook::InstallImpl() diff --git a/src/ProtoInput/ProtoInputHooks/MoveWindowHook.h b/src/ProtoInput/ProtoInputHooks/MoveWindowHook.h index 0e8d913..57d15da 100644 --- a/src/ProtoInput/ProtoInputHooks/MoveWindowHook.h +++ b/src/ProtoInput/ProtoInputHooks/MoveWindowHook.h @@ -25,7 +25,7 @@ namespace Proto return "When the game tries to reposition/resize its game window, this hook forces it to a fixed position and size. "; } - bool HasGuiStatus() const override { return false; } + bool HasGuiStatus() const override { return true; } void ShowGuiStatus() override; void InstallImpl() override; void UninstallImpl() override; diff --git a/src/ProtoInput/ProtoInputHooks/ProtoInputHooks.vcxproj b/src/ProtoInput/ProtoInputHooks/ProtoInputHooks.vcxproj index ee51cdc..87b363a 100644 --- a/src/ProtoInput/ProtoInputHooks/ProtoInputHooks.vcxproj +++ b/src/ProtoInput/ProtoInputHooks/ProtoInputHooks.vcxproj @@ -213,6 +213,7 @@ + @@ -274,6 +275,7 @@ + diff --git a/src/ProtoInput/ProtoInputHooks/ProtoInputHooks.vcxproj.filters b/src/ProtoInput/ProtoInputHooks/ProtoInputHooks.vcxproj.filters index 624e681..4b31074 100644 --- a/src/ProtoInput/ProtoInputHooks/ProtoInputHooks.vcxproj.filters +++ b/src/ProtoInput/ProtoInputHooks/ProtoInputHooks.vcxproj.filters @@ -180,6 +180,9 @@ Source Files\Hooks + + Source Files + @@ -323,5 +326,8 @@ Source Files\Hooks + + Source Files + \ No newline at end of file diff --git a/src/ProtoInput/ProtoInputHooks/RawInput.cpp b/src/ProtoInput/ProtoInputHooks/RawInput.cpp index a05f0d1..915a1f9 100644 --- a/src/ProtoInput/ProtoInputHooks/RawInput.cpp +++ b/src/ProtoInput/ProtoInputHooks/RawInput.cpp @@ -185,14 +185,14 @@ void RawInput::ProcessMouseInput(const RAWMOUSE& data, HANDLE deviceHandle) PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_RBUTTONUP, mouseMkFlags | MouseButtonFilter::signature, mousePointLparam); if ((data.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) != 0) - PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONDOWN, mouseMkFlags | (XBUTTON1 << 4) | MouseButtonFilter::signature, mousePointLparam); + PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONDOWN, (mouseMkFlags | MK_XBUTTON1) | (XBUTTON1 << 16) | MouseButtonFilter::signature, mousePointLparam); if ((data.usButtonFlags & RI_MOUSE_BUTTON_4_UP) != 0) - PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONUP, mouseMkFlags | (XBUTTON1 << 4) | MouseButtonFilter::signature, mousePointLparam); + PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONUP, (mouseMkFlags | MK_XBUTTON1) | (XBUTTON1 << 16) | MouseButtonFilter::signature, mousePointLparam); if ((data.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) != 0) - PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONDOWN, mouseMkFlags | (XBUTTON2 << 4) | MouseButtonFilter::signature, mousePointLparam); + PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONDOWN, (mouseMkFlags | MK_XBUTTON2) | (XBUTTON2 << 16) | MouseButtonFilter::signature, mousePointLparam); if ((data.usButtonFlags & RI_MOUSE_BUTTON_5_UP) != 0) - PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONUP, mouseMkFlags | (XBUTTON2 << 4) | MouseButtonFilter::signature, mousePointLparam); + PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_XBUTTONUP, (mouseMkFlags | MK_XBUTTON2) | (XBUTTON2 << 16) | MouseButtonFilter::signature, mousePointLparam); } @@ -233,6 +233,11 @@ void RawInput::ProcessKeyboardInput(const RAWKEYBOARD& data, HANDLE deviceHandle { lparam |= (1 << 30); } + + if (FakeMouseKeyboard::IsExtendedKeyStatePressed(data.VKey)) + { + lparam |= (1 << 24); // Set the extended-key flag + } PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_KEYDOWN, MessageFilterHook::IsKeyboardButtonFilterEnabled() ? data.VKey | KeyboardButtonFilter::signature : data.VKey, @@ -256,6 +261,11 @@ void RawInput::ProcessKeyboardInput(const RAWKEYBOARD& data, HANDLE deviceHandle lparam |= (1 << 30); // Previous key state (always 1 for key up) lparam |= (1 << 31); // Transition state (always 1 for key up) + if (FakeMouseKeyboard::IsExtendedKeyStatePressed(data.VKey)) + { + lparam |= (1 << 24); // Set the extended-key flag + } + PostMessageW((HWND)HwndSelector::GetSelectedHwnd(), WM_KEYUP, MessageFilterHook::IsKeyboardButtonFilterEnabled() ? data.VKey | KeyboardButtonFilter::signature : data.VKey, lparam); diff --git a/src/ProtoInput/ProtoInputHooks/SetWindowPosHook.cpp b/src/ProtoInput/ProtoInputHooks/SetWindowPosHook.cpp index e9a90cb..7738ac5 100644 --- a/src/ProtoInput/ProtoInputHooks/SetWindowPosHook.cpp +++ b/src/ProtoInput/ProtoInputHooks/SetWindowPosHook.cpp @@ -1,5 +1,6 @@ #include "SetWindowPosHook.h" #include +#include "HwndSelector.h" namespace Proto { @@ -25,14 +26,24 @@ BOOL WINAPI Hook_SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int void SetWindowPosHook::ShowGuiStatus() { int pos[2] = { posx, posy }; - ImGui::SliderInt2("Position", &pos[0], -5000, 5000); + ImGui::InputInt2("Position", &pos[0]); posx = pos[0]; posy = pos[1]; int size[2] = { width, height }; - ImGui::SliderInt2("Size", &size[0], 0, 5000); + ImGui::InputInt2("Size", &size[0]); width = size[0]; height = size[1]; + + ImGui::Separator(); + + if (ImGui::Button("Apply Changes")) + { + if ((HWND)HwndSelector::GetSelectedHwnd() != NULL) + { + ::SetWindowPos((HWND)HwndSelector::GetSelectedHwnd(), NULL, posx, posy, width, height, SWP_NOZORDER | SWP_NOACTIVATE); + } + } } void SetWindowPosHook::InstallImpl() diff --git a/src/ProtoInput/ProtoInputHooks/dllmain.cpp b/src/ProtoInput/ProtoInputHooks/dllmain.cpp index c8350b7..423afce 100644 --- a/src/ProtoInput/ProtoInputHooks/dllmain.cpp +++ b/src/ProtoInput/ProtoInputHooks/dllmain.cpp @@ -16,6 +16,7 @@ #include "FocusMessageLoop.h" #include "Gui.h" #include "FakeCursor.h" +#include "INISettings.h" HMODULE dll_hModule; @@ -45,6 +46,9 @@ DWORD WINAPI StartThread(LPVOID lpParameter) // Useful to add a pause if we need to attach a debugger // MessageBoxW(NULL, L"Press OK to start", L"", MB_OK); + // LoadConfig is an alternative way of setting the configuration values instead of using the pipe communication. + Proto::LoadConfig(); + Proto::HwndSelector::UpdateMainHwnd(); Proto::FocusMessageLoop::SetupThread();