Winapi 从Windows上的三个鼠标读取输入

Winapi 从Windows上的三个鼠标读取输入,winapi,input,Winapi,Input,我想读取来自多个鼠标的输入,因为我想创建能够对鼠标传感器做出反应的木制踏板。我已经做了我自己的方向盘,它工作得很好,但我想创造加速和刹车。我发现了一些关于rawinputapi的有用信息,可以从不同的hid(人机界面设备)读取原始输入。但它只适用于一个应用程序。如果我点击另一个窗口,它就不工作了。我读过关于flag RIDEV_INPUTSINK的文章,但它也不起作用 有人知道如何从多个鼠标读取输入吗 这是我的代码: //#define _WIN32_WINNT 0x0501 // Iden

我想读取来自多个鼠标的输入,因为我想创建能够对鼠标传感器做出反应的木制踏板。我已经做了我自己的方向盘,它工作得很好,但我想创造加速和刹车。我发现了一些关于rawinputapi的有用信息,可以从不同的hid(人机界面设备)读取原始输入。但它只适用于一个应用程序。如果我点击另一个窗口,它就不工作了。我读过关于flag RIDEV_INPUTSINK的文章,但它也不起作用

有人知道如何从多个鼠标读取输入吗

这是我的代码:

//#define _WIN32_WINNT 0x0501   // Identify this as a Windows XP application.  
This is necessary

//    to pull in RawInput (which is an XP exclusive)

#define WM_INPUT 0x00FF

char mousemessage[256]; // this is the string we draw to the screen for the 
first mouse 

char mousemessage2[256]; // this is the string we draw to the screen for the 
second mouse 

char rawinputdevices[256]; // string with number of raw input devices

                          //    so we can access rawinput

#include <windows.h>

#include <Winuser.h>

#include <stdlib.h>

#include <string.h>



HWND handle_notepad = FindWindowA(NULL, "Untitled - Notepad");

void InitRawInput()
{
RAWINPUTDEVICE Rid[50]; // allocate storage for 50 device (not going to need this many :) )

UINT nDevices;

PRAWINPUTDEVICELIST pRawInputDeviceList;

if (GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
{
    return;
}

pRawInputDeviceList = (RAWINPUTDEVICELIST*)malloc(sizeof(RAWINPUTDEVICELIST) * nDevices);

GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST));

// do the job...

wsprintf(rawinputdevices, "Number of raw input devices: %i\n\n", nDevices);

// after the job, free the RAWINPUTDEVICELIST

free(pRawInputDeviceList);

Rid[0].usUsagePage = 0x01;

Rid[0].usUsage = 0x02;

//Rid[0].dwFlags = RIDEV_NOLEGACY |
//  RIDEV_CAPTUREMOUSE;
//Rid[0].dwFlags = RIDEV_INPUTSINK;
Rid[0].dwFlags = 0; // RIDEV_NOLEGACY;   // adds HID mouse and also ignores legacy mouse messages

Rid[0].hwndTarget = 0;
//Rid[0].hwndTarget = NULL;



if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE)
{
    wsprintf(mousemessage, "RawInput init failed:\n");

    //registration failed. 
}

// Change position of the window

handle_notepad = FindWindowA(NULL, "Untitled - Notepad");
if (handle_notepad != NULL)
{
    OutputDebugString(TEXT("Gites !\n"));
    //SetWindowPos(handle_notepad, NULL, 100, 100, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
}

return;
}



