Java Native Access 不正确 Windows 句柄
Java Native Access incorrect Windows Handle
我正在使用 javafx 制作覆盖应用程序。
我想在按下按钮时将键输入发送到第三方应用程序。
我正在使用 JNA 来聚焦应用程序和 Robot 来模拟按键。
我可以使用 FindWindows
:
正确地获得 Windows 句柄
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
但是,当我想将那个句柄与
一起使用时
if(windowsHandle != null) WindowsFinder.INSTANCE.SetWindowPos(windowsHandle, WindowsFinder.WINDOW_TOPMOST, 0, 0, 0, 0, 43);
不行,Native.getLastError()
return 1400,意思是Invalid Window Handle
。我不明白为什么我的句柄不正确,因为它来自 JNA。
我在检索句柄后立即执行 setWindowsPos
,没有触及目标 windows。我担心将句柄保存为 Java 指针对象然后在 JNA 中转换回时会出现转换错误。
我也试过使用 SetFocus
,这次我得到错误 5 (ERROR_ACCESS_DENIED)。
代码来自本论坛(法语):https://www.developpez.net/forums/d1297379/java/general-java/focus-fenetre-exterieure/
有什么我遗漏的吗?
P.S。 : FindWindow
似乎工作有它 returns null 当我“我的 windows” 不存在或不是这样拼写的。
您的句柄无效,只是不是您认为的那样。
问题出在您 SetWindowPos
:
的函数映射中
boolean SetWindowPos(Pointer hWnd, int hWndAfter, int x, int y, int cx, int cy, int flags);
}
第二个参数是 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
);
您可以通过将第二个参数更改为 Pointer
以匹配第一个参数,并将您的 WINDOW_TOPMOST
更改为 new Pointer(-1)
来使其工作。但是,您可能希望对两个参数都使用 JNA 的 HWND
类型。
我正在使用 javafx 制作覆盖应用程序。 我想在按下按钮时将键输入发送到第三方应用程序。 我正在使用 JNA 来聚焦应用程序和 Robot 来模拟按键。
我可以使用 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
但是,当我想将那个句柄与
一起使用时if(windowsHandle != null) WindowsFinder.INSTANCE.SetWindowPos(windowsHandle, WindowsFinder.WINDOW_TOPMOST, 0, 0, 0, 0, 43);
不行,Native.getLastError()
return 1400,意思是Invalid Window Handle
。我不明白为什么我的句柄不正确,因为它来自 JNA。
我在检索句柄后立即执行 setWindowsPos
,没有触及目标 windows。我担心将句柄保存为 Java 指针对象然后在 JNA 中转换回时会出现转换错误。
我也试过使用 SetFocus
,这次我得到错误 5 (ERROR_ACCESS_DENIED)。
代码来自本论坛(法语):https://www.developpez.net/forums/d1297379/java/general-java/focus-fenetre-exterieure/
有什么我遗漏的吗?
P.S。 : FindWindow
似乎工作有它 returns null 当我“我的 windows” 不存在或不是这样拼写的。
您的句柄无效,只是不是您认为的那样。
问题出在您 SetWindowPos
:
boolean SetWindowPos(Pointer hWnd, int hWndAfter, int x, int y, int cx, int cy, int flags);
}
第二个参数是 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
);
您可以通过将第二个参数更改为 Pointer
以匹配第一个参数,并将您的 WINDOW_TOPMOST
更改为 new Pointer(-1)
来使其工作。但是,您可能希望对两个参数都使用 JNA 的 HWND
类型。