tutorial libreria interfaz grafica español ejemplos componentes clase java winapi swing jni hwnd

interfaz - libreria swing java netbeans



En Java Swing, ¿cómo se obtiene una referencia de manejador de ventana Win32(hwnd) a una ventana? (7)

En Java 1.4 puede usar ((SunToolkit) Toolkit.getDefaultToolkit ()). GetNativeWindowHandleFromComponent () pero eso fue eliminado.

Parece que tienes que usar JNI para hacer esto ahora. ¿Tiene el código JNI y el código de ejemplo de Java para hacer esto?

Necesito esto para llamar a las llamadas a la API Win32 GetWindowLong y SetWindowLong, lo que se puede hacer a través de la biblioteca Jawin.

Me gustaría algo muy preciso para poder pasar una referencia al JDialog o JFrame y obtener el identificador de la ventana.

La transparencia de oscilación usando JNI puede estar relacionada.


El siguiente código le permite pasar un componente para obtener el identificador de ventana (HWND). Para asegurarse de que un Componente tiene un manejador de ventana correspondiente, invoqueLightWeight () en el Componente y verifique que sea falso. Si no es así, intente con sus padres llamando a Component.getParent ().

Código Java:

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

Archivo de encabezado 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

La fuente C 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; }




Es lo mismo que la respuesta de Jared MacD, pero utiliza la reflexión para que el código pueda compilarse y cargarse en una computadora que no sea de Windows. Por supuesto, fallará si intentas llamarlo.

import java.awt.Frame; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class WindowHandleGetter { private static final Logger log = LoggerFactory.getLogger(WindowHandleGetter.class); private final Frame rootFrame; protected WindowHandleGetter(Frame rootFrame) { this.rootFrame = rootFrame; } protected long getWindowId() { try { Frame frame = rootFrame; // The reflection code below does the same as this // long handle = frame.getPeer() != null ? ((WComponentPeer) frame.getPeer()).getHWnd() : 0; Object wComponentPeer = invokeMethod(frame, "getPeer"); Long hwnd = (Long) invokeMethod(wComponentPeer, "getHWnd"); return hwnd; } catch (Exception ex) { log.error("Error getting window handle"); } return 0; } protected Object invokeMethod(Object o, String methodName) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class c = o.getClass(); for (Method m : c.getMethods()) { if (m.getName().equals(methodName)) { Object ret = m.invoke(o); return ret; } } throw new RuntimeException("Could not find method named ''"+methodName+"'' on class " + c); } }


Este pequeño método JNI acepta un título de ventana y devuelve el identificador de ventana correspondiente.

JNIEXPORT jint JNICALL Java_JavaHowTo_getHwnd (JNIEnv *env, jclass obj, jstring title){ HWND hwnd = NULL; const char *str = NULL; str = (*env)->GetStringUTFChars(env, title, 0); hwnd = FindWindow(NULL,str); (*env)->ReleaseStringUTFChars(env, title, str); return (jint) hwnd; }

ACTUALIZAR:

Con JNA, es un poco más fácil. Hice un pequeño ejemplo que encuentra el mango y lo uso para llevar el programa al frente.


Los dos métodos anteriores funcionan bien, pero ambos devuelven un HWND como java int (32 bits). esto está bien para una plataforma de 32 bits, pero es poco probable que su aplicación funcione en una plataforma de 64 bits. Cambiaría los tipos de devolución a longs (64bits) ya que esto se comportará correctamente tanto en sistemas de 64 bits como en sistemas de 32 bits (solo tendrá que volver a compilar el archivo DLL).


No tiene que escribir ningún código C / JNI. De Java:

import sun.awt.windows.WComponentPeer; public static long getHWnd(Frame f) { return f.getPeer() != null ? ((WComponentPeer) f.getPeer()).getHWnd() : 0; }

Advertencias:

  • Esto usa un paquete sun *. Obviamente, esto no es API pública. Pero es poco probable que cambie (y creo que es menos probable que se rompa que las soluciones anteriores).
  • Esto se compilará y ejecutará solo en Windows. Tendría que convertir esto en código de reflexión para que sea portátil.