基于this answer中的代码,我尝试在将其实现到实际程序之前做一个示例。但是,我收到以下错误:
c:\users\danie\dropbox\programming\code\notepad++\java\stack overflow\questions\jnitest\JNI.h(2): fatal error C1083: Cannot open include file: 'jni.h': No such file or directory.
我认为它与头文件的第二行有关,但是,这是自动生成的,所以我不确定。以下是源文件。
JNI.java
import java.awt.*;
import javax.swing.*;
public class JNI extends JFrame {
/**
* This should only allow resize in one direction with no glitches
*/
private JNI() {
super("JNI Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setMaximizedBounds(new java.awt.Rectangle(0, 0, 360, 1200));
setMaximumSize(new java.awt.Dimension(360, 1200));
setMinimumSize(new java.awt.Dimension(360, 600));
setPreferredSize(new java.awt.Dimension(360, 600));
setVisible(true);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
new JNI();
}
static {
if (System.getProperty("sun.arch.data.model").equals("32")) {// 32-bit JVM
System.loadLibrary("my32bitdll");
System.out.println("Running 32-bit JVM");
} else { // 64-bit JVM
System.loadLibrary("my64bitdll");
System.out.println("Running 64-bit JVM");
}
}
// Sets a window to never be resized above or below these minimum widths/heights
public static native int setMinMaxResizeBoundaries(int hwnd, int minWidth, int minHeight, int maxWidth, int maxHeight);
public static native int getComponentHWND(Component c);
}
DllMain.cpp
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
#include "JNI.h"
// Global variables defined in DllMain.cpp
// Used for setMinMaxResizeBoundaries()
struct SHwndMinMax
{
HWND hwnd;
int minWidth;
int minHeight;
int maxWidth;
int maxHeight;
WNDPROC prefWndProc;
};
SHwndMinMax gsHwndMinMax[2048];
int gsHwndMinMaxCount = 0;
LRESULT CALLBACK MinMaxWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
// Code added somwhere:
// setMinMaxResizeBoundaries()
// Sets the resize boundary window sizes, so the window will not be resized above/below that size
JNIEXPORT jint JNICALL Java_JNI_setMinMaxResizeBoundaries(JNIEnv* env, jclass cls,
jint hwnd,
jint minWidth, jint minHeight,
jint maxWidth, jint maxHeight)
{
// We create a hook for the window, and intercept the WM_GETMINMAXINFO message occurs, and update the info
if (IsWindow((HWND)hwnd))
{ // Let's add it
if (gsHwndMinMaxCount < 2048)
{ // We're good
// Can add code here to check if this option is valid or not--so it can later be "unhooked" by a separate function call
gsHwndMinMax[gsHwndMinMaxCount].hwnd = (HWND)hwnd;
gsHwndMinMax[gsHwndMinMaxCount].minWidth = minWidth;
gsHwndMinMax[gsHwndMinMaxCount].minHeight = minHeight;
gsHwndMinMax[gsHwndMinMaxCount].maxWidth = maxWidth;
gsHwndMinMax[gsHwndMinMaxCount].maxHeight = maxHeight;
gsHwndMinMax[gsHwndMinMaxCount].prefWndProc = (WNDPROC)SetWindowLongPtr((HWND)hwnd, GWLP_WNDPROC, (LONG_PTR)&MinMaxWindowProc);
// Success
++gsHwndMinMaxCount;
return(0);
} else {
// Failuire, too many hooks
return(-2);
}
} else {
// Failure, HWND is not valid
return(-1);
}
}
LRESULT CALLBACK MinMaxWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
int i;
MINMAXINFO* mmi;
for (i = 0; i < gsHwndMinMaxCount; i++)
{
if (hwnd == gsHwndMinMax[i].hwnd)
{ // This is our man, see if it's our message
if (msg == WM_GETMINMAXINFO)
{ // It is
// When maximized, window is at upper-left
mmi = (MINMAXINFO*)lParam;
mmi->ptMaxSize.x = gsHwndMinMax[i].maxWidth;
mmi->ptMaxSize.y = gsHwndMinMax[i].maxHeight;
mmi->ptMaxPosition.x = 0; // Can add code here to properly position the window centered in the screen, etc.
mmi->ptMaxPosition.y = 0; // Same here
// Set the minimum and maximum tracking size (when the user is resizing, what's the smallest and biggest window they see)
mmi->ptMinTrackSize.x = gsHwndMinMax[i].minWidth;
mmi->ptMinTrackSize.y = gsHwndMinMax[i].minHeight;
mmi->ptMaxTrackSize.x = gsHwndMinMax[i].maxWidth;
mmi->ptMaxTrackSize.y = gsHwndMinMax[i].maxHeight;
return(DefWindowProc(hwnd, msg, wParam, lParam));
} else {
// Nope, pass it on
return(CallWindowProc(gsHwndMinMax[i].prefWndProc, hwnd, msg, wParam, lParam));
}
}
}
return(0);
}
// getComponentHWND()
// Called to return the HWND of the component, if it has one.
JNIEXPORT jint JNICALL Java_JNI_getComponentHWND(JNIEnv* env, jclass cls, jobject obj)
{
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;
HMODULE _hAWT = 0;
// Load AWT Library
if (!_hAWT)
_hAWT = LoadLibrary(L"jawt.dll"); // for Java 1.4+
if (!_hAWT)
_hAWT = LoadLibrary(L"awt.dll"); // for Java 1.3
if (_hAWT)
{
PJAWT_GETAWT JAWT_GetAWT = (PJAWT_GETAWT)GetProcAddress(_hAWT, "JAWT_GetAWT");
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, obj);
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; // Failed to obtain the handle (not running on Windows)
ds->FreeDrawingSurfaceInfo(dsi);
} else {
hWnd = (HWND)-2; // Failed to get the drawing surface info block
}
ds->Unlock(ds);
} else {
hWnd = (HWND)-3; // Failed to lock the drawing surface to obtain information about it
}
awt.FreeDrawingSurface(ds);
} else {
hWnd = (HWND)-4; // Failed to get the drawing surface from the compoment
}
} else {
hWnd = (HWND)-5; // Failed to obtain a proper result from _JAWT_GetAWT()
}
} else {
hWnd = (HWND)-6; // Failed to find "_JAWT_GetAWT()" function
}
} else {
hWnd = (HWND)-7; // Failed to load awt.dll
}
return (jint)hWnd;
}
JNI.h - 使用批处理文件生成
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNI */
#ifndef _Included_JNI
#define _Included_JNI
#ifdef __cplusplus
extern "C" {
#endif
#undef JNI_FOCUS_TRAVERSABLE_UNKNOWN
#define JNI_FOCUS_TRAVERSABLE_UNKNOWN 0L
#undef JNI_FOCUS_TRAVERSABLE_DEFAULT
#define JNI_FOCUS_TRAVERSABLE_DEFAULT 1L
#undef JNI_FOCUS_TRAVERSABLE_SET
#define JNI_FOCUS_TRAVERSABLE_SET 2L
#undef JNI_TOP_ALIGNMENT
#define JNI_TOP_ALIGNMENT 0.0f
#undef JNI_CENTER_ALIGNMENT
#define JNI_CENTER_ALIGNMENT 0.5f
#undef JNI_BOTTOM_ALIGNMENT
#define JNI_BOTTOM_ALIGNMENT 1.0f
#undef JNI_LEFT_ALIGNMENT
#define JNI_LEFT_ALIGNMENT 0.0f
#undef JNI_RIGHT_ALIGNMENT
#define JNI_RIGHT_ALIGNMENT 1.0f
#undef JNI_serialVersionUID
#define JNI_serialVersionUID -7644114512714619750i64
#undef JNI_serialVersionUID
#define JNI_serialVersionUID 4613797578919906343i64
#undef JNI_INCLUDE_SELF
#define JNI_INCLUDE_SELF 1L
#undef JNI_SEARCH_HEAVYWEIGHTS
#define JNI_SEARCH_HEAVYWEIGHTS 1L
#undef JNI_OPENED
#define JNI_OPENED 1L
#undef JNI_serialVersionUID
#define JNI_serialVersionUID 4497834738069338734i64
#undef JNI_DEFAULT_CURSOR
#define JNI_DEFAULT_CURSOR 0L
#undef JNI_CROSSHAIR_CURSOR
#define JNI_CROSSHAIR_CURSOR 1L
#undef JNI_TEXT_CURSOR
#define JNI_TEXT_CURSOR 2L
#undef JNI_WAIT_CURSOR
#define JNI_WAIT_CURSOR 3L
#undef JNI_SW_RESIZE_CURSOR
#define JNI_SW_RESIZE_CURSOR 4L
#undef JNI_SE_RESIZE_CURSOR
#define JNI_SE_RESIZE_CURSOR 5L
#undef JNI_NW_RESIZE_CURSOR
#define JNI_NW_RESIZE_CURSOR 6L
#undef JNI_NE_RESIZE_CURSOR
#define JNI_NE_RESIZE_CURSOR 7L
#undef JNI_N_RESIZE_CURSOR
#define JNI_N_RESIZE_CURSOR 8L
#undef JNI_S_RESIZE_CURSOR
#define JNI_S_RESIZE_CURSOR 9L
#undef JNI_W_RESIZE_CURSOR
#define JNI_W_RESIZE_CURSOR 10L
#undef JNI_E_RESIZE_CURSOR
#define JNI_E_RESIZE_CURSOR 11L
#undef JNI_HAND_CURSOR
#define JNI_HAND_CURSOR 12L
#undef JNI_MOVE_CURSOR
#define JNI_MOVE_CURSOR 13L
#undef JNI_NORMAL
#define JNI_NORMAL 0L
#undef JNI_ICONIFIED
#define JNI_ICONIFIED 1L
#undef JNI_MAXIMIZED_HORIZ
#define JNI_MAXIMIZED_HORIZ 2L
#undef JNI_MAXIMIZED_VERT
#define JNI_MAXIMIZED_VERT 4L
#undef JNI_MAXIMIZED_BOTH
#define JNI_MAXIMIZED_BOTH 6L
#undef JNI_serialVersionUID
#define JNI_serialVersionUID 2673458971256075116i64
#undef JNI_EXIT_ON_CLOSE
#define JNI_EXIT_ON_CLOSE 3L
/*
* Class: JNI
* Method: setMinMaxResizeBoundaries
* Signature: (IIIII)I
*/
JNIEXPORT jint JNICALL Java_JNI_setMinMaxResizeBoundaries
(JNIEnv *, jclass, jint, jint, jint, jint, jint);
/*
* Class: JNI
* Method: getComponentHWND
* Signature: (Ljava/awt/Component;)I
*/
JNIEXPORT jint JNICALL Java_JNI_getComponentHWND
(JNIEnv *, jclass, jobject);
#ifdef __cplusplus
}
#endif
#endif
批处理文件
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
javac JNI.java
javah -jni JNI
cl /EHsc DllMain.cpp
pause
此外,我的所有文件都在同一目录中
感谢您解决此问题的任何帮助。
此外,如果有人能告诉我为什么我的控制台输出在批处理文件运行时看起来像这样
而不是这个
我很感激
修改
工作批处理文件。
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
javac JNI.java
javah -jni JNI
cl -I"C:/Program Files (x86)/Java/jdk1.8.0_92/include" -I"C:/Program Files (x86)/Java/jdk1.8.0_92/include/win32" -MD -LD DllMain.cpp -FeDllMain.dll
pause
请注意,如果有人有答案,这仍然没有显示步骤