实现在目标窗口获得鼠标移动的像素点。

实现在目标窗口获得鼠标移动的像素点。效果如下图!
求指点,设了钩子但是不知道,就是不知道要用哪个API

img

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
要实现在目标窗口获得鼠标移动的像素点,需要用到Windows操作系统提供的Hook机制。Hook机制可以让我们截取并处理操作系统发出的事件,包括鼠标事件、键盘事件等。在本次场景中,我们需要使用的是鼠标Hook。

以下是实现步骤:

  1. 使用Windows API函数SetWindowsHookEx注册一个鼠标钩子,参数中指定钩子类型为WH_MOUSE,并指定回调函数。
  2. 当系统发出鼠标事件时,回调函数将被自动调用。在回调函数中,获取鼠标移动的坐标,并使用Windows API函数SendMessage发送自定义消息到目标窗口。
  3. 在目标窗口中,重载处理自定义消息的函数,并在其中处理鼠标移动坐标,并绘制相应的像素点。

下面是示例代码:

#include <windows.h>

// 全局变量,用于保存目标窗口句柄
HWND g_hTargetWnd = NULL;

// 自定义消息,用于通知目标窗口获取鼠标移动坐标
#define WM_MOUSEMOVE_MSG (WM_USER + 100)

// 鼠标Hook回调函数
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    // 检查Hook是否可用
    if (nCode < 0)
    {
        return CallNextHookEx(NULL, nCode, wParam, lParam);
    }

    switch (wParam)
    {
    case WM_MOUSEMOVE:
    {
        // 获取鼠标移动的坐标
        int x = ((MSLLHOOKSTRUCT*)lParam)->pt.x;
        int y = ((MSLLHOOKSTRUCT*)lParam)->pt.y;

        // 发送自定义消息到目标窗口
        SendMessage(g_hTargetWnd, WM_MOUSEMOVE_MSG, NULL, MAKELPARAM(x, y));
        break;
    }
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // 获取目标窗口句柄
    g_hTargetWnd = FindWindow(NULL, "窗口标题");

    // 注册鼠标Hook
    HHOOK hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseHookProc, hInstance, 0);

    // 进入消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // 卸载Hook
    UnhookWindowsHookEx(hMouseHook);

    return 0;
}

// 目标窗口消息处理函数
LRESULT CALLBACK TargetWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_MOUSEMOVE_MSG:
    {
        // 获取鼠标移动坐标
        int x = LOWORD(lParam);
        int y = HIWORD(lParam);

        // TODO: 在目标窗口中处理鼠标移动坐标,并绘制相应的像素点

        break;
    }
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

注意事项:

  1. 鼠标Hook需要在主线程中注册,因此示例代码中使用WinMain作为入口函数。
  2. 注册Hook时,需要传递当前程序实例句柄、钩子类型以及回调函数地址。
  3. 钩子回调函数需要检查Hook是否可用,避免无限递归调用。
  4. 目标窗口必须存在,并且使用正确的窗口标题进行查找。
  5. 自定义消息使用了WM_USER + 100,可以根据需要自定义,但必须保证不与系统自带的消息冲突。
  6. 目标窗口需要处理自定义消息,并在其中处理鼠标移动坐标。具体处理方式可以根据实际需求进行设计。

希望这份代码对你有所帮助!
如果我的回答解决了您的问题,请采纳!

“Devil组”引证GPT后的撰写:
要在Windows操作系统中获取鼠标移动的像素点,需要使用鼠标钩子(Mouse Hook)来监视鼠标事件。在C++中,可以使用以下API实现:

  • SetWindowsHookEx函数 - 用于安装鼠标钩子。
  • 在回调函数中处理鼠标消息,可以获得鼠标的坐标信息,并进行处理。
  • 在处理鼠标坐标信息时,需要记录下上一次鼠标的位置,计算出鼠标移动的像素点,并输出到控制台。

下面是一个简单的C++代码示例,可以实现在目标窗口中获取鼠标移动的像素点:

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

using namespace std;

HHOOK g_hHook = NULL;
POINT g_lastPos = {0, 0};

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HC_ACTION && (wParam == WM_MOUSEMOVE || wParam == WM_LBUTTONDOWN))
    {
        POINT pos = *((POINT*)lParam);
        int dx = pos.x - g_lastPos.x;
        int dy = pos.y - g_lastPos.y;
        cout << "你在[" << GetTickCount() << "]秒时水平移动了[" << dx << "]像素,竖直移动了[" << dy << "]像素" << endl;
        g_lastPos = pos;
    }
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

int main()
{
    g_hHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, NULL, 0);
    if (g_hHook == NULL)
    {
        cout << "SetWindowsHookEx failed" << endl;
        return -1;
    }

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

    UnhookWindowsHookEx(g_hHook);

    return 0;
}

安装了一个鼠标低级钩子(WH_MOUSE_LL),并在回调函数中处理鼠标消息。每当鼠标移动或者左键按下时,就计算出鼠标移动的像素点,并输出到控制台。同时,还记录下鼠标的上一个位置,以便计算移动距离。最后,用GetMessage函数来等待消息,并在收到WM_QUIT消息时退出循环。在程序退出前,需要卸载钩子,以释放资源。

该回答引用ChatGPT
要在C++中实现在目标窗口中获取鼠标移动的像素点,可以使用Windows API中的鼠标事件和窗口消息处理函数。



