如何伪造键盘移键。 Qt,Windows 10

Posted

技术标签:

【中文标题】如何伪造键盘移键。 Qt,Windows 10【英文标题】:How to fake a keyboard shift press. Qt, Windows 10 【发布时间】:2018-08-20 04:44:34 【问题描述】:

我为基于触控的平板电脑开发了一些软件。该装置没有键盘,只有一个触摸屏(触摸屏模拟鼠标)。操作系统是 Windows 10,我们使用 Qt 作为图形用户界面框架。

我们依赖于一个类库点云库,它有一个组件,当我们单击鼠标左键时,该组件需要按下 SHIFT 键才能使某些事情发生。

我需要让底层软件组件相信已按下 SHIFT 键。

我试图通过“Qt 手段”将按键事件发送到 Qt 小部件,但假的 SHIFT 按键似乎没有到达底层 sw。零件。可能是因为它位于与 Qt 无关的类库中,并且该软件类库可能以不同方式检查关键事件(例如通过操作系统调用、c++ std 方式或类似方式)。

在尝试“Qt 方式”时这似乎不起作用:

QKeyEvent key_press(QEvent::KeyPress, Qt::Key_Shift, Qt::ShiftModifier);
QApplication::sendEvent(ui->qvtkWidget, &key_press);

因此,我可能需要使用操作系统方法来伪造 SHIFT 按键。

问题: 如何从 Qt 执行 OS 系统调用或类似操作,以使底层软件组件认为已按下并按住 SHIFT 键(同时用户按下鼠标左键)。

【问题讨论】:

也许这可以帮助你:batchloaf.wordpress.com/2012/04/17/… 强烈的迹象表明这是XY Problem。请解释点云库的确切作用,当您按住 shift 单击时(以及在哪里)。如果一切都失败了,您是否尝试过发送QMouseEvent?它允许您在单击时发送键盘修饰符。但是,根据库的确定方式,是否按住 [Shift] 键,您可能不走运。尤其是与 Qt 一起使用时,会出现令人麻木的消息处理实现。 由于我怀疑按下 shift 键是您的实际目标,而只是达到目的的一种手段,因此更优雅的方法是直接告诉底层软件组件将其行为更改为(无论行为按下shift键时有)。当然,这可能需要对底层软件组件进行修改,如果这不可能,那么您可能会留下黑客(例如假装按下 shift 键)作为您唯一的选择,但这不是最好的方法。 【参考方案1】:

您想要的不是伪造换档键输入,而是在交互级别禁用换档检查。绝对是 XY 问题。

vtk InteractorStyle 类负责处理用户输入事件。您可以在 pcl_visualizer.cpp 的line 506 中看到

boost::signals2::connection
pcl::visualization::PCLVisualizer::registerPointPickingCallback (boost::function<void (const pcl::visualization::PointPickingEvent&)> callback)

  return (style_->registerPointPickingCallback (callback));

回调在PCLVisualizerInteractorStyle 类中注册。

您可以在PCLVisualizer 的构造中传递您自己的自定义交互器样式,以便您可以安全地覆盖这个样式。要使用的构造函数是这个one

PCLVisualizer (int &argc, char **argv, const std::string &name="", PCLVisualizerInteractorStyle *style=PCLVisualizerInteractorStyle::New(), const bool create_interactor=true) 

PointPickingCallback 类在初始化默认交互器样式时被 added automatically 作为鼠标回调。因此,为了覆盖此行为,您需要从 PCLVisualizerInteractorStyle 派生自己的类并覆盖 Initialize() 方法,并在构造时将此新的交互器样式传递给 PCLVisualizer

PointPickingCallback 中的 Execute 方法是检查 shift 键的地方。

void
pcl::visualization::PointPickingCallback::Execute (vtkObject *caller, unsigned long eventid, void*)

  PCLVisualizerInteractorStyle *style = reinterpret_cast<PCLVisualizerInteractorStyle*>(caller);
  vtkRenderWindowInteractor* iren = reinterpret_cast<pcl::visualization::PCLVisualizerInteractorStyle*>(caller)->GetInteractor ();
  if (style->CurrentMode == 0)
  
    if ((eventid == vtkCommand::LeftButtonPressEvent) && (iren->GetShiftKey () > 0))
    
      float x = 0, y = 0, z = 0;
      int idx = performSinglePick (iren, x, y, z);
      // Create a PointPickingEvent if a point was selected   
      [... and so on]

总的来说,您需要:

    PointPickingCallback 派生一个新类,该类覆盖Execute 方法中对shift 键的检查。 从 PCLVisualizerInteractorStyle 派生并覆盖 Initialize 方法以注册新的自定义 PointPickingCallback 类,该类不检查 shift 键,作为鼠标回调。 将新的交互器样式传递给PCLVisualizer

值得注意。可视化器支持两种选择模式:区域选择的橡皮筋和单点选择,可以通过按“x”键互换。我认为默认选择的是橡皮筋,这就是为什么它可能会首先检查是否按下了那个 shift 键。

【讨论】:

【参考方案2】:

不确定其他解决方案是否正确,但我找到了一个更简单的解决方案。

使用可视化工具setupInteractor() 函数并通过QVTKWidget::interactor()-&gt;GetInteractorStyle()-&gt;GetInteractor()QVTKWidget 的交互器赋予它

这应该在你按下 shift 时起作用。

【讨论】:

以上是关于如何伪造键盘移键。 Qt,Windows 10的主要内容,如果未能解决你的问题,请参考以下文章

Qt全屏窗口隐藏Win8/10触摸键盘

罗技 dpi 使用修饰符移位

从 QML 生成 KeyEvent

如何安装 Thrift 以使用 Qt-Windows

QT模拟win系统键盘输出,模拟组合快捷键输出(仅限windows系统)

QT模拟win系统键盘输出,模拟组合快捷键输出(仅限windows系统)