【问题标题】:How do I interact with other applications in C++?如何在 C++ 中与其他应用程序交互?
【发布时间】:2014-01-05 18:45:08
【问题描述】:

我想知道有没有办法改变其他应用程序的定位是C++。我想要做的是在屏幕上移动活动窗口。例如,我想以循环移动方式移动 Firefox。 2:17 http://www.youtube.com/watch?v=TLqPepLhDTY&list=WL8D6E1A188FBFE181 浏览器移动了,怎么办?

【问题讨论】:

    标签: c++ windows ipc


    【解决方案1】:

    您应该首先使用FindWindow() 函数获取窗口的HWND。然后你可以简单地使用 SetWindowPos()MoveWindow() 和找到的 HWND 来改变位置。

    【讨论】:

      【解决方案2】:

      在 linux、mac 和 FreeBSD 上:这是一个快速脚本,它使用 xdotool 沿着某个轨迹滑动 chrome 浏览器:

      #!/bin/bash
      
      while read x y
      do 
          xdotool search --class google-chrome windowmove $x $y
          sleep 0.001
      done <<TRAJECTORY
      624 624
      634 614
      644 624
      654 614
      664 624
      674 614
      684 624
      694 614
      704 624
      TRAJECTORY
      

      注意事项

      • 我让轨迹变得很无聊
        不过,您可以使用一些基本的三角函数来使运动成为圆形。该示例显示您甚至可以从列表中输入形状
      • 该示例对目标窗口进行硬编码(但您可以使用例如selectwindow 让用户单击任何窗口进行操作)
        再次,您的想象力是极限

      【讨论】:

      • 很有趣,但是超出了 OP 请求...(这里没有 c++ 和 windows 的东西)
      • @pepper_chico 好吧。我在回答他的问题,而不是标签。通常会涉及到一定程度的X/Y asking。此外,没有什么可以阻止他 (a) 从 c++ 驱动 xdotool 或 (b) 直接从 c++ 使用 xlib+xtst,使用 the source code of xdotool 作为参考。即使对于商业应用程序,许可证似乎也不排除这种情况。
      • 对我来说似乎不是一个干净的解决方案;调用外部程序来解决问题是 IMO 肮脏的。
      • @Paranaix 我不知道在没有该进程合作的情况下干预另一个进程的窗口位置可能是“干净的”xD 此外,您还没有阅读我评论中的(b) 部分.这是一个非常具体的例子,说明它是如何完成的。如果 OP 喜欢它,他将能够以他喜欢的方式编写代码。
      • @sehe 一个窗口通常更多地属于一个操作系统作为一个进程,因此有干净的方法来完成这样的任务,即调用提供的操作系统函数。虽然我个人不喜欢这个解决方案,但我接受这一点,它是一个解决方案,因此我也没有否决它。
      【解决方案3】:

      实际上在您没有创建的窗口上使用FindWindow 很困难,因为您需要在该窗口上使用的类名。请改用EnumWindows。这是一个代码示例,用于搜索并关闭名称中包含“Firefox”的任何窗口。持续发送WM_MOVE 而不是 WM_CLOSE 来移动窗口。

      #include <windows.h>
      #include <tchar.h>
      #include <iostream>
      using namespace std;
      
      #pragma comment(lib, "user32.lib")
      
      HWND windowHandle;
      
      BOOL CALLBACK MyEnumProc(HWND hWnd, LPARAM lParam)
      {
          TCHAR title[500];
          ZeroMemory(title, sizeof(title));
      
          //string strTitle;
      
          GetWindowText(hWnd, title, sizeof(title)/sizeof(title[0]));
      
          //_tprintf(_T("Found window: %s\n"), title);
      
          //strTitle += title; // Convert to std::string
          if(_tcsstr(title, _T("Firefox")))
          {
              windowHandle = hWnd;
              return FALSE;
          }
          return TRUE;
      }
      
      int main()
      {
          while (true)
          {
              windowHandle = NULL;
              EnumWindows(MyEnumProc, 0);
      
              cout << endl << endl << "Desired window handle: " << windowHandle << endl << "Sending WM_CLOSE message..." << endl;
              SendMessage(windowHandle, WM_CLOSE, NULL, NULL);
          }
          return 0;
      }
      

      【讨论】:

      • 可以查类名,FindWindow也可以查名字。
      • 这通常更可靠,因为任何窗口都可以有标题“Firefox”
      • 但是为什么要连续发送 WM_MOVE 而不是一次呢?
      • @gdany 如果您只想移动一次窗口,他们只发送一次。我的印象是您想以某种模式(如圆圈)移动窗口。
      • 是的,我在这方面做了一些工作,我意识到这就是 while 循环存在的原因。 :D
      【解决方案4】:

      哇,谢谢你们,我没想到会这么快回答。我会尝试看看哪个代码最适合使用。它终于按我想要的方式工作了。代码如下所示:

      #include <windows.h>
      #include <tchar.h>
      #include <iostream>
      
      using namespace std;
      
      #pragma comment(lib, "user32.lib")
      
      HWND windowHandle;
      
      BOOL CALLBACK MyEnumProc(HWND hWnd, LPARAM lParam)
      {
          TCHAR title[500];
          ZeroMemory(title, sizeof(title));
      
          //string strTitle;
      
          GetWindowText(hWnd, title, sizeof(title)/sizeof(title[0]));
      
          //_tprintf(_T("Found window: %s\n"), title);
      
          //strTitle += title; // Convert to std::string
          if(_tcsstr(title, _T("Firefox")))
          {
              windowHandle = hWnd;
              return FALSE;
          }
          return TRUE;
      }
      int xLoc = 10;
      int yLoc = 50;
      
      int getXLoc(){
          if(xLoc<70&&yLoc<=30){
              xLoc += 1;
              Sleep(10);
          }else if(yLoc>30){
              xLoc -= 1;
              Sleep(10);
          }
          return xLoc;
      }
      int getYLoc(){
          if(yLoc>10&&xLoc<30){
              yLoc -= 1;
              Sleep(10);
          }else if(xLoc>=30&&yLoc<70){
              yLoc += 1;
              Sleep(10);
          }
          return yLoc;
      }
      
      int main()
      {
          windowHandle = NULL;
          EnumWindows(MyEnumProc, 0);
          while(true){
              MoveWindow(windowHandle, getXLoc(), getYLoc(), 1220, 930, false);
              Sleep(5);
          }
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2012-11-25
        • 2018-07-20
        • 2014-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-26
        • 2010-10-29
        • 1970-01-01
        相关资源
        最近更新 更多