#include <Windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // 创建窗口
    HWND hwnd = CreateWindowEx(
        0,
        "MyWindowClass",    // 窗口类名
        "My Window",        // 窗口标题
        WS_OVERLAPPEDWINDOW, // 窗口样式
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, // 窗口位置和大小
        NULL, NULL, hInstance, NULL);

    if (hwnd == NULL)
    {
        MessageBox(NULL, "窗口创建失败!", "错误", MB_ICONERROR);
        return 0;
    }

    // 注册窗口消息处理函数
    WNDCLASSEX wc;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "MyWindowClass";
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "窗口类注册失败!", "错误", MB_ICONERROR);
        return 0;
    }

    // 显示窗口
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static int last_x = -1;
    static int last_y = -1;

    switch (uMsg)
    {
        case WM_MOUSEMOVE:
        {
            int x = LOWORD(lParam);
            int y = HIWORD(lParam);

            if (last_x != -1 && last_y != -1)
            {
                int dx = x - last_x;
                int dy = y - last_y;

                // 在此处处理鼠标移动事件
                // 可以调用特定的函数,将dx和dy作为参数传递进去

                // 示例代码:将移动的像素点输出到控制台
                printf("Mouse moved by %d pixels horizontally and %d pixels vertically.\n", dx, dy);
            }

            last_x = x;
            last_y = y;

            break;
        }
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }

    return 0;
}


参考gpt和自己的思路,要在Windows中实现在目标窗口获得鼠标移动的像素点,可以使用鼠标钩子(Mouse Hook)。

以下是一个使用C++和Windows API实现鼠标钩子的示例代码:


#include <windows.h>

// 全局变量
HHOOK mouseHook = NULL;

// 钩子回调函数
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HC_ACTION) {
        PMSLLHOOKSTRUCT pMSLLHookStruct = (PMSLLHOOKSTRUCT)lParam;

        // 如果鼠标在移动
        if (wParam == WM_MOUSEMOVE) {
            HWND targetWindow = FindWindow(NULL, "目标窗口标题"); // 替换成目标窗口的标题
            if (targetWindow != NULL) {
                // 转换坐标系
                POINT point;
                point.x = pMSLLHookStruct->pt.x;
                point.y = pMSLLHookStruct->pt.y;
                ScreenToClient(targetWindow, &point);

                // 在目标窗口中获取鼠标位置的颜色
                HDC hdc = GetDC(targetWindow);
                COLORREF color = GetPixel(hdc, point.x, point.y);
                ReleaseDC(targetWindow, hdc);

                // 输出颜色值
                printf("x=%d, y=%d, color=0x%06X\n", point.x, point.y, color);
            }
        }
    }

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

// 安装鼠标钩子
void InstallMouseHook() {
    if (mouseHook == NULL) {
        mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, NULL, 0);
    }
}

// 卸载鼠标钩子
void UninstallMouseHook() {
    if (mouseHook != NULL) {
        UnhookWindowsHookEx(mouseHook);
        mouseHook = NULL;
    }
}

int main() {
    // 安装钩子
    InstallMouseHook();

    // 运行消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // 卸载钩子
    UninstallMouseHook();

    return 0;
}


在这个示例代码中,我们使用了Windows API中的SetWindowsHookEx函数来安装鼠标钩子,使用GetMessage函数运行消息循环。在钩子回调函数中,我们首先检查nCode是否为HC_ACTION,如果是,则检查wParam是否为WM_MOUSEMOVE,如果是,则获取鼠标位置的颜色,并将其输出到控制台。在获取颜色之前,我们还需要先将鼠标位置从屏幕坐标系转换到目标窗口的客户区坐标系,这可以使用ScreenToClient函数来实现。

需要注意的是,如果想要在钩子回调函数中操作目标窗口,需要先使用FindWindow函数来获取目标窗口的句柄。

可以使用Windows API的GetCursorPos函数来获取鼠标的像素坐标。该函数可以获取当前活动窗口中的鼠标坐标,并将其存储在POINT结构中。你可以使用该结构中的x和y坐标来获取鼠标移动的像素点。

下面是一个示例代码,希望它可以帮助你实现你的目标:

#include <windows.h>

int main()
{
    POINT pt;
    GetCursorPos(&pt);
    int x = pt.x;
    int y = pt.y;
    // Do something with the x and y coordinates
    return 0;
}

我希望这些信息对你有帮助!😊

题主,这个问题我来替你解决,若有帮助,还望采纳,点击回答右侧采纳即可。

示例代码如下:题主可以参考一下



```cpp
#include<iostream>
#include <stdio.h>
#include<windows.h>

#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0) //必要
using namespace std;

int main()
{
    POINT p;
    while (true)
    {
        printf("鼠标左键是否按下:");
        //mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
        //    Sleep(10);//要留给某些应用的反应时间
        //mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
        //MOUSEEVENTF_LEFTDOWN
        //MOUSEEVENTF_RIGHTDOWN
        if(KEY_DOWN(MOUSE_MOVED))
        {
            GetCursorPos(&p);//获取鼠标坐标
            printf("是 x:%d y:%d",p.x,p.y);
        }
        else
        {
            printf("否");
        }
        printf("\n");
        printf("鼠标右键是否按下:");
        if(KEY_DOWN(MOUSE_EVENT))
        {
            GetCursorPos(&p);//获取鼠标坐标
            printf("是 x:%d y:%d",p.x,p.y);
        }
        else
        {
            printf("否");
        }
        printf("\n");
        printf("鼠标滚轮键是否按下:");
        if(KEY_DOWN(MOUSE_WHEELED))
        {
            printf("是");
        }
        else
        {
            printf("否");
        }
        
        printf("\n");
        
        Sleep(20);//循环时间间隔,防止太占内存
        system("cls");//清屏
    }
}