2009-03-04 3 views
5

SWT 프로그램의 창 ID를 찾고 싶습니다.Java SWT의 창 ID

표준 SWT 쉘을 시작합니다. 그런 다음 어떻게 생성 된 창의 ID를 찾을 수 있습니까? 이 프로그램은 Compiz-Fusion 창 관리자를 사용하여 Fedora 10에서 실행됩니다 (차이가 나는 경우).

코드가 무슨 뜻인지 설명하기 위해 : (아래의 제안을 VonC 덕분에)보고 사물의 전체 범위를 시도 후 2009년 3월 6일 을

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(); 
    } 
    } 
} 

업데이트, 나는 가로 질러 온 지금까지 효과가 있었던 것. 그것은 대단히 dodgy하지만 최소한 내가 다른 어떤 일을 잠시 동안 할 수있게 해줍니다.

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

답변

3

스타일이 SWT.EMBEDDED 스타일 인 경우 SWT/GTK + Composite.embeddedHandle 아래에서 XEMBED 자녀를 양육하는 데 사용할 수있는 X 창 ID가됩니다.

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 프로토콜을 사용한 내장을 지원합니다.

이 핸들에서 code here

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

예를 윈도우 ID를 얻기 위해 사용되는 JNI 코드와 유사하다. 내가 찾을 수

org.eclipse.swt.widgets.Tree, org.eclipse.swt.widgets.CoolItem,

OS가 실제로 org.eclipse.swt.internal.win32.OS이다 GTK하지, 당신은 내부 패키지에 액세스 할 것이기 때문에 그것은 완벽한 솔루션되지 않습니다 : 클래스의

예 OS를 사용하여 그러나 그것은 당신에게 어디에서 볼 것인지 생각을 줄 수 있습니다.

귀하의 경우 org.eclipse.swt.internal.gtk.OS이 올바른 클래스이므로 Tree 또는 CoolItem 소스에서 GetWindow 기능을 사용하는 방법을 살펴보아야합니다. 할 수처럼
일부 다른 기능 필요, GTK에서 호출되는 gtk_container_get_children(int container);

그것은 당신이 X 윈도우가 필요한 경우 할 수있는 방법은 없습니다 내가 처음

에서 언급 된 메시지에 said in an answer입니다 공개 SWT API (심지어 내부를 거치기)에서 비롯된 것입니다. 또한 모든 컨트롤에 대해이를 보장 할 수 있다고 생각하지 않는 방법이 있더라도.이 작품 있는지 확실하지 않습니다하지만 당신이 얻을 수있는 가장 가까운에 수 있습니다 :

  1. Control.fixedHandle 공공
  2. 사용 OS.GTK_WIDGET_WINDOW (control.fixedHandle)는 X 창으로 그 번역하는 GdkWindow
  3. 사용 OS.gdk_x11_drawable_get_xid (gdkWindow)을 얻을 수 있도록
나는 다른 방법이 Control.handle 수행 한 다음에 GTK_WIDGET_WINDOW() 전화, 또는 인 경우에 null 킵 호출 할 수 있습니다 추측 GdkWindow으로 찾아서 X 윈도우로 변환 할 때까지 부모님에게 보내십시오.

여기에서의 어려움은 SWT가 GDK와 대화하고 GTK +와 대화하여 X와 대화한다는 것입니다. 따라서 사용자와 X 창 사이에 세 개의 레이어가 있습니다.

+0

도움에 감사드립니다. 그러나 org.eclipse.swt.internal.gtk.OS에서 GetWindow 메서드 나 GW_CHILD 속성을 찾을 수 없습니다 - 사용할 패키지가 맞습니까? – cursa

0

감사합니다. mplayer로 비디오를 보여주기 위해 임베디드 SWT 캔버스가 있습니다.

캔버스가 SWT 컨트롤로 만들어진 다른 예제를 발견했습니다. 디버깅 할 때 embeddedHandle 필드를 볼 수는 있지만 액세스/사용할 수는 없습니다.

예제에 따르면 SWT 컨트롤에서 컴포지트로 변경되었으므로 이제 embeddedHandle에 액세스 할 수 있습니다.

3

이 여전히 칠년 후 :-), 당신에게 중요한 확실하지만, 이것은 나를 위해 작동하지 :

특히
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