Java - JNA - User32.INSTANCE.GetLayeredWindowAttributes returns wrong transparency value

0

After years of finding answers here, this case I could not find anything so I post question about here

I try to get the transparency level of some window using GetLayeredWindowAttributes function in Win32 API.

In C++/C, to get the transparency level I use the following code:

DWORD flags = LWA_ALPHA;
BYTE alpha;
if (GetLayeredWindowAttributes(target_hwnd, nullptr, &alpha, &flags))
{
  // Here I got the value inside alpha variable
}

In Java + JNA, I did not found any straightforward example. But I think that I come with something that should work. Here is what I did in Java:

ByteByReference alpha = new ByteByReference();
if (User32.INSTANCE.GetLayeredWindowAttributes(windowHwnd,null,alpha,new IntByReference((byte) 0x00000002))) {
    // Here I got the transparency in alpha.getValue()
}

The issue is that for some reason, the java code will return -27 while the C++ code will return for the same window 229 that is the correct value.

I noticed that when the transparency is 255, both codes (Java and C++) will return 255 but for some reason, the Java code is return wrong values and I don't know why.

Any idea what I am doing wrong and how to fix it?

Thanks!

java
winapi
jna
asked on Stack Overflow Jan 9, 2021 by gil123

1 Answer

0

I still have no idea why it happens but I figure out a workaround how to fix the returned value


public static int getWindowTransparency(WinDef.HWND windowHwnd) {
    ByteByReference alpha = new ByteByReference();
    // According to my tests, this API call will return false when the transparency is 255 (This is unlike when using it from C)
    // so we just assume it as 255 and return 255
    if (!User32.INSTANCE.GetLayeredWindowAttributes(windowHwnd, null, alpha, new IntByReference((byte) 0x00000002)))
        return 255;

    int transparency = alpha.getValue();

    // Here we fix some strange behavior that the value may be negative.
    // This will fix it and make sure it between 0 and 255
    if (transparency < 0)
        transparency = 128 + (128 - Math.abs(transparency));

    return transparency;
}

If this is wrong please let me know and I will update the answer. Thanks.

I tested it and compared the results with the C++ version and it seems to return the correct value all the time.

answered on Stack Overflow Jan 9, 2021 by gil123

User contributions licensed under CC BY-SA 3.0