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.