Search code examples
javawinapijna

Why does my call to winapi RegisterClassExW fail (using JNA)?


These are the winapi methods

ATOM WINAPI RegisterClassEx(
     _In_ const WNDCLASSEX *lpwcx
  );

typedef struct tagWNDCLASSEX {
  UINT      cbSize;
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
  HBRUSH    hbrBackground;
  LPCTSTR   lpszMenuName;
  LPCTSTR   lpszClassName;
  HICON     hIconSm;
} WNDCLASSEX, *PWNDCLASSEX;

My Java Code:-

public class WNDCLASSEX extends com.sun.jna.Structure {
    public int cbSize;
    public int style;
    public WNDPROC lpfnWndProc;
    public int cbClsExtra;
    public int cbWndExtra;
    public HMODULE hInstance;
    public HICON hIcon;
    public HCURSOR hCursor;
    public HBRUSH hbrBackground;
    public String lpszMenuName;
    public String lpszClassName;
    public HICON hIconSm;
}

public interface User32 extends StdCallLibrary {
    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
    Atom RegisterClassExW(WNDCLASSEX wc);
}

public class other {
  public static void main(String[] args){
      User32.WNDPROC WndProc = new User32.WNDPROC() {

         public LRESULT callback(HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam)
         {
            int id = User32.INSTANCE.GetWindowThreadProcessId(hWnd, null);
            return new LRESULT(0);
         }
      };
      WNDCLASSEX wc = new WNDCLASSEX();
      wc.style = 0;
      wc.lpfnWndProc = WndProc;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = 0;
      wc.hInstance = null;
      wc.hIcon = null;
      wc.hbrBackground = null;
      wc.cbSize= wc.size(); 
      wc.lpszMenuName = null; 
      wc.lpszClassName = "Magnifier";


    Atom atom = User32.INSTANCE.RegisterClassExW(wc);
  }
}

I got the following error if I call RegisterClassEx(wc) method. I think the problem is due to wc is a object but RegisterClassExW accepts pointer.

If it is the case, How to send wc as pointer? Else How can I solve this issue?

Error is

Exception in thread "main" java.lang.IllegalArgumentException: Unsupported argument type jna.extra.WNDCLASSEX at parameter 0 of function RegisterClassExW


Solution

  • WNDCLASSEX needs to extend Structure, and then you'll need to implement its getFieldOrder() method.

    public class WNDCLASSEX extends com.sun.jna.Structure {
        public int cbSize;
        public int style;
        public WNDPROC lpfnWndProc;
        public int cbClsExtra;
        public int cbWndExtra;
        public HMODULE hInstance;
        public HICON hIcon;
        public HCURSOR hCursor;
        public HBRUSH hbrBackground;
        public String lpszMenuName;
        public String lpszClassName;
        public HICON hIconSm;
        public List getFieldOrder() {
            return Arrays.asList("cbSize","style","lpfnWndProc","cbClsExtra","cbWndExtra","hInstance","hIcon","hCursor","hbrBackground","lpszMenuName","lpszClassName","hIconSm");
        }
    }