Home > database >  Java Native Access incorrect Windows Handle
Java Native Access incorrect Windows Handle

Time:02-16

I'm using javafx to make an overlay app. I want to send key input to a third party application when a button is pressed. I'm using JNA to focus the application and Robot to simulate key pressing.

I can correctly get a Windows Handle with FindWindows:

public interface WindowsFinder extends StdCallLibrary
{
    public static final int WINDOW_TOPMOST    = -1;

    public static final int WINDOW_NONTOPMOST = -2;

    Map<String, Object> UNICODE_OPTIONS   = new HashMap<String, Object>()
    {
        private static final long serialVersionUID = 1L;

        {
            put(OPTION_TYPE_MAPPER,
                    W32APITypeMapper.UNICODE);
            put(OPTION_FUNCTION_MAPPER,
                    W32APIFunctionMapper.UNICODE);
        }
    };

    Map<String, Object>     ASCII_OPTIONS     = new HashMap<String, Object>()
    {
        private static final long serialVersionUID = 1L;
        {
            put(OPTION_TYPE_MAPPER,
                    W32APITypeMapper.ASCII);
            put(OPTION_FUNCTION_MAPPER,
                    W32APIFunctionMapper.ASCII);
        }
    };

    Map<String, Object>     DEFAULT_OPTIONS   = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS
            : UNICODE_OPTIONS;

    WindowsFinder INSTANCE = (WindowsFinder) Native.load(
            "user32", WindowsFinder.class,
            DEFAULT_OPTIONS);

    Pointer FindWindow(String lpClassName, String lpWindowName);

    void SetFocus(Pointer hWnd);

    boolean SetWindowPos(Pointer hWnd, int hWndAfter, int x, int y, int cx,
                         int cy, int flags);
}
Pointer windowsHandle = WindowsFinder.INSTANCE.FindWindow(null, "my windows");
Result : native@0x10450

However, when I want to use that handle with

if(windowsHandle != null) WindowsFinder.INSTANCE.SetWindowPos(windowsHandle, WindowsFinder.WINDOW_TOPMOST, 0, 0, 0, 0, 43);

It doesn't work, and Native.getLastError() return 1400, which means Invalid Window Handle. I don't understand why my handle is incorrect, as it comes from JNA.

I execute setWindowsPos just after retrieving the handle, without touching to the targeted windows. I'm worried it is a conversion error when saving the handle as a Java Pointer object and then converting back in JNA.

I tried using SetFocus too, and this time I get the error 5 (ERROR_ACCESS_DENIED).

The code comes from this forum (written in French) : https://www.developpez.net/forums/d1297379/java/general-java/focus-fenetre-exterieure/

Is there something I'm missing ?

P.S. : FindWindow seems to work has it returns null when I "my windows" doesn't exist or isn't spelled like this.

CodePudding user response:

You have an invalid handle, just not the one you think.

The problem is in your function mapping for SetWindowPos:

boolean SetWindowPos(Pointer hWnd, int hWndAfter, int x, int y, int cx, int cy, int flags);
}

The second argument is a HWND:

BOOL SetWindowPos(
  [in]           HWND hWnd,
  [in, optional] HWND hWndInsertAfter,
  [in]           int  X,
  [in]           int  Y,
  [in]           int  cx,
  [in]           int  cy,
  [in]           UINT uFlags
);

You could get it to work by changing the second argument to Pointer to match the first, and changing your WINDOW_TOPMOST to a new Pointer(-1). However, you may want to use JNA's HWND type for both arguments.

  • Related