LRESULT CALLBACK MainWndProc(HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
static HWND   hwndButton = 0;

static int    cx, cy;          /* Height and width of our button. */

HDC           hdc;             /* A device context used for drawing */

PAINTSTRUCT   ps;              /* Also used during window drawing */

RECT          rc;              /* A rectangle used during drawing */

LPBYTE lpb;// = new BYTE[dwSize];//LPBYTE lpb = new BYTE[dwSize];

UINT dwSize;

RAWINPUT* raw;

long tmpx, tmpy;



static long maxx = 0;

switch (nMsg)
{
case WM_DESTROY:
{
    PostQuitMessage(0);
    return 0;
    break;
}
case WM_PAINT:
{
    hdc = BeginPaint(hwnd, &ps);

    GetClientRect(hwnd, &rc);

    DrawText(hdc, mousemessage, strlen(mousemessage), &rc, DT_CENTER);

    OffsetRect(&rc, 0, 200); // move the draw position down a bit

    DrawText(hdc, rawinputdevices, strlen(rawinputdevices), &rc, DT_CENTER);

    EndPaint(hwnd, &ps);

    return 0;

    break;
}
case WM_INPUT:
{
    GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize,
        sizeof(RAWINPUTHEADER));



    lpb = (LPBYTE)malloc(sizeof(LPBYTE) * dwSize);

    if (lpb == NULL)
    {
        return 0;
    }



    if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize,
        sizeof(RAWINPUTHEADER)) != dwSize)

        OutputDebugString(TEXT("GetRawInputData doesn't return correct size !\n"));



    raw = (RAWINPUT*)lpb;



    //SetWindowPos(handle_notepad, NULL, 100, 100, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);

    

    if (raw->header.dwType == RIM_TYPEMOUSE)
    {
        OutputDebugString(TEXT("NOM !\n"));
        MoveWindow(handle_notepad, 100, 100, 400, 200, FALSE);

        tmpx = raw->data.mouse.lLastX;

        tmpy = raw->data.mouse.lLastY;

        //if (tmpx > maxx) 

        maxx = tmpx;

        /* Convert to Directx format */

        //if ((tmpx > 0xff00))

          //{ 

            //tmpx = -(0xffff - tmpx);

          //wsprintf(mousemessage, "TMPX WAS HUGE!!!  %ld", tmpx);

          //  }

        //if (tmpy > 0xff00) tmpy = -(0xffff - tmpy);



        wsprintf(mousemessage, "Mouse:hDevice %d \n usFlags=%04x \nulButtons=%04x \nusButtonFlags=%04x \nusButtonData=%04x \nulRawButtons=%04x \nlLastX=%ld \nlLastY=%ld \nulExtraInformation=%04x\r, %ld\n",

            raw->header.hDevice,

            raw->data.mouse.usFlags,

            raw->data.mouse.ulButtons,

            raw->data.mouse.usButtonFlags,

            raw->data.mouse.usButtonData,

            raw->data.mouse.ulRawButtons,

            tmpx, //raw->data.mouse.lLastX, 

            tmpy, //raw->data.mouse.lLastY, 

            raw->data.mouse.ulExtraInformation),

            maxx;

    }

    InvalidateRect(hwnd, 0, TRUE);

    SendMessage(hwnd, WM_PAINT, 0, 0);



    free(lpb);

    return 0;
}
}

return DefWindowProc(hwnd, nMsg, wParam, lParam);
}



int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
{
OutputDebugString(TEXT("START !\n"));

HWND         hwndMain;        /* Handle for the main window. */

MSG          msg;             /* A Win32 message structure. */

WNDCLASSEX   wndclass;        /* A window class structure. */

const char* szMainWndClass = "WinTestWin";

/* The name of the main window class */



memset(&wndclass, 0, sizeof(WNDCLASSEX));

wndclass.lpszClassName = szMainWndClass;

wndclass.cbSize = sizeof(WNDCLASSEX);

wndclass.style = CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc = MainWndProc;

wndclass.hInstance = hInst;

wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);

wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

RegisterClassEx(&wndclass);

hwndMain = CreateWindow(

    //WS_EX_COMPOSITED,// | WS_EX_LAYERED | WS_EX_NOACTIVATE |
    //WS_EX_TOPMOST,// | WS_EX_TRANSPARENT,

    szMainWndClass,             /* Class name */

    "Hello",                    /* Caption */

    //WS_DISABLED | 
    //WS_POPUP | WS_VISIBLE,

    WS_OVERLAPPEDWINDOW,        /* Style */

    CW_USEDEFAULT,              /* Initial x (use default) */

    CW_USEDEFAULT,              /* Initial y (use default) */

    CW_USEDEFAULT,              /* Initial x size (use default) */

    CW_USEDEFAULT,              /* Initial y size (use default) */

    NULL,                       /* No parent window */

    NULL,                       /* No menu */

    hInst,                      /* This program instance */

    NULL                        /* Creation parameters */
);

