Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Linux/Ubuntu中捕获窗口事件(屏幕捕获和鼠标/键盘事件) 我想在C++中开发一个应用程序,它需要通过标准的IO(鼠标+键盘)与其他程序交互。它应该能够将鼠标/键盘输入发送到窗口,并捕获特定窗口的“屏幕截图”_C++_Linux_Keyboard_Mouse_Capture - Fatal编程技术网

在Linux/Ubuntu中捕获窗口事件(屏幕捕获和鼠标/键盘事件) 我想在C++中开发一个应用程序,它需要通过标准的IO(鼠标+键盘)与其他程序交互。它应该能够将鼠标/键盘输入发送到窗口,并捕获特定窗口的“屏幕截图”

在Linux/Ubuntu中捕获窗口事件(屏幕捕获和鼠标/键盘事件) 我想在C++中开发一个应用程序,它需要通过标准的IO(鼠标+键盘)与其他程序交互。它应该能够将鼠标/键盘输入发送到窗口,并捕获特定窗口的“屏幕截图”,c++,linux,keyboard,mouse,capture,C++,Linux,Keyboard,Mouse,Capture,(1) 现在我做了一些研究,我知道Linux使用“X窗口”系统。建议从这一层开始编程,还是应该使用更高级别的框架(例如wxWidgets) (2) 即使窗口未聚焦,也可以将输入事件发送到/捕获窗口的屏幕吗 (3) 我不是在问你代码,但我很乐意阅读一些关于这个主题的文献。遗憾的是,我找不到关于这个话题的好消息来源 如果有人能在这件事上帮我,那就太好了 提前谢谢你 (注:此程序应作为后端运行,稍后执行java应用程序的命令。该计划是为Windows/Linux提供后端C++应用程序) < P>强>解

(1) 现在我做了一些研究,我知道Linux使用“X窗口”系统。建议从这一层开始编程,还是应该使用更高级别的框架(例如wxWidgets)

(2) 即使窗口未聚焦,也可以将输入事件发送到/捕获窗口的屏幕吗

(3) 我不是在问你代码,但我很乐意阅读一些关于这个主题的文献。遗憾的是,我找不到关于这个话题的好消息来源

如果有人能在这件事上帮我,那就太好了

提前谢谢你


(注:此程序应作为后端运行,稍后执行java应用程序的命令。该计划是为Windows/Linux提供后端C++应用程序)

< P>强>解决方案1 <强>,我可以推荐一段代码来发送我自己用来模拟按键的键盘事件。它基于XSendEvent

#include <X11/Xlib.h>
#include <X11/keysym.h>

/** Modifier states */
#define MOD_ALT 0x8
#define MOD_CONTROL 0x4
#define MOD_CONTROL_ALT 0xc
#define MOD_SHIFT_CONTROL 0x5
#define MOD_SHIFT_ALT 0x9

XKeyEvent createKeyEvent(Display *display, Window &win,
                           Window &winRoot, bool press,
                           int keycode, int modifiers)
{
   XKeyEvent event;

   event.display     = display;
   event.window      = win;
   event.root        = winRoot;
   event.subwindow   = None;
   event.time        = CurrentTime;
   event.x           = 1;
   event.y           = 1;
   event.x_root      = 1;
   event.y_root      = 1;
   event.same_screen = True;
   event.keycode     = XKeysymToKeycode(display, keycode);
   event.state       = modifiers;

   if(press)
      event.type = KeyPress;
   else
      event.type = KeyRelease;

   return event;
}


void pressKey(Display* display, Window &win_focus, Window &win_root,
              KeySym key, int modifiers)
{
    // Send a fake key press event to the window.
    XKeyEvent event = createKeyEvent(display, win_focus, win_root, true, key, modifiers);
    XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);

    // Send a fake key release event to the window.
    event = createKeyEvent(display, win_focus, win_root, false, key, modifiers);
    XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
}
解决方案2使用XTest库可以实现类似的行为。不过,它在“更高级别”上运行,例如,窗口管理器也将接收这些按键。XTest的按键功能可能如下所示(代码不是很干净):


解决方案3另一个解决方案是使用以下工具编写解决方案。基本上,您描述的大部分内容都可以通过bash脚本实现。这也是一个很好的信息来源,告诉你如何实现你想要的一切。

嘿,安德烈,谢谢你快速而简洁的回答!所以你建议我使用XWindow。然后我有一些更详细的问题。(1) 如何获取没有键盘焦点的特定窗口的“句柄”?(2) 如果我可以做所有与该窗口相关的事情(例如,鼠标坐标不是相对于屏幕,而是相对于窗口),那将是最好的。你知道这可能吗?(3) XWindow是否支持拍摄我必须拥有的窗口截图。你有什么建议吗?(如果你知道一个好的消息来源,我很乐意看一看!)首先,我假设你希望这是一个C++应用程序。在这种情况下,x lib确实是一条出路。有XSendEvent方法,但也有XTest方法,对您来说可能更简单。不过,也可以通过外部工具实现很多功能,只需编写脚本即可。我也会用这个解决方案来扩展我的答案。@Marvin,如果这个解决方案对你有帮助,你能接受这个答案吗?
// Obtain the X11 display.
Display *display = XOpenDisplay(0);
if (display == NULL)
{
  printf("Null display!\n");
  return 1;
}

// Get the root window for the current display
Window win_root = XDefaultRootWindow(display);

// Find the window which has the current keyboard focus
Window win_focus;
int    revert;
XGetInputFocus(display, &win_focus, &revert);


pressKey(display, win_focus, win_root, XK_w, MOD_ALT);

if (display)
  XCloseDisplay(display);
void pressKey(Display* display, KeySym modifier1, KeySym modifier2, KeySym key)
{
    // Release every other modifier
    KeyCode keycodec = XKeysymToKeycode(display, XK_Control_L);
    KeyCode keycodea = XKeysymToKeycode(display, XK_Alt_L);
    KeyCode keycodes = XKeysymToKeycode(display, XK_Shift_L);
    XTestFakeKeyEvent(display, keycodec, False, 0); // key release event
    XTestFakeKeyEvent(display, keycodea, False, 0); // key release event
    XTestFakeKeyEvent(display, keycodes, False, 0); // key release event
    XFlush(display);

    // Press the actual keys
    KeyCode keycode1 = XKeysymToKeycode(display, modifier1);
    KeyCode keycode2 = XKeysymToKeycode(display, modifier2);
    KeyCode keycode3 = XKeysymToKeycode(display, key);
    if (keycode1)
        XTestFakeKeyEvent(display, keycode1, True, 0); // key press event
    if (keycode2)
        XTestFakeKeyEvent(display, keycode2, True, 0); // key press event
    if (keycode3)
    {
        XTestFakeKeyEvent(display, keycode3, True, 0); // key press event
        XTestFakeKeyEvent(display, keycode3, False, 0); // key release event
    }
    if (keycode2)
        XTestFakeKeyEvent(display, keycode2, False, 0); // key release event
    if (keycode1)
        XTestFakeKeyEvent(display, keycode1, False, 0); // key release event
    XFlush(display);
}