javawinapiswingjava-native-interfacehwnd

In Java Swing how do you get a Win32 window handle (hwnd) reference to a window?


In Java 1.4 you could use ((SunToolkit) Toolkit.getDefaultToolkit()).getNativeWindowHandleFromComponent() but that was removed.

It looks like you have to use JNI to do this now. Do you have the JNI code and sample Java code to do this?

I need this to call the Win32 GetWindowLong and SetWindowLong API calls, which can be done via the Jawin library.

I would like something very precise so I can pass a reference to the JDialog or JFrame and get the window handle.

Swing transparency using JNI may be related.


Solution

  • The following code lets you pass a Component to get the window handle (HWND) for it. To make sure that a Component has a corresponding window handle call isLightWeight() on the Component and verify that it equals false. If it doesn't, try it's parent by calling Component.getParent().

    Java code:

    package win32;
    public class Win32 {
        public static native int getWindowHandle(Component c);
    }
    

    Header file main.h:

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class win32_Win32 */
    
    #ifndef _Included_win32_Win32
    #define _Included_win32_Win32
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     win32_Win32
     * Method:    getWindowHandle
     * Signature: (Ljava/awt/Component;Ljava/lang/String;)I
     */
    JNIEXPORT jint JNICALL Java_win32_Win32_getWindowHandle
      (JNIEnv *, jclass, jobject);
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    The C source main.c:

    #include<windows.h>
    #include <jni.h>
    #include <jawt.h>
    #include <jawt_md.h>
    
    HMODULE _hAWT = 0;
    
    JNIEXPORT jint JNICALL Java_win32_Win32_getWindowHandle
      (JNIEnv * env, jclass cls, jobject comp)
    {
        HWND hWnd = 0;
        typedef jboolean (JNICALL *PJAWT_GETAWT)(JNIEnv*, JAWT*);
        JAWT awt;
        JAWT_DrawingSurface* ds;
        JAWT_DrawingSurfaceInfo* dsi;
        JAWT_Win32DrawingSurfaceInfo* dsi_win;
        jboolean result;
        jint lock;
    
        //Load AWT Library
        if(!_hAWT)
            //for Java 1.4
            _hAWT = LoadLibrary("jawt.dll");
        if(!_hAWT)
            //for Java 1.3
            _hAWT = LoadLibrary("awt.dll");
        if(_hAWT)
        {
            PJAWT_GETAWT JAWT_GetAWT = (PJAWT_GETAWT)GetProcAddress(_hAWT, "_JAWT_GetAWT@8");
            if(JAWT_GetAWT)
            {
                awt.version = JAWT_VERSION_1_4; // Init here with JAWT_VERSION_1_3 or JAWT_VERSION_1_4
                //Get AWT API Interface
                result = JAWT_GetAWT(env, &awt);
                if(result != JNI_FALSE)
                {
                    ds = awt.GetDrawingSurface(env, comp);
                    if(ds != NULL)
                    {
                        lock = ds->Lock(ds);
                        if((lock & JAWT_LOCK_ERROR) == 0)
                        {
                            dsi = ds->GetDrawingSurfaceInfo(ds);
                            if(dsi)
                            {
                                dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
                                if(dsi_win)
                                {
                                    hWnd = dsi_win->hwnd;
                                }
                                else {
                                    hWnd = (HWND) -1;
                                }
                                ds->FreeDrawingSurfaceInfo(dsi);
                            }
                            else {
                                hWnd = (HWND) -2;
                            }
                            ds->Unlock(ds);
                        }
                        else {
                            hWnd = (HWND) -3;
                        }
                        awt.FreeDrawingSurface(ds);
                    }
                    else {
                        hWnd = (HWND) -4;
                    }
                }
                else {
                    hWnd = (HWND) -5;
                }
            }
            else {
                hWnd = (HWND) -6;
            }
        }
        else {
            hWnd = (HWND) -7;
        }
        return (jint)hWnd;
    
    }