You need not declare the entire Microsoft® Win32® API yourself. The com.ms.win32 package provides classes that contain these declarations. All you have to do is import the correct class or classes. The J/Direct Message Box example could be simplified to the following:
import com.ms.win32.*; class ShowMsgBox { public static void main(String args[]) { MessageBox(0, "It worked!", "This message box from Java", 0); } }
The available APIs are declared in a set of classes, one for each Windows DLL, as shown in the following table.
Import | DLL Name | Contains |
Kernel32.class | KERNEL32.DLL | Base API |
Gdi32.class | GDI32.DLL | Graphics |
Ole32.class | OLE32.DLL | J/Direct methods |
User32.class | USER32.DLL | User interface |
Advapi32.class | ADVAPI32.DLL | Crypto API, event logging |
Shell32.class | SHELL32.DLL | Interface to Microsoft® Windows® Explorer |
Winmm.class | WINMM.DLL | Multimedia |
Spoolss.class | SPOOLSS.DLL | Spooling |
For instance, MessageBox is contained in USER32.DLL and therefore declared in User32.class; import this class (or the whole package) and you can call MessageBox directly.
Windows constants are in the com.ms.win32.wina-winz classes. To access these, import com.ms.win32.win and use win.[CONSTANT_NAME], shown as follows. Don't try to take a shortcut by extending or implementing com.ms.win32.win in your class; doing so will require that the entire class be loaded each time you load your class. Write out "win.xxx" instead.
System.out.println("MAX_PATH = " + win.MAX_PATH);
Finally, the supported Windows structures are declared in a set of class files that have the structure name as the class name, such as com.ms.win32.RECT.class. Just import these and you can use the Windows structures as though they were Java classes.
The com.ms.win32 classes are an optional part of the Microsoft SDK for Java. if you don't have them, just reinstall the VM. (The Java sources are in the \Src\Win32API subdirectory of the Microsoft SDK for Java.)
Because the classes contain only declarations, your users won't need to have them installed on their computers, but you'll need them to compile.
For importing the ANSI or Unicode DLL version, or the optimal version depending on the platform, see Calling Different Versions of DLL Functions.
Many Windows functions (in particular, the USER32 functions) require the application instance handle as a parameter. In Win32, an instance handle is defined the same as a module handle. Thus, the instance handle can be obtained by passing NULL to the GetModuleHandle function.
/** @dll.import("KERNEL32") */ private static native int GetModuleHandle(String modName); int hInst = GetModuleHandle(null);
Windows applications written in C have a WinMain function where execution begins. Java applications written in C have a main function instead.
The Microsoft® Windows® operating system passes four parameters to WinMain. The following table shows how to obtain these values from Java.
The application instance handle | Pass NULL to the GetModuleHandle function. |
The previous instance handle | In Win32, this value is always NULL. |
The command line | Passed as the String args[] parameter to main. |
The default value to pass to ShowWindow | Can be obtained by GetStartupInfo. However, it is recommended that Microsoft® Win32® applications pass SW_SHOWDEFAULT to ShowWindow rather than using the value passed to WinMain. |
Use the jexegen tool to create an .exe file that can be launched like a Windows application. When using jexegen, you can select whether to build a GUI executable or a console executable. The default is console, but you can select GUI by specifying the /W option. For example, consider the following Java application:
public class app { public static void main(String args[]) { int hInst = GetModuleHandle(null); MessageBox(0,"Instance handle is " + Integer.toHexString(hInst),"",0); } /** @dll.import("KERNEL32") */ private static native int GetModuleHandle(String modName); /** @dll.import("USER32") */ private static native int MessageBox(int hWndOwner,String text, String title,int MyStyle); }
This class can be converted to a GUI executable by executing the following command lines:
jvc app jexegen /W /out:app.exe /main:app *.class
For more details on jexegen, see the jexegen section of the Tools Reference.