Skip to content

Instantly share code, notes, and snippets.

@nguyentruongtho
Created March 18, 2022 23:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nguyentruongtho/c8a035e0bdc4aa1e98fff667b8347fdc to your computer and use it in GitHub Desktop.
Save nguyentruongtho/c8a035e0bdc4aa1e98fff667b8347fdc to your computer and use it in GitHub Desktop.
Prevents the game from freezing when interacting with the title bar.
// reversed from https://gist.github.com/shavitush/0d25bc384b52412f035e959fc71d6ce4
auto __stdcall hooks::CreateWindowExA(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle,
int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) -> HWND
{
auto hWnd = trampolines::CreateWindowExA(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
if(std::strcmp(lpClassName, "MapleStoryClass") == 0)
{
wndproc::original = reinterpret_cast<WNDPROC>(::SetWindowLongA(hWnd, GWLP_WNDPROC, reinterpret_cast<long long>(wndproc::custom_wndproc)));
}
return hWnd;
}
auto wndproc::custom_wndproc(HWND hWnd, unsigned int msg, unsigned int wParam, int lParam) -> LRESULT
{
if(!(msg == WM_SYSKEYDOWN && wParam == VK_F4) && !wndproc::unfreeze_messages(hWnd, msg, wParam, lParam))
{
return false;
}
return ::CallWindowProcA(wndproc::original, hWnd, msg, wParam, lParam);
}
auto wndproc::unfreeze_messages(HWND hWnd, unsigned int msg, unsigned int wParam, int lParam) -> bool
{
static bool bMoving{};
static POINT ptOffset{};
static LRESULT nLastSpot{};
const auto on_release_capture = [hWnd]() -> void
{
if(nLastSpot == HTCLOSE)
{
::PostQuitMessage(EXIT_SUCCESS);
bMoving = false;
::ReleaseCapture();
return;
}
else if(nLastSpot == HTMAXBUTTON)
{
::CallWindowProcA(wndproc::original, hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
return;
}
else if(nLastSpot == HTMINBUTTON)
{
::ShowWindow(hWnd, SW_MINIMIZE);
return;
}
bMoving = false;
::ReleaseCapture();
};
const auto drag_window = [hWnd]() -> void
{
if((::GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0)
{
if(bMoving)
{
POINT ptCursor;
::GetCursorPos(&ptCursor);
::SetWindowPos(hWnd, nullptr, ptCursor.x - ptOffset.x, ptCursor.y - ptOffset.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
}
else if(bMoving)
{
bMoving = false;
::ReleaseCapture();
}
};
const auto drag_title_bar = [hWnd]() -> void
{
if(nLastSpot == HTCAPTION)
{
RECT rcWnd;
::GetWindowRect(hWnd, &rcWnd);
POINT ptCursor;
::GetCursorPos(&ptCursor);
ptOffset.x = ptCursor.x - rcWnd.left;
ptOffset.y = ptCursor.y - rcWnd.top;
::SetCapture(hWnd);
bMoving = true;
}
};
switch(msg)
{
case WM_NCMOUSEMOVE:
nLastSpot = wParam;
break;
case WM_MOUSEMOVE:
nLastSpot = HTCLIENT;
drag_window();
break;
case WM_LBUTTONUP:
case WM_NCLBUTTONUP:
on_release_capture();
break;
case WM_NCLBUTTONDOWN:
drag_title_bar();
[[fallthrough]];
case WM_NCRBUTTONDOWN:
case WM_NCRBUTTONUP:
return false;
case WM_RBUTTONUP:
return !bMoving;
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment