Reputation: 105
So here is what is happening. I am using User32 to use the FindWindowA function, where my test case is Notepad (i.e. "Untitled - Notepad"). I then use several other functions like GetWindowInfo and GetWindowRect, and the values returned are strangely all 0. So here is what I do in 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);
The output results in this:
Pointer is valid.
result of GetWindowInfo: true
60
0
0
0, 0, 0, 0
result of GetWindowRect: true
0, 0, 0, 0
I used Notepad as a test case because it's just a base, one-window program. Why am I getting "0" for everyone of these values? The window handle is clearly not null, and in theory should work.
For extra information, here are my structs that I made for JNA so it would map them:
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"});
}
}
I am working with the WinAPI using Java and the JNA library. User32 is used to call the above calls.
Any help would be appreciated. I cannot find a lot of info related to why this is happening (even on the WinAPI documentation). Thanks.
Upvotes: 0
Views: 670
Reputation: 596186
You are creating instances of your classes, and then manually calling getPointer()
on them to allocate native memory to give to the Win32 API to populate, but you are not read()
'ing that native memory back into your class members afterwards, which is why the members remain all zeros after the functions have exited.
Per the getPointer()
documentation:
Return a
Pointer
object to this structure. Note that if you use the structure's pointer as a function argument, you are responsible for callingwrite()
prior to the call andread()
after the call. These calls are normally handled automatically by theFunction
object when it encounters aStructure
argument or return value. The returned pointer may not have meaning forStructure.ByValue
structure representations.
For example:
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
Otherwise, you should change the declaration of user32.GetWindowInfo()
to take a WinAPI.WINDOWINFO
parameter instead of a Pointer
parameter. Same with user32.GetWindowRect()
and WinAPI.RECT
. Let JNA handle the serialization of native memory for you.
Upvotes: 3