Fix for JFrame and Alt menu on Win32

This code allows Java JFrames to behave like the LWJGL window, ie, no system menu when you click the icon.

Header:


/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class library_NativeRoutines */

#ifndef _Included_library_NativeRoutines
#define _Included_library_NativeRoutines
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     library_NativeRoutines
 * Method:    hookWindowProcess
 * Signature: (Ljavax/swing/JFrame;)I
 */
JNIEXPORT jint JNICALL Java_library_NativeRoutines_hookWindowProcess
  (JNIEnv *, jclass, jobject);

#ifdef __cplusplus
}
#endif
#endif

C++ source:


#include "Library.h"
#include <Windows.h>
#include <jawt_md.h>
#include <jawt.h>
#include <map>

std::map<HWND, WNDPROC> processMap;

LRESULT WINAPI CALLBACK HookedWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	if (uMsg == 0x0112 && wParam == 0xF093) {
		return 0;
	}
	if (uMsg == 0x0112 && wParam == 0xF063) {
		return 0;
	}
	if (uMsg == 0x00A5 || uMsg == 0x00A4) {
		return 0;
	}
	std::map<HWND, WNDPROC>::iterator mWndProc = processMap.find(hWnd);
	if (mWndProc == processMap.end()) {
		return 0; // Cannot process
	}
	return CallWindowProc(mWndProc->second, hWnd, uMsg, wParam, lParam);
}

JNIEXPORT jint JNICALL Java_library_NativeRoutines_hookWindowProcess
  (JNIEnv *env, jclass klass, jobject jframe) {
    typedef jboolean (JNICALL *PJAWT_GETAWT)(JNIEnv*, JAWT*);
    JAWT awt;
    JAWT_DrawingSurface* ds;
    JAWT_DrawingSurfaceInfo* dsi;
    JAWT_Win32DrawingSurfaceInfo* dsi_win;
    jboolean result;
    jint lock;
    HWND hWnd = 0;
 
    HMODULE hAWT = GetModuleHandle(L"jawt.dll");
    if (!hAWT)
       hAWT = LoadLibrary(L"jawt.dll");
    if (hAWT) {
        PJAWT_GETAWT JAWT_GetAWT = (PJAWT_GETAWT) GetProcAddress(hAWT, "_JAWT_GetAWT@8");
        if (JAWT_GetAWT) {
            awt.version = JAWT_VERSION_1_3;
            result = JAWT_GetAWT(env, &awt);
            if (result != JNI_FALSE) {
                ds = awt.GetDrawingSurface(env, jframe);
                if (ds != NULL) {
                    lock = ds->Lock(ds);
                    if((lock & JAWT_LOCK_ERROR) == 0) {
                        dsi = ds->GetDrawingSurfaceInfo(ds);
                        dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
                        hWnd = dsi_win->hwnd;
                        ds->FreeDrawingSurfaceInfo(dsi);
                        ds->Unlock(ds);
					} else {
						return 5;
					}
				} else {
					return 4;
				}
                awt.FreeDrawingSurface(ds);
			} else {
				return 3;
			}
		} else {
			return 2;
		}
	} else {
		return 1;
	}
	LONG oldWndProc = GetWindowLong(hWnd, GWL_WNDPROC);
	if (!oldWndProc) {
		return 6;
	}
	processMap[hWnd] = (WNDPROC) oldWndProc;
	if (!SetWindowLong(hWnd, GWL_WNDPROC, (LONG) HookedWndProc)) {
		return 7;
	}
	return 0;
}

Java source:


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package library;

import javax.swing.JFrame;

public class NativeRoutines {

	private static native int hookWindowProcess(JFrame jf);

	public static boolean hookWndProc(JFrame jf) {
		try {
			int result = hookWindowProcess(jf);
			return result == 0;
		} catch (Throwable err) {
			err.printStackTrace();
			return false;
		}
	}
}

How to disable the system menu and double icon click that closes the window:


try {
 System.loadLibrary("jawt");
 System.loadLibrary("Library");
 library.NativeRoutines.hookWndProc(yourJFrame);
} catch (UnsatisfiedLinkError ex) {
 // handle
}

Hope this helps some of you out there.