Nurav
Nurav

Reputation: 177

How to record the distance travelled by my mouse cursor in win32 application?

I am working on a project on windows desktop development in C++ using win32 API .In the application I am trying to calculate the distance travelled by my mouse cursor or you can say mouse thrashing.

Thrashed Cursor—or thrashing cursor or mouse—isn’t some pun for a user so frustrated that they’re losing control of their arms while shouting expletives. Rather, Thrashed Cursor is when users erratically move their cursor back and forth.

Rapidly moving the cursor over a page can indicate the user is getting exasperated with some aspect of their experience. Perhaps the site performance is slow or they are struggling to figure something out. Thrashed Cursor is like a physical outpouring of some mental state in the user—and that state very likely could be frustration. Like all frustration signals, there is a chance of a false positive with Thrashed Cursor. E.g. perhaps the user has a broken mouse or their computer is so slow that they’re thrashing their mouse in protest. The only way to deduce if Thrashed Cursor is signalling frustration is to watch a session and make some observations.

by mouse thrashing i mean i want to record erratic movement of mouse cursor in search of any button or tool so i want to log total distance travelled in this erratic movement.

And i want to log this information of this session and send it to my server in json format.

During this thrashing user may click mouse which may generate WM_LBUTTONDOWN but I am using that message to perform some function i don't want that click when user was frustrated to invoke that particular function.

I am new in win32 desktop development if anyone who could help me.

Upvotes: 0

Views: 1076

Answers (3)

Nurav
Nurav

Reputation: 177

This is the method I have found without explicitly writing .dll and function for getting the thread of process . And without using Mouse Hooks.

  std::vector<POINT> pt;
    POINT p1 = { 0 };
    BOOL flag = 1;
    int x = 0, y = 0;
    int dis = 0;  



case WM_MOUSEMOVE:
            GetCursorPos(&point);
            pt.push_back(point);
            if (flag)
            {
                p1 = pt.back();
                flag = 0;   
            }
            x = abs(pt.back().x - p1.x);
            y = abs(pt.back().y - p1.y);
            dis += sqrt(x * x + y * y);
            p1 = pt.back();
            wchar_t waCoord1[20];
            wsprintf(waCoord1, _T("(%i)"), dis);
            OutputDebugString(waCoord1);

Upvotes: 0

Strive Sun
Strive Sun

Reputation: 6299

Yes thats exactly what i want to do but i dont know how to implement that i was thinking to log all the coordinates as the mouse moves and calculate the total distance.

SetWindowsHookEx and WH_MOUSE_LL can help you do this.

You can install mouse hook to monitor mouse movements and calculate the distance between mouse coordinates.

Code:

#include <Windows.h>
#include <iostream>
#include <vector>

using namespace std;

HHOOK mouseHook;
std::vector<POINT> pt;
POINT p1 = { 0 };
BOOL flag = 1;
int x = 0, y = 0;
int dis = 0;
LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{  
    if (nCode >= 0)
    {
        switch (wParam)
        {
        case WM_MOUSEMOVE:
            MSLLHOOKSTRUCT* MSLStruct = (MSLLHOOKSTRUCT*)lParam;
            pt.push_back(MSLStruct->pt);

            if (flag)
            {
                p1 = pt.back();
                flag = 0;
            }
            x = abs(pt.back().x - p1.x);
            y = abs(pt.back().y - p1.y);
            dis+=sqrt(x*x +y*y);
            p1 = pt.back();

            cout << dis << endl;

            return 0;
        }
    }
    return CallNextHookEx(mouseHook, nCode, wParam, lParam);
}

void SetHook()
{
    if (!(mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, NULL, 0)))
    {
        cout << "Failed to install mouse hook!" << endl;
    }
}

void ReleaseHook()
{
    UnhookWindowsHookEx(mouseHook);
}


int main()
{   
    SetHook();
    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;

    ReleaseHook();
}

Debug:

enter image description here

Updated:

.dll

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <vector>

