W Javie jak uzyskać Win32 window handle (hwnd) reference do okna?
W Javie 1.4 można użyć ((SunToolkit) Toolkit.getDefaultToolkit ()).getNativeWindowHandleFromComponent (), ale to zostało usunięte.
Wygląda na to, że musisz użyć JNI, aby to zrobić. Czy masz do tego Kod JNI i przykładowy kod Javy?
Potrzebuję tego, aby wywołać wywołania API Win32 GetWindowLong i SetWindowLong, które można wykonać za pomocą biblioteki Jawin.
Chciałbym coś bardzo precyzyjnego, żebym mógł podać odniesienie do JDialog lub JFrame i weź klamkę.
Przezroczystość huśtawki przy użyciu JNI może być powiązana.
6 answers
Nie masz żadnego kodu C/JNI. From Java:
import sun.awt.windows.WComponentPeer;
public static long getHWnd(Frame f) {
return f.getPeer() != null ? ((WComponentPeer) f.getPeer()).getHWnd() : 0;
}
Zastrzeżenia:
- To używa słońca.* pakiet. Oczywiście nie jest to publiczne API. Ale jest mało prawdopodobne, aby zmienić(i myślę, że mniej prawdopodobne, aby złamać niż rozwiązania powyżej).
- zostanie skompilowany i uruchomiony tylko w systemie Windows. Musisz zmienić to w kod odbicia, aby to było przenośne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-02 03:48:18
Ta mała metoda JNI akceptuje tytuł okna i zwraca odpowiedni uchwyt okna.
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;
}
Aktualizacja:
Z JNA jest trochę łatwiej. Zrobiłem mały przykład , który znajduje uchwyt i używa go do doprowadzenia programu do przodu.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-16 22:27:26
Poniższy kod pozwala przekazać komponent, aby uzyskać uchwyt okna (HWND) dla niego. Aby upewnić się, że komponent ma odpowiedni uchwyt okna wywołanie isLightWeight () na komponencie i sprawdzić, czy jest równe false. Jeśli nie, spróbuj wywołać komponent jako rodzica.getParent ().
Kod Javy:
package win32;
public class Win32 {
public static native int getWindowHandle(Component c);
}
Główny plik nagłówka.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
C Źródło główne.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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-05 17:40:05
Znalazłem to: http://jna.java.net/javadoc/com/sun/jna/Native.html#getWindowID (java. awt. Window )
JNA pozwala wywoływać natywne biblioteki bez konieczności pisania kodu natywnego jni. Okazuje się, że sama biblioteka ma metodę, która bierze okno i produkuje int, prawdopodobnie uchwyt (lub wskaźnik?), który mam nadzieję działa na wszystkich platformach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-27 16:41:40
W bibliotece JNA widzimy, że używanie natywnego AWT w Javie 5 i 6 UnsatisfiedLinkError podczas uruchamiania bez głowy, więc użyj dynamicznego łączenia. Zobacz metodę Java_com_sun_jna_Native_getWindowHandle0
W https://github.com/twall/jna/blob/master/native/dispatch.c .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-02 04:01:56
Jest to to samo, co odpowiedź Jareda Macda, ale wykorzystuje odbicie, aby Kod mógł się skompilować i załadować na komputerze spoza systemu Windows. Oczywiście, że się nie uda, jeśli spróbujesz to nazwać.
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);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-03 18:43:30