how to use mouse move in WinAPI without lag? - c++

i hope to make a console when i click right button,
mouse move down little bit
i tried this code,
bool MouseMove(int x, int y)
{
INPUT input;
input.type = INPUT_MOUSE;
input.mi.mouseData = 0;
input.mi.time = 0;
input.mi.dx = x;
input.mi.dy = y;
input.mi.dwFlags = MOUSEEVENTF_MOVE;
SendInput(1, &input, sizeof(input));
return true;
}
HWND hWnd;
HHOOK hMSHook;
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= HC_ACTION)
{
if (wParam == WM_RBUTTONUP)
{
MouseMove(0, 10);
return 1;
}
}
return CallNextHookEx(hKBHook, nCode, wParam, lParam);
}
int _tmain() {
hWnd = ::GetConsoleWindow();
ShowWindow(hWnd, 0);
HMODULE hInstance = GetModuleHandle(NULL);
hMSHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, hInstance, NULL);
MSG Msg;
while (GetMessage(&Msg, NULL, 0, 0)) { DispatchMessage(&Msg); }
return 0;
}
It works fine, but if i try it few times,
it causing lag (struggle, slow, laggy)
someone know how to fix it?

Related

Raw Input - recive WM_INPUT while window/program is in background

I am trying to monitor and printout the RAWINPUT from a mouse sent to the foreground window, or just all RAWINPUT from the mouse in general.
the global hook LowLevelMouseProc does not work for me because it returns a MOUSEHOOKSTRUCT that does not give me the dx and dy.
The Raw Input API mentions that for WM_INPUT received when the current window is in the back ground, wParam will be set to RIM_INPUTSINK. But I have no idea how to receive WM_INPUT while the program is in the background.
here is some code explaining what I am trying to do.
int main()
{
//regiter the monitoring device
static bool raw_input_initialized = false;
if (raw_input_initialized == false)
{
RAWINPUTDEVICE rid;
rid.usUsagePage = 0x01; //Mouse
rid.usUsage = 0x02;
rid.dwFlags = 0;
rid.hwndTarget = NULL;
if (RegisterRawInputDevices(&rid, 1, sizeof(rid)) == FALSE)
{
exit(-1);
}
raw_input_initialized = true;
}
HWND targetWindow = { 0 };
while (true)
{
targetWindow = GetForegroundWindow(); // get the window runing in the formost window;
std::cout << targetWindow << '\n';
}
return 0;
}
// enterd every time there is a rawinput to ForegroundWindow, or alternatively just a rawinput in general
LRESULT CALLBACK targetWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
// print out the values that I need
case WM_INPUT:
UINT dataSize;
GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, NULL, &dataSize, sizeof(RAWINPUTHEADER)); //Need to populate data size first
std::cout << GET_RAWINPUT_CODE_WPARAM(wParam) << " code thing\n";
if (dataSize > 0)
{
std::unique_ptr<BYTE[]> rawdata = std::make_unique<BYTE[]>(dataSize);
if (GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, rawdata.get(), &dataSize, sizeof(RAWINPUTHEADER)) == dataSize)
{
RAWINPUT* raw = reinterpret_cast<RAWINPUT*>(rawdata.get());
if (raw->header.dwType == RIM_TYPEMOUSE)
{
std::cout << raw->data.mouse.lLastX << std::endl;
}
}
}
break;
}
}
But I have no idea how to receive WM_INPUT while the program is in the background.
You need to specify the RIDEV_INPUTSINK flag when registering the device, per the RAWINPUTDEVICE documentation:
dwFlags
Type: DWORD
Mode flag that specifies how to interpret the information provided by usUsagePage and usUsage. It can be zero (the default) or one of the following values. By default, the operating system sends raw input from devices with the specified top level collection (TLC) to the registered application as long as it has the window focus.
...
RIDEV_INPUTSINK
0x00000100
If set, this enables the caller to receive the input even when the caller is not in the foreground. Note that hwndTarget must be specified.
As such, you must specify an HWND to receive the WM_INPUT messages, and have a message loop to service that window.
Try this:
#include <iostream>
#include <vector>
#include <Windows.h>
LRESULT CALLBACK targetWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int main()
{
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASS wc = {};
wc.lpfnWndProc = targetWindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = TEXT("MyRawInputWnd");
if (!RegisterClass(&wc))
return -1;
HWND targetWindow = CreateWindowEx(0, wc.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, hInstance, NULL);
if (!targetWindow)
return -1;
//register the monitoring device
RAWINPUTDEVICE rid = {};
rid.usUsagePage = 0x01; //Mouse
rid.usUsage = 0x02;
rid.dwFlags = RIDEV_INPUTSINK;
rid.hwndTarget = targetWindow;
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
return -1;
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DestroyWindow(targetWindow);
return 0;
}
LRESULT CALLBACK targetWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
// print out the values that I need
case WM_INPUT: {
UINT dataSize;
GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, NULL, &dataSize, sizeof(RAWINPUTHEADER)); //Need to populate data size first
std::cout << GET_RAWINPUT_CODE_WPARAM(wParam) << " code thing\n";
if (dataSize > 0)
{
std::vector<BYTE> rawdata(dataSize);
if (GetRawInputData(reinterpret_cast<HRAWINPUT>(lParam), RID_INPUT, rawdata.data(), &dataSize, sizeof(RAWINPUTHEADER)) == dataSize)
{
RAWINPUT* raw = reinterpret_cast<RAWINPUT*>(rawdata.data());
if (raw->header.dwType == RIM_TYPEMOUSE)
{
std::cout << raw->data.mouse.lLastX << std::endl;
}
}
}
return 0;
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