HINSTANCE hinst;
#pragma data_seg(".shared")
HHOOK hhk;
#pragma data_seg()

std::vector<POINT> pt;
POINT p1 = { 0 };
BOOL flag = 1;
int x = 0, y = 0;
int dis = 0;

LRESULT CALLBACK wiremouseProc(int code, WPARAM wParam, LPARAM lParam) {
    if (code >= 0)
    {
        switch (wParam)
        {
        case WM_MOUSEMOVE:
            MSLLHOOKSTRUCT* MSLStruct = (MSLLHOOKSTRUCT*)lParam;
            pt.push_back(MSLStruct->pt);

            if (flag)
            {
                p1 = pt.back();
                flag = 0;
            }
            x = abs(pt.back().x - p1.x);
            y = abs(pt.back().y - p1.y);
            dis += sqrt(x * x + y * y);
            p1 = pt.back();

            std::cout << dis << std::endl;

            return 0;
        }
    }
    return CallNextHookEx(hhk, code, wParam, lParam);
}

extern "C" __declspec(dllexport) void install(unsigned long threadID) {
    hhk = SetWindowsHookEx(WH_MOUSE, wiremouseProc, hinst, threadID);
}
extern "C" __declspec(dllexport) void uninstall() {
    UnhookWindowsHookEx(hhk);
}

BOOL WINAPI DllMain(__in HINSTANCE hinstDLL, __in  DWORD fdwReason, __in  LPVOID lpvReserved) {
    hinst = hinstDLL;
    return TRUE;
}

.cpp

#include <Windows.h>
#include <stdio.h>
#include <tchar.h>

unsigned long GetTargetThreadIdFromWindow(const char* className, const char* windowName)
{
    HWND targetWnd;
    HANDLE hProcess;
    unsigned long processID = 0;

    targetWnd = FindWindow(className, windowName);
    return GetWindowThreadProcessId(targetWnd, &processID);
}

int main() {
    unsigned long threadID = GetTargetThreadIdFromWindow("Notepad", "1.txt - Notepad"); // Use Notepad for test
    printf("TID: %i", threadID);

    HINSTANCE hinst = LoadLibrary(_T("D:\\Test_WH_MOUSE\\Mydll\\Debug\\Mydll.dll"));

    if (hinst) {
        typedef void (*Install)(unsigned long);
        typedef void (*Uninstall)();

        Install install = (Install)GetProcAddress(hinst, "install");
        Uninstall uninstall = (Uninstall)GetProcAddress(hinst, "uninstall");

        install(threadID);

        MSG msg = {};

        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        uninstall();
    }

    return 0;
}

Debug:

enter image description here

Upvotes: 2

Adrian McCarthy
Adrian McCarthy

Reputation: 48019

I'm still not clear on what the problem is, but I've listed several guesses at the bottom.

Here's an example of the basic idea:

case WM_MOUSEMOVE:
    POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
    LogMouseMovementForTracking(pt);
    WhateverOtherStuffYouWantToDoWhenTheMouseMoves(pt);
    break;

case WM_LBUTTONDOWN:
    // You don't have to do tracking here.  You will almost certainly have
    // received a WM_MOUSEMOVE that brings you to the click before the
    // system sends you the WM_LBUTTONDOWN.
    WhateverYouWantToDoWhenTheButtonIsPressed();
    break;

Some of my guesses as to the problem your having:

  • Your window may not get WM_MOUSEMOVE messages when the mouse moves over (or is captured by) a child window, but you want to log those.
  • Your window is capturing the mouse (perhaps when you get a WM_LBUTTONDOWN), and that's making the WM_MOUSEMOVE logic more complicated.
  • You're trying to distinguish between thrashing and non-thrashing and log only the thrashing, but we (and possibly you) don't have a precise definition of what thrashing is.
  • You want your application to see all mouse movement of the Windows session, not just mouse movement within your application window.
  • You accidentally have one case in your switch statement falling through into another.

If you could clarify the question more, we could probably help you out.

Upvotes: 0

Related Questions