2009-03-04 23 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