我正在做一个用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
桌面开发,如果有人能帮助我。
是的,这正是我想做的,但我不知道如何实现,我想记录鼠标移动时的所有坐标,并计算总距离。
SetWindowsHookEx 和 WH_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();
}
调试。
更新:
.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;
}
调试。
我仍然不清楚问题出在哪里 但我在底部列出了几个猜测。
下面是一个基本思路的例子。
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
逻辑更复杂。如果你能更清楚地说明这个问题,我们也许可以帮助你。
这是我找到的方法,而没有明确地写上 .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);