【问题标题】:Handle external windows using java使用 java 处理外部窗口
【发布时间】:2011-10-03 12:38:03
【问题描述】:

我需要检查是否使用标题打开了外部窗口(另一个 java 程序,但不受我正在处理的程序控制),如果它打开,则根据用户最大化或最小化它Java 中的命令(我只知道窗口的标题,不知道其他)。谷歌只说我可以使用winapi 来获取窗口句柄并使用句柄对其进行操作,但我无法找到如何做到这一点。

我可以在这里找到有关如何使用 JNI 的参考: In Java Swing how do you get a Win32 window handle (hwnd) reference to a window?。不使用 JNI 是否可以做到这一点?

有人可以帮我理解如何做到这一点。

感谢和问候

【问题讨论】:

    标签: java winapi


    【解决方案1】:

    我刚刚在JNA 中添加了很多win32 相关的窗口函数。可以查看详情here

    // Find and minimize a window:
    WinDef.HWND hWnd = User32.INSTANCE.FindWindow("className", "windowName");
    User32.INSTANCE.ShowWindow(hWnd, WinUser.SW_MINIMIZE);
    

    你也可以枚举所有窗口:

    final WinDef.HWND[] windowHandle = new WinDef.HWND[1];
    User32.INSTANCE.EnumWindows(new WinUser.WNDENUMPROC() {
        @Override
        public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
            if (matches(hwnd)) {
                windowHandle[0] = hwnd;
                return false;
            }
            return true;
        }
    }, Pointer.NULL);
    
    // Minimize or maximize windowHandle[0] here...
    

    【讨论】:

    【解决方案2】:

    Java 没有这方面的 API,因此您必须使用 JNI。有关详细信息,请参阅 eznme 的答案。

    【讨论】:

      【解决方案3】:

      您可以使用 Windows API 获取窗口句柄,然后调整其大小:

      EnumWindows:
      http://msdn.microsoft.com/en-us/library/ms633497%28v=VS.85%29.aspx
      
      GetNextWindow:
      http://msdn.microsoft.com/en-us/library/ms633509%28v=VS.85%29.aspx
      
      GetWindowText:   (to decide whether that is the window you want; if title matches)
      http://msdn.microsoft.com/en-us/library/ms633520%28v=VS.85%29.aspx
      
      FindWindow:  (for this you need the exact title beforehand, not just part of it)
      http://msdn.microsoft.com/en-us/library/ms633499%28v=vs.85%29.aspx
      
      ShowWindow:
      http://msdn.microsoft.com/en-us/library/ms633548%28v=VS.85%29.aspx
      

      典型的 WinAPI 界面,使用起来有点笨拙但功能强大。

      【讨论】:

      • +1 没有 JNI 是不可能的,所以要么他使用 JNI,要么他做不到。
      • 当存在 FindWindow API 时,无论哪种方式,这种方法都过大了
      【解决方案4】:

      如上所述,这在纯 Java 中是不可能的。本地执行的示例(您需要将其转换为 JNI):

      HWND hwnd = FindWindow( _T("classname"), _T("windowname") );
      
      // Minimize
      ShowWindow( hwnd, SW_MINIMIZE );
      
      // Maximize
      ShowWindow( hwnd, SW_MAXIMIZE );
      

      您已经有了窗口名称,但您还应该提供一个类名,因为这可以让您更准确地获取窗口。如果有多个窗口具有相同的窗口名称,那么您的程序可能会做一些不受欢迎的事情。

      您可以使用 Spy++ 之类的东西来获取类名。或者也可以简单地通过代码。确保您的窗口是当前唯一具有匹配窗口名称的窗口,然后您可以这样做:

      TCHAR lpClassName[256] = {0};
      
      HWND hwnd = FindWindow( _T("classname"), _T("windowname") );
      GetClassName( hwnd, lpClassName, _countof( lpClassName ) );
      MessageBox( NULL, _T("Class Name"), lpClassName, MB_OK );
      

      如果可以使用代码 here 从 Java 进程本身获取 HWND,那么您应该将其传递给本机部分,因为它可以保证是可靠的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-28
        • 2017-01-08
        • 2013-10-07
        • 1970-01-01
        • 2012-07-02
        • 2012-12-03
        相关资源
        最近更新 更多