java 使用java处理外部窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6662956/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:51:02  来源:igfitidea点击:

Handle external windows using java

javawinapi

提问by Balanivash

I need to check if an external window (another java program, but not controlled by the program that I'm working on) is open using the title, and if it open, then either maximize or minimize it based on the user command in Java (I know only the title of the window and nothing else) . Google only says that I can use winapito get the window handle and manipulate it using the handle, but I'm not able to find how to do this.

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

I could find references on how to do it using JNI here: In Java Swing how do you get a Win32 window handle (hwnd) reference to a window?. Is it possible to do this without using JNI?

我可以在此处找到有关如何使用 JNI 执行此操作的参考资料: 在 Java Swing 中,您如何获得对窗口的 Win32 窗口句柄 (hwnd) 引用?. 是否可以在不使用 JNI 的情况下执行此操作?

Could someone help me understand how to do this.

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

Thanks and Regards

谢谢并恭祝安康

回答by Luke Quinane

I've just added a lot of win32 related window functions into JNA. You can see the details here.

我刚刚在JNA 中添加了很多与 win32 相关的窗口函数。您可以在此处查看详细信息。

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

You can also enumerate all windows:

您还可以枚举所有窗口:

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...

回答by Bernd Elkemann

You can use the Windows API to get a handle to the window and then resize it:

您可以使用 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

Typical WinAPI interface, a little clunky to use but powerful.

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

回答by Aaron Digulla

Java has no API for this, so you have to use JNI. See eznme's answer for details.

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

回答by Mike Kwan

As stated, this is not possible in pure Java. An example of doing it natively (which you would need to translate to JNI):

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

HWND hwnd = FindWindow( _T("classname"), _T("windowname") );

// Minimize
ShowWindow( hwnd, SW_MINIMIZE );

// Maximize
ShowWindow( hwnd, SW_MAXIMIZE );

You already have the window name but you should also supply a classname since this allows you to more accurately get the window. If there were multiple windows with the same windowname then your program might do something undesirable.

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

You can use something like Spy++ to get the class name. Or also simply through code. Ensure that your window is currently the only window with a matching windowname then you can do:

您可以使用 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 );

If it is possible to get the HWND from the Java process itself with the code herethen you should pass that to the native part since it will be guaranteed to be reliable.

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