2009-03-04 20 views
5

我想找到我的SWT程序的窗口ID。来自Java SWT的窗口ID

我以标准方式启动我的SWT shell。那么我如何找到已经创建的窗口的ID?该程序使用Compiz-Fusion窗口管理器在Fedora 10上执行(如果这有所帮助)。

代码,以帮助解释一下我的意思是:

public static void main(String[] args) { 
    Display display = new Display(); 
    Shell shell = new Shell(); 

    // find window ID here?? 

    shell.open(); 

    while (!shell.isDisposed()) { 
    if(!display.readAndDispatch()) { 
     display.sleep(); 
    } 
    } 
} 

更新2009年3月6日 寻找和尝试的事情的整个范围(感谢VonC下面的建议)之后,我碰到迄今为止工作的东西。这是至高无上的,但至少可以让我继续做一些其他的工作。

Control.embeddedHandle返回的ID接近窗口ID。它与可预测的偏移量不同。所以我的代码是:

public static void main(String[] args) { 
    ... 
    Shell shell = new shell(display, SWT.NONE); 

    Composite e = new Composite(shell, SWT.EMBEDDED); 
    long windowID = e.embeddedHandle - WINDOW_ID_MAGIC_NUMBER; 
    e.dispose(); 
    .... 

WINDOW_ID_MAGIC_NUMBER是5+(在嵌入式合成之前添加到壳的小部件的数量)。

到目前为止,我的系统似乎很可靠。我还没有看到它是否会在不同的环境中崩溃。

+0

刚刚更新了我的答案一些更多的线索......虽然没有“确定性”。 – VonC 2009-03-05 07:04:00

回答

3

如果你的create a Composite样式为SWT.EMBEDDED样式,那么在SWT/GTK + Composite.embeddedHandle下将会是一个X窗口ID,您可以使用它来为XEMBED孩子做父母。

Composite embed = new Composite(shell, SWT.EMBEDDED); 
System.out.println ("X window ID: " + embed.embeddedHandle); 
int hwndChild = OS.GetWindow (c.handle, OS.GW_CHILD); 

这支持使用XEMBED协议进行嵌入。

这类似于用来从它的手柄得到窗口ID的code here

GtkWidget *widget = (GtkWidget *) handle; 
GdkWindow *window = widget->window; 
xwinid = GDK_WINDOW_XWINDOW(window); 

实施例的JNI代码。使用类的

例OS:

org.eclipse.swt.widgets.Treeorg.eclipse.swt.widgets.CoolItem

OS可以找我确实org.eclipse.swt.internal.win32.OS,不是GTK,它是不是一个完美的解决方案,因为你会访问内部包,但是这可以让你知道在哪里看。

在你的情况下,org.eclipse.swt.internal.gtk.OS是正确的类,你应该看看Tree或CoolItem的来源他们如何使用GetWindow函数。
其他一些功能需要在GTK被调用,像可能是gtk_container_get_children(int container);

这是said in an answer到我在一开始

提到的消息如果你需要的X窗口,没有办法做到这来自公共SWT API(甚至是通过内部),而且即使有一种方法,我认为你不能保证它可以用于所有的控制。我不知道,如果这个工程,但你能得到的最接近可能是:

  1. 使Control.fixedHandle公共
  2. 使用OS.GTK_WIDGET_WINDOW (control.fixedHandle)获得GdkWindow
  3. 使用OS.gdk_x11_drawable_get_xid (gdkWindow)翻译是一个X窗口

我想其他的方法可能是采取Control.handle,然后就可以调用GTK_WIDGET_WINDOW(),或者如果这是null保持通话它在其父母身上,直到找到一个带有GdkWindow的人,然后将其转换为X窗口。

这里的难点在于SWT会与GTK +进行对话,GTK会与GDK进行对话,然后会与X进行对话。所以,您和X窗口之间有三层。

+0

感谢您的帮助。但是,我无法在org.eclipse.swt.internal.gtk.OS中找到GetWindow方法或GW_CHILD属性 - 是否使用正确的包? – cursa 2009-03-05 00:40:21

0

谢谢你,这对我很有帮助。我有一个嵌入式SWT画布以用mplayer显示视频。

我发现了另一个Canvas作为SWT控件创建的例子。调试时,我可以看到嵌入的句柄字段,但无法访问/使用它。

根据你的例子,我从SWT控制改为复合,现在我可以访问embeddedHandle,它可以工作!

3

不知道这还是对你很重要,7年后:-),但是这对我的作品:

private static long getWindowIdFromShell(Shell shell) { 
    long handle = shell.handle; 
    long topWidget = OS._gtk_widget_get_toplevel(handle); 
    long topWindow = OS._gtk_widget_get_window(topWidget); 
    long topXid = OS._gdk_x11_window_get_xid(topWindow); 
    return topXid; 
} 

尤其是“get_toplevel”的步骤是什么跳到根小部件/窗,这意味着你不需要“减法魔术窗口偏移”黑客(我最初也坚持这样做)。

+2

谢谢:)从那时起我已经多次移动职位/城市/大陆,我甚至不记得当我发布问题时我正在尝试做什么。 但希望它能帮助别人解决这个问题。 – cursa 2016-10-21 11:54:37