Created
February 11, 2021 23:56
-
-
Save gynvael/ff39eeb91b114d86ebab56d65823a600 to your computer and use it in GitHub Desktop.
Fake cursor always shown on top of all other windows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Show a triangle at mouse position, always on top. | |
// Warning: This was coded in 40 minutes, so the quality isn't the greatest :shrug: | |
// Blame: Gynvael Coldwind (2021) | |
// Known issues: | |
// - The "cursor" doesn't change between a normal arrow / text arrow / etc. It's just a triangle. | |
// - There is a minor lag to the "cursor" changing position. | |
// - Size probably doesn't adjust to DPI. Didn't test. | |
// - The "cursor" is a pixel off - that's kinda a workaround to not block the actual cursor's hot point. | |
// How to compile: | |
// g++ cursor_on_top.cc -Wall -Wextra -lgdi32 -o cursor_on_top.exe | |
// Just use mingw-w64 installer to get a compiler if you don't have one: | |
// https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/installer/mingw-w64-install.exe | |
#include <windows.h> | |
#include <stdio.h> | |
#define IDT_TIMER1 1001 | |
#define W 12 | |
#define H 20 | |
LONG prevX = -1; | |
LONG prevY = -1; | |
POINT arrow[] = { | |
{ 1, 1 }, | |
{ W, H }, | |
{ 1, H }, | |
{ 1, 1 } | |
}; | |
HRGN arrowRgn; | |
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { | |
switch (uMsg) { | |
case WM_CREATE: { | |
SetTimer(hwnd, IDT_TIMER1, 17 /* 59 fps */, NULL); | |
arrowRgn = CreatePolygonRgn(arrow, sizeof(arrow) / sizeof(arrow[0]), ALTERNATE); | |
SetWindowRgn(hwnd, arrowRgn, TRUE); | |
} | |
break; | |
case WM_TIMER: { | |
POINT p; | |
GetCursorPos(&p); | |
if (p.x == prevX && p.y == prevY) { | |
break; | |
} else { | |
prevX = p.x; | |
prevY = p.y; | |
MoveWindow(hwnd, p.x + 1, p.y + 1, W, H, TRUE); | |
} | |
} | |
break; | |
case WM_NCHITTEST: | |
return HTNOWHERE; | |
case WM_CLOSE: | |
KillTimer(hwnd, IDT_TIMER1); | |
DestroyWindow(hwnd); | |
PostQuitMessage(0); | |
break; | |
default: | |
return DefWindowProc(hwnd, uMsg, wParam, lParam); | |
} | |
return 0; | |
} | |
int main(void) { | |
HINSTANCE hInstance = GetModuleHandle(NULL); | |
WNDCLASS wc{}; | |
wc.lpfnWndProc = WindowProc; | |
wc.hInstance = hInstance; | |
wc.lpszClassName = "FakeMouseCursorClass"; | |
RegisterClass(&wc); | |
HWND hwnd = CreateWindowEx( | |
WS_EX_TOPMOST | WS_EX_NOACTIVATE /*| WS_EX_TRANSPARENT | WS_EX_LAYERED*/, | |
"FakeMouseCursorClass", | |
"FakeMouseCursor", | |
WS_POPUP | WS_VISIBLE | WS_BORDER, | |
50, 50, W, H, | |
NULL, | |
NULL, | |
hInstance, | |
NULL | |
); | |
ShowWindow(hwnd, SW_SHOW); | |
MSG msg{}; | |
while (GetMessage(&msg,0,0,0) > 0) { | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment