在简单的 main() 中获取rawinputdata

2024-03-14

我正在尝试使用简单的 C++ 技术和 Windows 从操纵杆读取值。 我的目标是编写一个程序,每当操纵杆信号超过预定义阈值时,该程序就会发送键盘命令。键盘命令将由当时处于活动状态的窗口拾取。

我的 C++ 编码技能有限,因此我希望以最简单的方式完成此操作,最好在一个 main() 内。

到目前为止我已经成功注册了操纵杆。

但我偶然发现了第一个问题,即如何使用 GetRawInputData()。我在 win32 结构中找到了很多关于此的示例,但我正在努力将其转换为简单的 main()。

到目前为止我的代码如下:

#include <windows.h>
#include <iostream>

RAWINPUTDEVICE Rid[1];

int main()
{
    UINT      bufferSize;

    Rid[0].usUsagePage = 0x01;
    Rid[0].usUsage = 0x05;
    Rid[0].dwFlags = 0;
    Rid[0].hwndTarget = 0;

    if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE)
    {
        std::cout << "Registration failed" << std::endl;
        return 1;
    }
    else
    {
        std::cout << "Registration OK" << std::endl;

        while (1)
        {
            // This is the part in which I would like to read the joystick values
            // and determine whether to send a keyboard event or not.
        }


    }

    return 0;

}

你能帮我吗?

Thanks.

UPDATE

按照使用 JoyGetInput() 的建议,以下是更新后的代码:

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

using namespace std;

#define mid 32767
#define trig 1804
#define reset 1475

int main()
{

    JOYINFO pos;

    UINT result;
    SYSTEMTIME st;
    INPUT xi, yi, zi;

    int i = 0;
    int state[6] = { 0,0,0,0,0,0 };
    int uu = mid + trig;
    int ul = mid + reset;

    xi.type = INPUT_KEYBOARD;
    yi.type = INPUT_KEYBOARD;
    zi.type = INPUT_KEYBOARD;

    while (1)
    {
        result = joyGetPos(i, &pos);

        if (result != JOYERR_NOERROR)
        {
            cout << "JoyID " << i << " returned an error. Trying the next one." << endl;
            i++;
            if (i > 15)
            {
                cout << "Reached the maximum allowed attempts. Exiting." << endl;
                return 1;
            }               
        }
        else
        {
            //GetSystemTime(&st);

            //cout << st.wHour << ":" << st.wMinute << ":" << st.wSecond << ":" << st.wMilliseconds <<  "\tX: " << pos.wXpos << "\tY: " << pos.wYpos << "\tZ: " << pos.wZpos << endl;

            if (pos.wXpos > uu && state[0] == 0)
            {
                xi.ki.wVk = 0x30;
                xi.ki.dwFlags = 0;
                SendInput(1, &xi, sizeof(INPUT));
                state[0] = 1;
                GetSystemTime(&st);
                cout << "Key down - X axis" << endl;
                cout << st.wHour << ":" << st.wMinute << ":" << st.wSecond << ":" << st.wMilliseconds << "\tX: " << pos.wXpos << "\tY: " << pos.wYpos << "\tZ: " << pos.wZpos << endl;
            }
            if (pos.wXpos < ul && state[0] == 1)
            {
                xi.ki.wVk = 0x30;
                xi.ki.dwFlags = KEYEVENTF_KEYUP;
                SendInput(1, &xi, sizeof(INPUT));
                state[0] = 0;
                GetSystemTime(&st);
                cout << "Key up - X axis" << endl;
                cout << st.wHour << ":" << st.wMinute << ":" << st.wSecond << ":" << st.wMilliseconds << "\tX: " << pos.wXpos << "\tY: " << pos.wYpos << "\tZ: " << pos.wZpos << endl;
            }
        }
    }

    return 0;
}

我现在的新问题是: 如何模拟长按键?我希望目标窗口的行为就像用户一直按住该键一样。使用上述代码,密钥仅发出一次。


GetRawInputData() https://msdn.microsoft.com/en-us/library/windows/desktop/ms645596.aspx需要一个HRAWINPUT处理作为输入。您可以获得该句柄的唯一地方是从LPARAM的参数WM_INPUT https://msdn.microsoft.com/en-us/library/windows/desktop/ms645590.aspx窗口消息。

Your main()需要使用函数CreateWindow/Ex()创建一个窗口(如果您不希望用户看到它,请考虑制作一个仅消息窗口 https://msdn.microsoft.com/en-us/library/windows/desktop/ms632599.aspx#message_only),在操纵杆的窗口中指定该窗口RAWINPUTDEVICE::hwndTarget当你打电话时字段RegisterRawInputDevices() https://msdn.microsoft.com/en-us/library/windows/desktop/ms645600.aspx,然后运行消息循环以便窗口可以接收消息。例如:

#include <windows.h>
#include <iostream>

int main()
{
    WNDCLASSEX wx = {};
    wx.cbSize = sizeof(WNDCLASSEX);
    wx.lpfnWndProc = DefWindowProc;
    wx.hInstance = GetModuleHandle(NULL);
    wx.lpszClassName = TEXT("MyRawInputWndClass");

    if (!RegisterClassEx(&wx))
    {
        std::cout << "Window Class Registration failed" << std::endl;
        return 1;
    }

    HWND hWnd = CreateWindowEx(0, wx.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, wx.hInstance, NULL);
    if (!hWnd)
    {
        std::cout << "Window Creation failed" << std::endl;
        return 1;
    }

    RAWINPUTDEVICE Rid = {};
    Rid.usUsagePage = 0x01;
    Rid.usUsage = 0x05;
    Rid.dwFlags = 0;
    Rid.hwndTarget = hWnd;

    if (!RegisterRawInputDevices(&Rid, 1, sizeof(RAWINPUTDEVICE)))
    {
        std::cout << "Device Registration failed" << std::endl;
        return 1;
    }

    std::cout << "Device Registration OK" << std::endl;

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (msg.message == WM_INPUT)
        {
            HRAWINPUT hRawInput = reinterpret_cast<HRAWINPUT>(msg.lParam);
            // retrieve and process data from hRawInput as needed...
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return 0;
}

或者:

#include <windows.h>
#include <iostream>

LRESULT CALLBACK MyWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    if (Msg == WM_INPUT)
    {
        HRAWINPUT hRawInput = reinterpret_cast<HRAWINPUT>(lParam);
        // retrieve and process data from hRawInput as needed...
    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}

int main()
{
    WNDCLASSEX wx = {};
    wx.cbSize = sizeof(WNDCLASSEX);
    wx.lpfnWndProc = &MyWndProc;
    wx.hInstance = GetModuleHandle(NULL);
    wx.lpszClassName = TEXT("MyRawInputWndClass");

    if (!RegisterClassEx(&wx))
    {
        std::cout << "Window Class Registration failed" << std::endl;
        return 1;
    }

    HWND hWnd = CreateWindowEx(0, wx.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, wx.hInstance, NULL);
    if (!hWnd)
    {
        std::cout << "Window Creation failed" << std::endl;
        return 1;
    }

    RAWINPUTDEVICE Rid = {};
    Rid.usUsagePage = 0x01;
    Rid.usUsage = 0x05;
    Rid.dwFlags = 0;
    Rid.hwndTarget = hWnd;

    if (!RegisterRawInputDevices(&Rid, 1, sizeof(RAWINPUTDEVICE)))
    {
        std::cout << "Device Registration failed" << std::endl;
        return 1;
    }

    std::cout << "Device Registration OK" << std::endl;

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

    return 0;
}

我建议你阅读原始输入文档 https://msdn.microsoft.com/en-us/library/windows/desktop/ms645536.aspx更仔细地。这一切都得到了详细解释。如果您没有指定窗口RegisterRawInputDevices(),操作系统将发送WM_INPUT向当前具有键盘焦点的窗口发送消息,这不是您想要的。

话虽如此,如果您想要更简单的东西,您可以考虑使用joyGetPosEx() https://msdn.microsoft.com/en-us/library/dd757108.aspx而不是原始输入。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在简单的 main() 中获取rawinputdata 的相关文章

  • 是否可以更改 WPF 控件的父级

    是否可以更改 WPF 控件的父控件 这是一个例子 StackPanel堆栈1有Buttonbtn1 在里面 还有一个空的StackPanel堆栈2 我想以编程方式将 btn1 移动到 stack2 谢谢您的帮助 您可以通过以下方式执行此操作
  • C# Socket.receive连续接收0字节且循环中不阻塞

    我正在尝试用 C 编写一个最简单的多线程 TCP 服务器 它接收来自多个客户端的数据 每次连接新客户端时 都会建立套接字连接 并将套接字作为参数传递给新类函数 之后运行 while 循环并接收数据 直到客户端连接为止 这里的问题是 sock
  • Lambda、封闭变量、显示类、可序列化性和流行层

    我已经为 Compact Framework 实现了一个流行层 包括BinaryFormatter 类似序列化器 我希望能够在适当的情况下序列化编译器生成的类 这些类是由 lambda 和迭代器等产生的 这样如果 例如 lambda 及其封
  • Linux 缓冲区溢出环境变量

    我一直在审查不同类型的缓冲区溢出 并遇到了一个我不记得为什么会发生的问题 下面的代码是我尝试执行缓冲区溢出的程序 include
  • 将 MyGeneration 与 Fluent NHibernate 结合使用

    我在这里找到了一个使用 MyGeneration 生成 NHibernate 代码的绝佳模板 http vucetica blogspot com 2009 01 nhibernate template for my Generation
  • 如何将 list 对象附加到另一个对象

    在 C 中 我有两个list
  • 提高 ASP.NET/C# 编译速度的最佳方法是什么?

    更新 请将您的答案集中在硬件解决方案上 您使用什么硬件 工具 插件来提高 ASP NET 编译和首次执行速度 我们正在寻找固态硬盘来加快速度 但现在价格确实很高 我现在有两个 RAID 0 的 7200 rpm 硬盘 但我对性能不再满意 所
  • 将 size_t 变量添加到指针

    我想向指针添加 size t 类型 有些像这样 void function size t sizeA size t sizeB void pointer pointer malloc sizeA pointer pointer sizeB
  • 使用 .NET Core Razor Pages 将文件下载到浏览器

    使用 ASP NET Razor Pages 我尝试将文件下载到浏览器 在页面 html 中 使用这样的链接效果很好 href DownloadableFiles testB csv download newname gt Download
  • 如何获取 TFS 2013 中所有用户的列表

    我正在使用 Team Foundation Server TFS 2013 和 Visual studio 2012 我需要 TFS 中所有用户的列表 有没有办法使用C 获取TFS中的所有用户 从TFS 2010获取用户列表 您可以尝试使用
  • 实体框架..自引用表..获取深度=x的记录?

    我成功地在实体框架中使用自引用表 但我不知道如何获得所需深度的记录 这应该是什么逻辑 Model public class FamilyLabel public FamilyLabel this Children new Collectio
  • 二叉树实现C++

    二叉树插入 include stdafx h include
  • 为什么这是一个未定义的行为?

    我的回答这个问题 https stackoverflow com q 18706587 845092这个函数是 inline bool divisible15 unsigned int x 286331153 2 32 1 15 40086
  • C# SerialPort BaseStream ReadAsync - CancellationToken 从未取消?

    我尝试以异步方式从串行端口读取数据 请记住操作所花费的时间不得超过指定的时间段 我使用的代码 private async Task
  • 产量回报延迟迭代问题

    我知道yield return 利用了延迟加载 但我想知道我是否可能滥用迭代器或者很可能需要重构 我的递归迭代器方法返回给定的所有祖先PageNode包括pageNode itself public class PageNodeIterat
  • C# 中的自定义按钮:如何删除悬停背景?

    我正在尝试使用 Visual Studio 2005 对我的表单 其 FormBorderStyle none 执行自定义按钮 我在链接到该按钮的 ImageList 中有我的 3 种状态按钮图像 this btnClose AutoSiz
  • 如何将 typedef 结构传递给函数?

    此刻我正在努力 void avg everything 但这给了我错误 error subscripted value is neither array nor pointer 当我今天早些时候收到此错误时 这是 因为我没有正确地将 2D
  • C++ 头文件包含

    我正在开发一个项目 每个头文件都有一个预处理器包含防护 我的包含是这样的 文件 gt 包含 main cpp gt header h 字符 h header h gt 矢量 iostream DataFiles h Character h
  • Web 服务无法使用 GAC 中的类型创建类型错误

    遇到一个不寻常的问题时 我似乎喜欢做一些不常见的事情 我有一个复合控件 它检查给定的 Web 服务文件是否存在于我的应用程序的根目录中 如果不存在 它会在标记中创建带有必要指令的文件以进行滚动 如下所示 反过来 它被保存到输出中 完成此步骤
  • 如何让c代码执行hex机器代码?

    我想要一个简单的 C 方法能够在 Linux 64 位机器上运行十六进制字节码 这是我的 C 程序 char code x48 x31 xc0 include

随机推荐

  • 如何使用CodeMirror动态切换模式?

    如何使用CodeMirror动态切换模式 我有默认设置 但需要切换它 像这样的东西会对你有帮助 首先 设置CodeMirror this editor CodeMirror fromTextArea document getElementB
  • 使用 dplyr 的过滤器和 mutate 生成新变量

    我选择 hflights dataset 作为示例 我尝试创建一个包含飞机 TailNum 的变量 列 但仅限于飞行时间最长的 10 以下的飞机 install packages hflights library hflights flig
  • Git GUI 崩溃信号 6

    我正在使用 git 版本 1 9 2 和 Xcode6 Beta3 一开始 git gui 工作正常 由于某种原因 我不知道 在终端上输入 git gui 时 我收到以下崩溃消息 由于未捕获的异常 NSInternalInconsisten
  • 获取由 Worksheet.Copy 复制的最后一个工作表的句柄

    我正在尝试获取通过复制操作创建的工作表的句柄 以下代码曾经有效 Dim wsTempl As Worksheet pageCount as Long Set wsTempl Sheets Template For pageCount 1 T
  • Java中子线程会继承父线程的ThreadScope吗?

    在Java中 我有一个Thread A If A产生一个子线程 b does b可以访问任何 所有ThreadLocal由设置的变量A 如果你的意思是InheritableThreadLocal 扩展ThreadLocal 那么是的 每个子
  • 刷新后保持 WebSocket 连接处于活动状态

    我有一个实时应用程序 它在 java spring 服务器和浏览器之间使用 WebSockets 有没有办法在页面刷新后保持 Websocket 连接处于活动状态 这是我的 JavaScript 代码 consumerWebSocket n
  • 如何使用 $arrayElemAt 并从 MongoDB $projection 中的该元素中删除字段?

    我有 工作 和 用户 集合 每个用户都可以为给定的 jobCategoryId 创建一个作业 然后该作业将保存在 jobs 集合中 并包含其创建者的 userId 和 jobCategoryId 我正在尝试合并这两个集合 因此当我获取作业时
  • 当用户在 Android 中更改为静默模式时执行代码

    我正在使用一项服务 在该服务中 当用户更改为静默模式时 我的代码应该被执行 即一旦用户更改为静默模式 我的代码就需要被执行 我怎样才能做到这一点 您不想使用服务 相反 你想使用广播接收器 http developer android com
  • 使用innerHTML在某个div中显示JSON/对象数据

    我创建了以下 JS 代码 加载 HTML 文档时 脚本会正确显示三个位置数据集
  • 启动带有嵌入式 Tomcat 的 Spring Boot 应用程序时如何配置堆大小?

    我正在尝试部署一个春季启动 https projects spring io spring boot 为生产提供支持的 Web 应用程序 该应用程序是使用 Spring Boot 1 0 1 构建的 并嵌入了默认的 Tomcat 7 作为应
  • 如何在调试模式下编译? (netbeans、java、maven)

    我在项目中面临注释 持久性错误 并且持久性库抛出 NullPointerException when trying to resolve the entities org eclipse persistence internal jpa m
  • Galaxy Tab 出现奇怪的性能问题

    我正在编写 2d 教程 并且能够在 Samsung Galaxy Tab 上测试我当前的教程部分 本教程只是在屏幕上随机移动默认图标 通过点击 我创建了一个新的移动图标 只要屏幕上有 25 个或更少的元素 Galaxy 上的一切都可以正常运
  • Linux 上 Objective-C 的 IDE [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在学习 Objective C 我想知道在哪里可以找到 Linux 上 Objective C 的
  • 加载逗号后空格不一致的 CSV 文件

    我想使用加载 CSV 文件LOAD DATA INFILE命令 但逗号后面的空格不一致 即有些逗号后面跟着空格 有些逗号后面没有空格 我尝试使用FIELDS TERMINATED BY 指令 但结果表中的某些字段包含前导空格 如果输入是 a
  • 如何将我自己的存储库分叉到新项目中?

    我正在开发一个 HTML5 游戏引擎 我使用 Git 作为 SV 并使用 GitHub 来实际托管该项目 我在设计上做了一些实质性的改变 主要是切换到实体系统范例 我认为是时候换一个新引擎了 我想将它建立在旧引擎的基础上 因为我可以使用很多
  • Javascript:添加动态方法的更好方法?

    我想知道是否有更好的方法向现有对象添加动态方法 基本上 我试图动态地组装新方法 然后将它们附加到现有函数中 该演示代码有效 builder function fn methods method builder for p in method
  • 加载 JSON 文件时出现内存错误

    当我加载 500Mo 大的 JSON 文件时 Python 和间谍程序 返回 MemoryError 但我的电脑有 32Go RAM 当我尝试加载它时 spyder 显示的 内存 从 15 变为 19 看来我应该有更多的空间 有什么我没想到
  • 将网络抓取的响应保存为 csv 文件

    我从网站下载了一个文件rvest 如何将回复另存为csv file Step 1 猴子补丁rvest像这个线程中的包 如何在 Rvest 包中提交登录表单 不带按钮参数 https stackoverflow com questions 3
  • 如何在silverlight3.0中播放Youtube视频

    我正在开发一个 silverlight 应用程序 我想在其中播放 youtube 视频 任何建议请 可供参考的任何示例或任何链接 提前致谢 这里有一个关于这个问题的有趣主题 其中包含 SL 3 0 beta 中的一些示例 http silv
  • 在简单的 main() 中获取rawinputdata

    我正在尝试使用简单的 C 技术和 Windows 从操纵杆读取值 我的目标是编写一个程序 每当操纵杆信号超过预定义阈值时 该程序就会发送键盘命令 键盘命令将由当时处于活动状态的窗口拾取 我的 C 编码技能有限 因此我希望以最简单的方式完成此