首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Java Swing中,如何获得对窗口的Win32窗口句柄(hwnd)引用?

在Java Swing中,如何获得对窗口的Win32窗口句柄(hwnd)引用?
EN

Stack Overflow用户
提问于 2008-12-22 17:20:58
回答 6查看 45.8K关注 0票数 28

在Java1.4中,你可以使用((SunToolkit) Toolkit.getDefaultToolkit()).getNativeWindowHandleFromComponent() ),但它被删除了。

看起来你现在必须使用JNI来做这件事。您有JNI代码和样例Java代码来做这件事吗?

我需要它来调用Win32 GetWindowLong和SetWindowLong API调用,这可以通过Jawin库来完成。

我想要一些非常精确的东西,这样我就可以传递一个对JDialog或JFrame的引用,并获得窗口句柄。

Swing transparency using JNI可能是相关的。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-01-05 17:40:06

下面的代码允许您传递一个组件来获取它的窗口句柄(HWND)。要确保组件具有相应的窗口句柄,请在组件上调用isLightWeight()并验证它是否等于false。如果没有,可以通过调用Component.getParent()来尝试它的父类。

Java代码:

代码语言:javascript
运行
复制
package win32;
public class Win32 {
    public static native int getWindowHandle(Component c);
}

头文件main.h:

代码语言:javascript
运行
复制
/* 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源代码main.c:

代码语言:javascript
运行
复制
#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;

}
票数 10
EN

Stack Overflow用户

发布于 2010-09-17 05:02:35

您无需编写任何C/JNI代码。来自Java:

代码语言:javascript
运行
复制
import sun.awt.windows.WComponentPeer;

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

注意事项:

  • 这使用了sun.*包。显然,这不是公共API。但它不太可能改变(我认为比上面的解决方案更不可能失败)。
  • 这将只在Windows上编译和运行。您需要将此代码转换为反射代码,才能使其可移植。
票数 23
EN

Stack Overflow用户

发布于 2008-12-23 18:50:57

这个小JNI方法接受窗口标题并返回相应的窗口句柄。

代码语言:javascript
运行
复制
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;
 }

更新:

有了JNA,这就简单了一点。我做了一个small example,它找到了句柄,并用它把程序带到了前面。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/386792

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档