如何在JavaFX中获取舞台的窗口句柄(hWnd)?

时间:2013-02-22 22:39:12

标签: java javafx-2 jna javafx-8 hwnd

我们正在Windows中构建JavaFX应用程序,我们希望能够做一些事情来操纵我们的应用程序在Windows 7/8任务栏中的显示方式。这需要修改名为“Application User Model ID”的Windows变量。

我们已经设法使用JNA在Swing中完成了我们想要的工作,我们想在JavaFX中重复我们的解决方案。不幸的是,要做到这一点,我们需要能够为应用程序中的每个窗口检索hWnd(窗口句柄)。这可以通过JNA Native.getWindowPointer()方法在Swing / AWT中完成,该方法适用于java.awt.Window,但我无法找到使用javafx.stage.Window执行此操作的好方法。

是否有人知道如何为hWnd获取Stage

4 个答案:

答案 0 :(得分:3)

这是一个JavaFX2版本(使用Stage而不是Window):

private static Pointer getWindowPointer(Stage stage) {
    try {
        TKStage tkStage = stage.impl_getPeer();
        Method getPlatformWindow = tkStage.getClass().getDeclaredMethod("getPlatformWindow" );
        getPlatformWindow.setAccessible(true);
        Object platformWindow = getPlatformWindow.invoke(tkStage);
        Method getNativeHandle = platformWindow.getClass().getMethod( "getNativeHandle" );
        getNativeHandle.setAccessible(true);
        Object nativeHandle = getNativeHandle.invoke(platformWindow);
        return new Pointer((Long) nativeHandle);
    } catch (Throwable e) {
        System.err.println("Error getting Window Pointer");
        return null;
    }
}

答案 1 :(得分:1)

以下方法显示如何获取JavaFX Stage(或Window)的本机窗口句柄(hWnd),然后将其存储在JNA Pointer对象中:

private static Pointer getWindowPointer(javafx.stage.Window window) {
    Pointer retval = null;
    try {
        Method getPeer = window.getClass().getMethod("impl_getPeer");
        final Object tkStage = getPeer.invoke(window);
        Method getPlatformWindow = tkStage.getClass().getDeclaredMethod("getPlatformWindow");
        getPlatformWindow.setAccessible(true);
        final Object platformWindow = getPlatformWindow.invoke(tkStage);
        Method getNativeHandle = platformWindow.getClass().getMethod("getNativeHandle");
        retval = new Pointer((Long) getNativeHandle.invoke(platformWindow));
    } catch (Throwable t) {
        System.err.println("Error getting Window Pointer");
        t.printStackTrace();
    }
    return retval;
}

这个解决方案很脆弱,通常是不受欢迎的,因为它使用反射来访问一堆私有方法。但它完成了工作。希望Oracle最终能让我们直接访问本机窗口句柄,这样我们就不必这样做了。

当然,此代码仅在您在MS Windows上运行时才有效。此外,我只是尝试使用早期版本的JavaFX 8(但我怀疑它在JavaFX 2上也能正常工作。编辑:看起来它在JavaFX 2中不起作用。)

答案 2 :(得分:0)

com.sun.glass.ui.Window.getWindows.get(0).getNativeWindow

//

com.sun.glass.ui.Window.getFocusedWindow.getNativeWindow

答案 3 :(得分:0)

添加对JNA的依赖关系

 Table 'a' is specified twice, 
 both as a target for 'UPDATE' and as a separate source for data

然后为您的<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.3.1</version> </dependency> 赋予一个不同的标题(在此示例中为“ MyStage”),然后获得如下所示的Window ID:

Stage

无论JavaFX版本如何,它都可以在Windows上运行。