ShowWindow(hwndMain, nShow);

UpdateWindow(hwndMain);

InitRawInput();

//DWORD mainId;
//DWORD notepadId;
//GetWindowThreadProcessId(hwndMain, mainId);
//GetWindowThreadProcessId(handle_notepad, notepadId);
//AttachThreadInput(lpdwProcessId, 2, true);



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

    DispatchMessage(&msg);
}

return msg.wParam;
}
/#定义_WIN32_WINNT 0x0501//将其标识为Windows XP应用程序。
这是必要的
//拉入RawInput(XP专用)
#定义WM_输入0x00FF
char mousemessage[256];//这是我们在屏幕上绘制的字符串
第一只老鼠
char mousemessage2[256];//这是我们在屏幕上绘制的字符串
第二只老鼠
char rawinputdevices[256];//包含原始输入设备数的字符串
//这样我们就可以访问RAW输入
#包括
#包括
#包括
#包括
HWND handle_notepad=FindWindowA(NULL,“无标题的记事本”);
void InitRawInput()
{
RAWINPUTDEVICE Rid[50];//为50个设备分配存储(不需要这么多:)
设备;
PRAWINPUTDEVICELIST PRAWINPUTDEVICELIST;
if(GetRawInputDeviceList(NULL,&nDevices,sizeof(RAWINPUTDEVICELIST))!=0)
{
返回;
}
pRawInputDeviceList=(RAWINPUTDEVICELIST*)malloc(sizeof(RAWINPUTDEVICELIST)*设备);
GetRawInputDeviceList(pRawInputDeviceList,&nDevices,sizeof(RAWINPUTDEVICELIST));
//做这项工作。。。
wsprintf(rawinputdevices,“原始输入设备的数量:%i\n\n”,nDevices);
//作业完成后,释放RAWINPUTDEVICELIST
免费(pRawInputDeviceList);
Rid[0]。usUsagePage=0x01;
Rid[0]。usUsage=0x02;
//Rid[0]。dwFlags=RIDEV\u NOLEGACY|
//RIDEV_捕获小鼠;
//Rid[0]。dwFlags=RIDEV\u INPUTSINK;
Rid[0].dwFlags=0;//RIDEV\u NOLEGACY;//添加HID鼠标并忽略旧鼠标消息
Rid[0]。hwndTarget=0;
//Rid[0]。hwndTarget=NULL;
if(registerRarWinPutDevices(Rid,1,sizeof(Rid[0]))==FALSE)
{
wsprintf(mousemessage,“RawInput init失败:\n”);
//注册失败。
}
//改变窗户的位置
handle_notepad=FindWindowA(NULL,“Untitled-notepad”);
if(handle_notepad!=NULL)
{
OutputDebugString(文本(“Gites!\n”);
//SetWindowPos(句柄\记事本,空,100,100,0,0,SWP\ U NOZORDER | SWP\ U NOSIZE | SWP\ U SHOWWINDOW);
}
返回;
}
LRESULT回调MainWndProc(HWND HWND、UINT nMsg、WPARAM WPARAM、LPARAM LPARAM)
{
静态HWND hwndButton=0;
静态int cx,cy;/*按钮的高度和宽度*/
HDC HDC;/*用于绘图的设备上下文*/
PAINTSTRUCT ps;/*也用于窗口绘制*/
RECT rc;/*绘图过程中使用的矩形*/
LPBYTE lpb;//=新字节[dwSize];//LPBYTE lpb=新字节[dwSize];
单位尺寸;
原始输入*raw;
长tmpx,tmpy;
静态长maxx=0;
交换机(nMsg)
{
案例WM_销毁:
{
PostQuitMessage(0);
返回0;
打破
}
案例WM_油漆:
{
hdc=开始喷漆(hwnd和ps);
GetClientRect(hwnd和rc);
DrawText(hdc、mousemessage、strlen(mousemessage)和rc、DT_中心);
OffsetRect(&rc,0200);//将绘图位置向下移动一点
DrawText(hdc、rawinputdevices、strlen(rawinputdevices)和rc、DT_中心);
端漆(hwnd和ps);
返回0;
打破
}
案例WM_输入:
{
GetRawInputData((HRAWINPUT)LPRAM、RID_输入、NULL和dwSize,
sizeof(rawinputhreader));
lpb=(LPBYTE)malloc(sizeof(LPBYTE)*dwSize);
如果(lpb==NULL)
{
返回0;
}
如果(GetRawInputData((HRAWINPUT)LPRAM、RID_输入、lpb和dwSize,
sizeof(rawinputhreader))!=dwSize)
OutputDebugString(文本(“GetRawInputData未返回正确的大小!\n”);
原始=(原始输入*)lpb;
//SetWindowPos(句柄\记事本,空,100,100,0,0,SWP\ U NOZORDER | SWP\ U NOSIZE | SWP\ U SHOWWINDOW);
if(原始->header.dwType==RIM\u TYPEMOUSE)
{
OutputDebugString(文本(“NOM!\n”));
移动窗口(手柄_记事本,100100400200,假);
tmpx=raw->data.mouse.lLastX;
tmpy=raw->data.mouse.lLastY;
//如果(tmpx>maxx)
maxx=tmpx;
/*转换为Directx格式*/
//如果((tmpx>0xff00))
//{ 
//tmpx=-(0xffff-tmpx);
//wsprintf(鼠标信息,“TMPX太大了!!!%ld”,TMPX);
//  }
//如果(tmpy>0xff00)tmpy=-(0xffff-tmpy);
wsprintf(mousemessage,“鼠标:hDevice%d\n usFlags=%04x\nulButtons=%04x\nusbuttonnflags=%04x\nusbuttonda=%04x\nulRawButtons=%04x\nLastx=%ld\nLasty=%ld\nLextranformation=%04x\r,%ld\n”,
原始->header.hDevice,
原始->data.mouse.usFlags,
原始->data.mouse.ul按钮,
原始->data.mouse.usButtonFlags,
原始->data.mouse.usbuttonda,
原始->data.mouse.ulRawButtons,
tmpx,//raw->data.mouse.lLastX,
tmpy,//raw->data.mouse.lLastY,
原始->数据.mouse.ulextranformation),
maxx;
}
无效(hwnd,0,真);
SendMessage(hwnd,WM_-PAINT,0,0);
免费(lpb);
返回0;
}
}
返回DefWindowProc(hwnd、nMsg、wParam、lParam);
}
int APICENTRY WinMain(HINSTANCE hInst、HINSTANCE hPrev、LPSTR lpCmd、int nShow)
{
OutputDebugString(文本(“开始!\n”));
HWND hwndMain;/*主窗口的句柄*/
MSG;/*一种Win32消息结构*/
WNDCLASSEX wndclass;/*窗口类结构*/
const char*szMainWndClass=“WinTestWin”;
/*主窗口类的名称*/
memset(&wndclass,0,sizeof(WNDCLASSEX));
wndclass.lpszClassName=szMainWndClass;
wndclass.cbSize=sizeof(WNDCLASSEX);
wndclass.style=CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc=MainWndProc;
wndclass.hInstance=hInst;
wndclass.hIcon=Loa
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
using namespace std;
LRESULT CALLBACK MouseHook(int, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
    MSG msg;
    HHOOK hook = SetWindowsHookEx(WH_MOUSE_LL, MouseHook, NULL, 0);
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, NULL, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    UnhookWindowsHookEx(hook);
    return 0;
}

LRESULT CALLBACK MouseHook(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HC_ACTION) {
        switch (wParam)
        {
        case WM_LBUTTONDOWN:
        {
            HWND handle_notepad = FindWindowA(NULL, "Untitled - Notepad");
            SetWindowPos(handle_notepad, NULL, 100, 100, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
            return 0;
        }
        }
    }

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