Tips/JNI_HWND のバックアップ差分(No.15)
- バックアップ一覧
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Tips/JNI_HWND へ行く。
- 1 (2011-05-31 (火) 15:47:32)
- 2 (2011-07-29 (金) 22:06:11)
- 3 (2011-08-01 (月) 15:30:50)
- 4 (2011-08-02 (火) 13:06:26)
- 5 (2011-08-02 (火) 23:24:01)
- 6 (2011-08-20 (土) 21:37:18)
- 7 (2011-11-07 (月) 21:08:07)
- 8 (2012-01-03 (火) 04:42:25)
- 9 (2013-10-16 (水) 14:28:04)
- 10 (2013-10-31 (木) 16:59:15)
- 11 (2014-09-03 (水) 18:17:47)
- 12 (2014-10-02 (木) 15:19:28)
- 13 (2014-11-08 (土) 01:41:12)
- 14 (2015-09-29 (火) 19:37:11)
- 15 (2016-04-12 (火) 16:06:53)
- 16 (2017-04-07 (金) 13:51:51)
- 17 (2017-10-27 (金) 16:26:13)
- 18 (2018-02-27 (火) 13:10:51)
- 19 (2018-05-30 (水) 20:59:47)
- 追加された行はこの色です。
- 削除された行はこの色です。
---
title: JNIでJFrameのHWNDを取得
author: aterai
pubdate: 2008-09-04
description: JNI(Java Native Interface)でJFrame(SunAwtFrame)のHWND(ウィンドウハンドル)を取得します。
---
#contents
//[[コメント欄>Comments/Swing]]から移動
* 概要 [#d54756f6]
[http://www.telejapan.com/af/master/memo/memo_Java.html JNI Windowsでウィンドウハンドルを取得する - Memo of Master]の方法2を参考にして、`JNI`(`Java Native Interface`)で`JFrame`(`SunAwtFrame`)の`HWND`(ウィンドウハンドル)を取得します。
- [http://ateraimemo.com/data/swing/hwndTest.zip hwndTest.zip(サンプル)]
#ref(https://lh3.googleusercontent.com/-NNjiMJe_o94/TeSO493_q3I/AAAAAAAAA8k/KU8B7ms4SQE/s800/JNI_HWND.png)
* 環境 [#q9fd6c07]
- `Microsoft Windows XP [Version 5.1.2600]`
- `JDK 1.6.0_04`
- `Microsoft Visual Studio .NET 2003\vc7`
* サンプルコード [#yfef3d00]
#code{{
import java.awt.*;
import javax.swing.*;
public class windowHandler{
public native static int getHWND(Object obj);
static {
System.loadLibrary("hwndTest");
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
try{
//UIManager.getInstalledLookAndFeels();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(Exception e) {
e.printStackTrace();
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(320, 240);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
int hwnd = getHWND(frame);
frame.setTitle("HWND: 0x"+Integer.toHexString(hwnd).toUpperCase());
}
}
}}
#code{{
#include "windowHandler.h"
#include "jawt_md.h"
#include <windows.h>
JNIEXPORT jint JNICALL Java_windowHandler_getHWND(
JNIEnv *env, jobject jobj, jobject jframe) {
JAWT awt;
JAWT_DrawingSurface* ds;
JAWT_DrawingSurfaceInfo* dsi;
JAWT_Win32DrawingSurfaceInfo* dsi_win;
jint lock;
HWND hWnd;
awt.version = JAWT_VERSION_1_4;
if (JAWT_GetAWT(env, &awt) == JNI_FALSE) {
return 0;
}
ds = awt.GetDrawingSurface(env, jframe);
if (ds == NULL) {
return 0;
}
lock = ds->Lock(ds);
if ((lock & JAWT_LOCK_ERROR) != 0) {
awt.FreeDrawingSurface(ds);
return 0;
}
dsi = ds->GetDrawingSurfaceInfo(ds);
if (dsi == NULL) {
ds->Unlock(ds);
awt.FreeDrawingSurface(ds);
return 0;
}
dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
hWnd = dsi_win->hwnd;
/* Free the drawing surface info */
ds->FreeDrawingSurfaceInfo(dsi);
/* Unlock the drawing surface */
ds->Unlock(ds);
/* Free the drawing surface */
awt.FreeDrawingSurface(ds);
return (jint)hWnd;
}
}}
* 解説 [#gcd89e73]
以下のようにコンパイル、実行すると`JFrame`のタイルトバーに`HWND`が表示されます。
#code{{
@echo off
SETLOCAL
"%JAVA_HOME%\bin\javac" windowHandler.java
"%JAVA_HOME%\bin\javah" -jni windowHandler
set SDK=C:\Program Files\Microsoft Visual Studio .NET 2003\vc7
rem set SDK=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC
"%SDK%\bin\cl.exe" /c -I"%SDK%\include" -I"%SDK%\PlatformSDK\include" -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -IhwndTest.h hwndTest.c
set LIB=%SDK%\lib;%SDK%\PlatformSDK\lib
"%SDK%\bin\link.exe" /DLL hwndTest.obj "%JAVA_HOME%\lib\jawt.lib"
set Path=%Path%;%JAVA_HOME%\jre\bin
"%JAVA_HOME%\bin\java" windowHandler
}}
----
`JNI`を使用せず、以下のように`HWND`を取得する方法もあります。
-[http://stackoverflow.com/questions/386792/in-java-swing-how-do-you-get-a-win32-window-handle-hwnd-reference-to-a-window winapi - In Java Swing how do you get a Win32 window handle (hwnd) reference to a window? - Stack Overflow]に投稿されているJared MacD.さんのコードを引用
#code{{
import java.awt.*;
import javax.swing.*;
import sun.awt.windows.WComponentPeer;
public class WComponentPeerTest {
public static long getHWnd(Frame f) {
return f.getPeer()!=null ? ((WComponentPeer)f.getPeer()).getHWnd() : 0;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() { createAndShowGUI(); }
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
f.setTitle("HWnd: "+getHWnd(f));
}
}
}}
* 参考リンク [#z82fc32a]
- [http://www.telejapan.com/af/master/memo/memo_Java.html JNI Windowsでウィンドウハンドルを取得する - Memo of Master]
- [http://docs.oracle.com/javase/jp/6/technotes/guides/jni/ JDK 6 Java Native Interface 関連 API & 開発者ガイド -- Sun Microsystems]
* コメント [#h2768609]
#comment
- `Win32`の`MS Visual C++`の`WndProc()`にコールバックされるメッセージを`JNI`で検出する掲載もあると助かります。 -- &user(Java, C, JNI どれも超初心者); &new{2011-07-29 (金) 22:06:11};
-- `JNI`関係勉強しないとと思いながら最近はさっぱりです。どこかにサンプルがないか適当に検索してみたら、`JNA`に`WndProcCallbackListener`([http://stackoverflow.com/questions/4041174/create-a-native-windows-window-in-jna-and-some-getwindowlong-with-gwl-wndproc Create a native Windows window in JNA and some GetWindowLong with GWL_WNDPROC])というそれっぽいのがあるみたいです。 -- &user(aterai); &new{2011-08-01 (月) 15:30:50};
- ありがとうござます。一応リンク拝見しましたがもう少し自力で調査してみます。もし分かったら簡単に報告を書き込みます。 -- &user(Java, C, JNI どれも超初心者); &new{2011-08-02 (火) 13:06:26};
- 結論:あきらめました。リスナー各所にコールバックで処理したい内容をベタに記述しました。 -- &user(Java, C, JNI どれも超初心者?); &new{2011-08-20 (土) 21:37:18};
#comment