WinAPI GetWindowInfo 和 GetWindowRect 返回值为 0

WinAPI GetWindowInfo and GetWindowRect Returning Values of 0

这就是正在发生的事情。我正在使用 User32 来使用 FindWindowA 函数,我的测试用例是记事本(即“无标题 - 记事本”)。然后我使用其他几个函数,如 GetWindowInfo 和 GetWindowRect,奇怪的是,返回的值全为 0。所以我在 Java:

中所做的
Pointer windowHandle = user32.FindWindowA(null, "Untitled - Notepad");
System.out.println(windowHandle == null ? "Pointer is NULL" : "Pointer is valid.");

WinAPI.WINDOWINFO windowInfo = new WinAPI.WINDOWINFO();
Pointer windowInfoPtr = windowInfo.getPointer();
System.out.println("result of GetWindowInfo: " + user32.GetWindowInfo(windowHandle, windowInfoPtr));

System.out.println(windowInfo.cbSize);
System.out.println(windowInfo.dwWindowStatus);
System.out.println(windowInfo.dwStyle);

WinAPI.RECT rcWindow = windowInfo.rcWindow;
System.out.println(rcWindow.bottom.longValue() + ", " + rcWindow.left.longValue() + ", " + rcWindow.right.longValue() + ", " + rcWindow.top.longValue());

WinAPI.RECT r = new WinAPI.RECT();
Pointer rPtr = r.getPointer();

System.out.println("result of GetWindowRect: " + user32.GetWindowRect(windowHandle, rPtr));

System.out.println(r.top + ", " + r.left + ", " + r.bottom + ", " + r.right);

输出结果是这样的:

Pointer is valid.
result of GetWindowInfo: true
60
0
0
0, 0, 0, 0
result of GetWindowRect: true
0, 0, 0, 0

我使用记事本作为测试用例,因为它只是一个基础 one-window 程序。为什么我对这些值的每个人都得到“0”? window 句柄显然不为空,理论上应该有效。

有关额外信息,这是我为 JNA 制作的结构,因此它会映射它们:

    public static class WINDOWINFO extends Structure {
        public int cbSize = this.size();
        public RECT rcWindow;
        public RECT rcClient;
        public int dwStyle;
        public int dwExStyle;
        public int dwWindowStatus;
        public int cxWindowBorders;
        public int cyWindowBorders;
        public short atomWindowType;
        public short wCreatorVersion;

        public WINDOWINFO() {
            super();
        }

        public WINDOWINFO(Pointer p) {
            super(p);
        }

        protected List<String> getFieldOrder() {
            return Arrays.asList(new String[] {"cbSize", "rcWindow", "rcClient", "dwStyle", "dwExStyle", "dwWindowStatus", "cxWindowBorders", "cyWindowBorders", "atomWindowType", "wCreatorVersion"});
        }
    }

    public static class RECT extends Structure {
        public NativeLong left;
        public NativeLong top;
        public NativeLong right;
        public NativeLong bottom;

        public RECT() {
            super();
        }

        public RECT(Pointer p) {
            super(p);
        }

        protected List<String> getFieldOrder() {
            return Arrays.asList(new String[] {"left", "top", "right", "bottom"});
        }
    }

我正在使用 Java 和 JNA 库来处理 WinAPI。 User32用于调用以上调用。

如有任何帮助,我们将不胜感激。我找不到很多与发生这种情况的原因相关的信息(即使在 WinAPI 文档中也是如此)。谢谢

您正在创建 classes 的实例,然后在它们上手动调用 getPointer() 以分配本机内存以提供给 Win32 API 进行填充,但您不是read()之后将该本机内存返回到您的 class 成员中,这就是为什么在函数退出后成员仍然全为零的原因。

根据 getPointer() 文档:

Return a Pointer object to this structure. Note that if you use the structure's pointer as a function argument, you are responsible for calling write() prior to the call and read() after the call. These calls are normally handled automatically by the Function object when it encounters a Structure argument or return value. The returned pointer may not have meaning for Structure.ByValue structure representations.

例如:

WinAPI.WINDOWINFO windowInfo = new WinAPI.WINDOWINFO();
windowInfo.write(); // <-- add this
System.out.println("result of GetWindowInfo: " + user32.GetWindowInfo(windowHandle, windowInfo.getPointer()));
windowInfo.read(); // <-- add this
...
WinAPI.RECT r = new WinAPI.RECT();
//r.write(); // <-- optional in this case
System.out.println("result of GetWindowRect: " + user32.GetWindowRect(windowHandle, r.getPointer()));
r.read(); // <-- add this

否则,您应该更改 user32.GetWindowInfo() 的声明以采用 WinAPI.WINDOWINFO 参数而不是 Pointer 参数。与 user32.GetWindowRect()WinAPI.RECT 相同。让 JNA 为您处理本机内存的序列化。