如何在win32应用程序中记录鼠标光标移动的距离?

问题描述 投票:0回答:1

我正在做一个用C++语言使用win32 API开发windows桌面的项目,在这个项目中,我试图计算我的鼠标光标所走过的距离,或者你可以说是鼠标颤动。

Thrashed Cursor-or thrashing cursor or mouse-isn't some punish for a user so frustrated that they're losing control of their arms while shouting exprevesves. 相反,Thrashed Cursor是指用户不规则地来回移动光标。

在页面上快速移动光标可能表明用户对他们体验的某些方面感到恼火。也许是网站的性能很慢,或者是他们正在努力地想弄明白什么。鸫鸟光标就像是用户某种心理状态的身体发泄--这种状态很可能是挫折感。像所有的挫折信号一样,Thrashed Cursor也有可能出现假阳性。例如,也许用户的鼠标坏了,或者他们的电脑太慢了,以至于他们用鼠标来抗议。推断颤动光标是否为挫折信号的唯一方法是观察一个会话并进行一些观察。

鼠标颤动的意思是,我想记录鼠标光标在搜索任何按钮或工具时的不稳定运动,所以我想记录这种不稳定运动中的总距离。

我想记录这个会话的信息,并以json格式发送到我的服务器。

在这个过程中,用户可能会点击鼠标,这可能会产生以下信息 WM_LBUTTONDOWN 但我使用该消息来执行一些功能,我不希望点击时,用户是沮丧地调用该特定功能。

我是个新手 win32 桌面开发,如果有人能帮助我。

c++ json winapi logging mouse-cursor
1个回答
1
投票

是的,这正是我想做的,但我不知道如何实现,我想记录鼠标移动时的所有坐标,并计算总距离。

SetWindowsHookExWH_MOUSE_LL 可以帮助你做到这一点。

您可以安装鼠标钩来监控鼠标的移动并计算鼠标坐标之间的距离。

代码。

#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();
}

调试。

enter image description here

更新:

.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;
}

调试。

enter image description here


0
投票

我仍然不清楚问题出在哪里 但我在底部列出了几个猜测。

下面是一个基本思路的例子。

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;

我对你所遇到的问题的一些猜测:

  • 你的窗口可能没有得到 WM_MOUSEMOVE 鼠标移动到(或被)一个子窗口上时,你要记录这些信息。
  • 你的窗口正在捕捉鼠标(也许当你得到一个 WM_LBUTTONDOWN),这就使 WM_MOUSEMOVE 逻辑更复杂。
  • 你试图区分乱动和非乱动,并且只记录乱动,但我们(可能还有你)并没有精确定义什么是乱动。
  • 你希望你的应用程序能够看到Windows会话的所有鼠标移动,而不仅仅是应用程序窗口内的鼠标移动。
  • 你不小心让你的switch语句中的一个case掉到了另一个case中。

如果你能更清楚地说明这个问题,我们也许可以帮助你。


0
投票

这是我找到的方法,而没有明确地写上 .dll 和函数来获取进程的线程,而且不需要使用鼠标钩。

  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);
© www.soinside.com 2019 - 2024. All rights reserved.