Last active
May 2, 2018 09:52
-
-
Save EAirPeter/117e00f26ed7df6516d031741039eb9a to your computer and use it in GitHub Desktop.
按CTRL-ALT-Q,自动点击鼠标下窗口的相对坐标,间隔200ms。再次按CTRL-ALT-Q停止。https://enza.fun/game/1?code=f85c45f2-c7c7-4e7c-a17a-eb282c7c5f78&openExternalBrowser=1
This file contains 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
#include <Windows.h> | |
#include <math.h> | |
#include <stdio.h> | |
void ErrorExit(const char *pszWhat) { | |
auto dwError = GetLastError(); | |
char *pBuf; | |
FormatMessageA( | |
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | |
nullptr, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &pBuf, 0, nullptr | |
); | |
fprintf(stderr, "%s failed: %s\n", pszWhat, pBuf); | |
LocalFree(pBuf); | |
fprintf(stderr, "Press Enter to exit..."); | |
getchar(); | |
ExitProcess(dwError); | |
} | |
int main() { | |
if (!RegisterHotKey(nullptr, 0, MOD_CONTROL | MOD_ALT, 'Q')) | |
ErrorExit("RegisterHotKey"); | |
bool bActive = false; | |
UINT_PTR uTimer {}; | |
MSG vMsg {}; | |
HWND hWndActive {}; | |
POINT vPointActive {}; | |
while (GetMessageA(&vMsg, nullptr, 0, 0)) { | |
switch (vMsg.message) { | |
case WM_HOTKEY: { | |
if (bActive) { | |
if (!KillTimer(nullptr, uTimer)) | |
ErrorExit("KillTimer"); | |
printf("Stopped\n"); | |
bActive = false; | |
break; | |
} | |
struct Info { | |
HWND hWnd; | |
RECT vRect; | |
POINT vPoint; | |
double dDist; | |
} vInfo {nullptr, {}, {}, 0.0}; | |
if (!GetCursorPos(&vInfo.vPoint)) | |
ErrorExit("GetCursorPos"); | |
auto hWnd = WindowFromPoint(vInfo.vPoint); | |
EnumChildWindows(hWnd, [] (HWND hWnd, LPARAM lPar) -> BOOL { | |
auto pInfo = (Info *) lPar; | |
if (!IsWindowVisible(hWnd)/* || !IsWindowEnabled(hWnd)*/) | |
return TRUE; | |
RECT vRect; | |
if (!GetWindowRect(hWnd, &vRect)) | |
return TRUE; | |
auto &vPoint = pInfo->vPoint; | |
if (vPoint.x < vRect.left || vPoint.x > vRect.right) | |
return TRUE; | |
if (vPoint.y < vRect.top || vPoint.y > vRect.bottom) | |
return TRUE; | |
auto dX = (double) (vRect.left + vRect.right) / 2.0; | |
auto dY = (double) (vRect.top + vRect.bottom) / 2.0; | |
auto dDist = hypot(dX - vPoint.x, dY - vPoint.y); | |
bool bUpdate = !pInfo->hWnd; | |
if (!bUpdate) { | |
bUpdate = true; | |
bUpdate &= vRect.left >= pInfo->vRect.left && vRect.right <= pInfo->vRect.right; | |
bUpdate &= vRect.top >= pInfo->vRect.top && vRect.bottom <= pInfo->vRect.bottom; | |
if (!bUpdate) { | |
bUpdate |= vRect.left > pInfo->vRect.left || vRect.right < pInfo->vRect.right; | |
bUpdate |= vRect.top > pInfo->vRect.top || vRect.bottom < pInfo->vRect.bottom; | |
bUpdate &= dDist < pInfo->dDist; | |
} | |
} | |
if (bUpdate) { | |
pInfo->hWnd = hWnd; | |
pInfo->vRect = vRect; | |
pInfo->dDist = dDist; | |
} | |
return TRUE; | |
}, (LPARAM) &vInfo); | |
hWndActive = vInfo.hWnd ? vInfo.hWnd : hWnd; | |
vPointActive = vInfo.vPoint; | |
char aBuf[4096]; | |
GetWindowTextA(hWndActive, aBuf, 4096); | |
if (!ScreenToClient(hWndActive, &vPointActive)) | |
ErrorExit("ScreenToClient"); | |
uTimer = SetTimer(nullptr, 0, 200, nullptr); | |
if (!uTimer) | |
ErrorExit("SetTimer"); | |
printf("Started [%p] [%s]: x = %ld, y = %ld\n", (void *) hWndActive, aBuf, vPointActive.x, vPointActive.y); | |
bActive = true; | |
break; | |
} | |
case WM_TIMER: { | |
if (!PostMessageA(hWndActive, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(vPointActive.x, vPointActive.y))) | |
ErrorExit("PostMessage WM_LBUTTONDOWN"); | |
if (!PostMessageA(hWndActive, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(vPointActive.x, vPointActive.y))) | |
ErrorExit("PostMessage WM_LBUTTONUP"); | |
break; | |
} | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment