在简单的 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 的相关文章

  • 使用 gcc 在 Linux 上运行线程构建块 (Intel TBB)

    我正在尝试为线程构建块构建一些测试 不幸的是 我无法配置 tbb 库 链接器找不到库 tbb 我尝试在 bin 目录中运行脚本 但这没有帮助 我什至尝试将库文件移动到 usr local lib 但这又失败了 任何的意见都将会有帮助 确定您
  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 如何使用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 编码技能有限 因此我希望以最简单的方式完成此