5

我想找到我的 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+(在嵌入复合之前添加到外壳的小部件数量)。

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

4

2 回答 2

3

如果您使用 SWT.EMBEDDED 样式创建一个 Composite ,那么在 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 的 JNI 代码

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

这里的代码示例。

使用操作系统的类示例:

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

我可以找到的操作系统确实是org.eclipse.swt.internal.win32.OS,而不是 gtk,它不是一个完美的解决方案,因为您将访问一个内部包,但这可以让您知道在哪里查看。

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

在对我一开始提到的消息的回答中说

如果您需要 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 窗口之间存在三层。

于 2009-03-04T05:11:42.813 回答
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”步骤是跳转到根窗口小部件/窗口的步骤,因此意味着您不需要“减去魔法窗口偏移”黑客(我最初也被困在这样做)。

于 2016-10-17T02:44:38.913 回答