Win32 SendInput mousemove lag and freeze

I am trying to move the mouse (on Windows 10) using SendInput when I perform a physical mouse click. It works fine if I click once or twice, but if clicking for examples 6 times in quick succession the mouse lags for a few seconds then the program stops responding.
Is there any obvious reason why this is happening?
(Edited)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
LRESULT CALLBACK MouseHook(int, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int)
{
HHOOK hook = SetWindowsHookEx(WH_MOUSE_LL, MouseHook, NULL, 0);
MessageBox(NULL, L"Hello", L"Hello", MB_OK);
UnhookWindowsHookEx(hook);
return 0;
}
LRESULT CALLBACK MouseHook(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION) {
switch (wParam) {
case WM_RBUTTONUP:
INPUT buffer;
ZeroMemory(&buffer, sizeof(buffer));
buffer.type = INPUT_MOUSE;
buffer.mi.dx = 0;
buffer.mi.dy = 10;
buffer.mi.mouseData = 0;
buffer.mi.dwFlags = MOUSEEVENTF_MOVE;
buffer.mi.time = 0;
buffer.mi.dwExtraInfo = 0;
SendInput(1, &buffer, sizeof(INPUT));
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
Using Raw Input sample:
#include <windows.h>
#include <iostream>
using namespace std;
BOOL registerTouchpadForInput(HWND hWnd)
{
RAWINPUTDEVICE rid;
rid.dwFlags = RIDEV_NOLEGACY | RIDEV_INPUTSINK;
rid.usUsagePage = 1;
rid.usUsage = 2;
rid.hwndTarget = hWnd;
return RegisterRawInputDevices(&rid, 1, sizeof(rid));
}
void getinputdata(LPARAM lparam)
{
HRAWINPUT hInput = (HRAWINPUT)lparam;
RAWINPUT input = { 0 };
UINT size = sizeof(RAWINPUT);
GetRawInputData(hInput, RID_INPUT,&input, &size,sizeof(RAWINPUTHEADER));
if (RIM_TYPEMOUSE == input.header.dwType)
{
if (input.data.mouse.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
{
INPUT buffer;
ZeroMemory(&buffer, sizeof(buffer));
buffer.type = INPUT_MOUSE;
buffer.mi.dx = 0;
buffer.mi.dy = 10;
buffer.mi.mouseData = 0;
buffer.mi.dwFlags = MOUSEEVENTF_MOVE;
buffer.mi.time = 0;
buffer.mi.dwExtraInfo = 0;
SendInput(1, &buffer, sizeof(INPUT));
}
}
return;
}
static LRESULT CALLBACK NVTouch_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
BOOL registrationStatus = false;
switch (message)
{
case WM_CREATE:
registrationStatus = registerTouchpadForInput(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_INPUT:
getinputdata(lParam);
return DefWindowProc(hwnd, message, wParam, lParam);
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
int main()
{
WNDCLASSEX wndclass = {
sizeof(WNDCLASSEX),
CS_DBLCLKS,
NVTouch_WindowProc,
0,
0,
GetModuleHandle(0),
LoadIcon(0,IDI_APPLICATION),
LoadCursor(0,IDC_ARROW),
HBRUSH(COLOR_WINDOW + 1),
0,
L"myclass",
LoadIcon(0,IDI_APPLICATION)
};
bool isClassRegistered = false;
isClassRegistered = RegisterClassEx(&wndclass);
if (isClassRegistered)
{
HWND window = CreateWindow(wndclass.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(0), NULL);
if (window)
{
ShowWindow(window, SW_SHOWDEFAULT);
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}

How to detect drag in a mouse hook procedure

I've successfully set up a mouse hook for a window, and I'd like to detect a drag operation when the left mouse button is clicked. I've tried using DragDetect, as shown below, but it never returns TRUE, and it never suppresses the subsequent mouse-up event (in this code, hwnd is the target window):
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0)
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
switch (wParam)
{
case WM_LBUTTONDOWN:
{
// Get the click point
LPMOUSEHOOKSTRUCT pMouseHookStruct = reinterpret_cast<LPMOUSEHOOKSTRUCT>(lParam);
CPoint ptClick = pMouseHookStruct->pt;
// Drag detect
BOOL fDrag = DragDetect(hwnd, ptClick);
if (fDrag)
{
MessageBox(NULL, L"Drag", NULL, MB_OK);
}
break;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
Does DragDetect not work within hook procedures, or am I just doing something wrong?
As comments pointed, DragDetect does not predict the future. But you can compare the POINT of WM_LBUTTONDOWN and WM_MOUSEMOVE in a click-time.
Sample:
#include <windows.h>
#include <iostream>
using namespace std;
typedef BOOL(*SETHOOK)(HWND hWnd);
typedef BOOL(*UNHOOK)();
LRESULT CALLBACK WndProcFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
int main(int argc, char* argv[])
{
WNDCLASS wc{};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProcFunc;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = L"Class_Name";
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
RegisterClass(&wc);
HWND hWnd = CreateWindow(L"Class_Name", L"Test", WS_OVERLAPPEDWINDOW, 0, 0, 1000, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
SETHOOK SetHook;
UNHOOK UnHook;
HMODULE h = LoadLibraryA("PATH\\DLL4.dll");
SetHook = (SETHOOK)GetProcAddress(h, "SetHook");
UnHook = (UNHOOK)GetProcAddress(h, "UnHook");
BOOL i = SetHook(hWnd);
ShowWindow(hWnd, 1);
UpdateWindow(hWnd);
MSG Msg;
while (GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
UnHook();
return 0;
}
DLL:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#define PRESS TRUE
#define RELEASE FALSE
HHOOK tHook;
HMODULE hinstDLL;
BOOL button = RELEASE;
BOOL Drag = FALSE;
HWND hWnd;
POINT pt = { 0 };
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode < 0)
{
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
LPMOUSEHOOKSTRUCT pMouseHookStruct = reinterpret_cast<LPMOUSEHOOKSTRUCT>(lParam);
if (pMouseHookStruct->hwnd != hWnd)
{
button = RELEASE;
Drag = FALSE;
}
else {
switch (wParam)
{
case WM_LBUTTONDOWN:
{
button = PRESS;
Drag = FALSE;
printf("WM_LBUTTONDOWN\n");
printf("%d , %d\n", pMouseHookStruct->pt.x, pMouseHookStruct->pt.y);
pt.x = pMouseHookStruct->pt.x;
pt.y = pMouseHookStruct->pt.y;
break;
}
case WM_LBUTTONUP:
{
button = RELEASE;
Drag = FALSE;
printf("WM_LBUTTONUP\n");
break;
}
case WM_MOUSEMOVE:
{
if (button == PRESS)
{
printf("%d , %d\n", pMouseHookStruct->pt.x, pMouseHookStruct->pt.y);
if (Drag == FALSE && (abs(pt.x - pMouseHookStruct->pt.x) >= GetSystemMetrics(SM_CXDRAG) || abs(pt.y - pMouseHookStruct->pt.y) >= GetSystemMetrics(SM_CYDRAG)))
{
printf("Drag\n");
Drag = TRUE;
}
}
break;
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
extern "C" __declspec(dllexport) BOOL SetHook(HWND hwnd)
{
hWnd = hwnd;
tHook = SetWindowsHookEx(WH_MOUSE, MouseProc, hinstDLL, 0);
if (tHook == NULL)
return FALSE;
else
return TRUE;
}
extern "C" __declspec(dllexport) BOOL UnHook()
{
return UnhookWindowsHookEx(tHook);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hinstDLL = hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

C++ clipboard queue pasting random results?

I'm trying to make a clipboard queue, allowing me to copy multiple things and then paste them FIFO. To do so, I'm using with Windows API as well as a basic keyboard hook to detect ctrl+c and ctrl+v. My code seems to work however I seem to constantly get a random output from the queue.
#include <Windows.h>
#include <stdio.h>
#include <vector>
using namespace std;
vector<char*> clipboardQueue;
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
if (wParam == WM_KEYDOWN) {
if (p->vkCode == 0x43 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-c is pressed
WM_COPY;
Sleep(500);
OpenClipboard(NULL);
char* buffer;
buffer = (char*)GetClipboardData(CF_TEXT);
CloseClipboard();
clipboardQueue.push_back(buffer);
cout << buffer << " copied!\n";
cout << "clipboard size: " << clipboardQueue.size() << "\n";
}
else if (p->vkCode == 0x56 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-v is pressed
if (clipboardQueue.size() > 0) {
const char* output = clipboardQueue[0];
const size_t len = strlen(output) + 1;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
memcpy(GlobalLock(hMem), output, len);
GlobalUnlock(hMem);
OpenClipboard(0);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
WM_PASTE;
clipboardQueue.erase(clipboardQueue.begin());
cout << output << " pasted!\n";
cout << "clipboard size: " << clipboardQueue.size() << "\n";
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int main()
{
OpenClipboard(NULL);
EmptyClipboard();
CloseClipboard();
HHOOK keyBoard = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, NULL);
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(keyBoard);
}
Using this code when copying "one, two, three, four, five" my outputs seem to be random with occassional missing keys entirely:
three
three
three
?
five
one
?
three
?
five
?
four
four
four
five
Key edits:
When copy data to clipboard using ctrl + c there will sent a WM_CLIPBOARDUPDATE message which you can use to monitor ctrl + c operations. But there is no related message to monitor paste control + v operation so I keep hook part for control + v.
I can reproduce "outputs seem to be random" issue and solve it using array instead of std::vector.
Create a message-only window if you don't need a interact UI.
Add a new custom clipboard format MY_CLIPBOARD_FORMAT to indicate this is set data cased WM_CLIPBOARDUPDATE message not actual control + v operation.
The following is just an example implement for your use case you can refer to:
#include <windows.h>
#define MAX_LOADSTRING 100
#define MY_CLIPBOARD_FORMAT (CF_PRIVATEFIRST + 1)
// Global Variables:
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
static int index = 0;
static char dataArry[10][10] = {};
// Forward declarations of functions included in this code module:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK LowLevelKeyboardProc(int, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
DWORD errorCode;
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// Initialize global strings
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_QUEUECLIPBOARDDATA, szWindowClass, MAX_LOADSTRING);
// Register window class
WNDCLASSEXW wcex = {};
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.lpszClassName = szWindowClass;
ATOM cls = RegisterClassExW(&wcex);
errorCode = GetLastError();
// Create a message-only window
HWND hWnd = CreateWindowEx(0, szWindowClass, szTitle, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
if (!hWnd)
{
errorCode = GetLastError();
return FALSE;
}
// Set keyboard hook
HHOOK keyBoard = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, NULL);
// Register a clipboard format listener
if (!AddClipboardFormatListener(hWnd))
errorCode = GetLastError();
MSG msg;
// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
if (wParam == WM_KEYDOWN) {
if (p->vkCode == 0x56 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-v is pressed
if(index <= 0)
return CallNextHookEx(NULL, nCode, wParam, lParam);
static int i = 0;
if (i < index)
{
const char* output = dataArry[i];
const size_t len = strlen(output) + 1;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
memcpy(GlobalLock(hMem), output, len);
GlobalUnlock(hMem);
OpenClipboard(0);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
// Set custom defined format to indicate paste operation
SetClipboardData(MY_CLIPBOARD_FORMAT, NULL);
CloseClipboard();
OutputDebugStringA("\n pasted!\n");
i++;
}
else
{
i = 0;
index = 0;
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
DWORD errorCode;
HANDLE clipObj = NULL;
char* lptstr = NULL;
switch (message)
{
case WM_CLIPBOARDUPDATE:
{
OutputDebugStringA("\nWM_CLIPBOARDUPDATE\n");
// Empty clipboard casue this WM_CLIPBOARDUPDATE, actually no new data copied
if (IsClipboardFormatAvailable(MY_CLIPBOARD_FORMAT))
break;
if (!IsClipboardFormatAvailable(CF_TEXT))
break;
if (!OpenClipboard(hWnd))
{
errorCode = GetLastError();
break;
}
clipObj = GetClipboardData(CF_TEXT);
if(NULL == clipObj)
{
errorCode = GetLastError();
break;
}
lptstr = (char*)GlobalLock(clipObj);
if (lptstr != NULL)
{
OutputDebugStringA(lptstr);
memcpy(dataArry[index++], lptstr, strlen(lptstr));
GlobalUnlock(lptstr);
}
CloseClipboard();
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

Is it possible to simulate mouse move and mouse clicks at hidden window?

So is there a way to make my Win32 application "think" that the mouse is moving over its window and making some clicks when the actual window is hidden (i mean ShowWindow(hWnd, SW_HIDE);)?
I tried to simulate mouse moving with PostMessage and SendMessage but no luck so far.
int x = 0;
int y = 0;
while (true)
{
SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
x += 10;
y += 10;
Sleep(100);
}
Is this even possible?
Yes it's possible. This is a test hidden window:
#define UNICODE
#include <Windows.h>
#include <Strsafe.h>
#include <Windowsx.h>
LRESULT CALLBACK WndProc(HWND Hwnd, UINT Msg, WPARAM WParam, LPARAM LParam);
INT CALLBACK
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
INT nCmdShow)
{
WNDCLASSEX WndClass;
ZeroMemory(&WndClass, sizeof(WNDCLASSEX));
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.lpfnWndProc = WndProc;
WndClass.hInstance = hInstance;
WndClass.lpszClassName = L"HiddenWinClass";
if(RegisterClassEx(&WndClass))
{
HWND Hwnd;
MSG Msg;
Hwnd = CreateWindowEx(0, L"HiddenWinClass", L"Nan",
0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
if(Hwnd)
{
UpdateWindow(Hwnd);
ShowWindow(Hwnd, SW_HIDE);
while(GetMessage(&Msg, 0, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
}
return 0;
}
LRESULT CALLBACK
WndProc(HWND Hwnd,
UINT Msg,
WPARAM WParam,
LPARAM LParam)
{
TCHAR Message[255];
switch(Msg)
{
case WM_MOUSEMOVE:
StringCbPrintf(Message, sizeof(Message), L"(%d, %d)",
GET_X_LPARAM(LParam), GET_Y_LPARAM(LParam));
MessageBox(NULL, Message, L"WM_MOUSEMOVE", MB_OK);
break;
default:
return DefWindowProc(Hwnd, Msg, WParam, LParam);
}
return 0;
}
and this is your code:
#define UNICODE
#include <Windows.h>
int
main(int argc, char **argv)
{
HWND Hwnd;
if((Hwnd = FindWindow(L"HiddenWinClass", L"Nan")))
{
int x, y;
for(x = y = 0 ; ; x += 10, y += 10)
{
SendMessage(Hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
Sleep(100);
}
}
return 0;
}
It works nicely.