javawindowswinapijava-native-interfacejna

JNA Binding for Win32 function DwmGetColorizationColor returning E_INVALIDARG error


I am trying to create a binding for the Win32 function DwmGetColorizationColor using JNA.

According to MSDN, this is the function signature:

HRESULT DwmGetColorizationColor(
    [out] DWORD *pcrColorization,
    [out] BOOL  *pfOpaqueBlend
);

This is the binding I created:

WinNT.HRESULT DwmGetColorizationColor(
    WinDef.DWORD pcrColorization,
    WinDef.Bool pfOpaqueBlend
);

This is how I am calling this method:

var pcrColorization = new WinDef.DWORD();
var pfOpaqueBlend = new WinDef.BOOL();

var result = CLibrary.INSTANCE.DwnGetColorizationColor(
                pcrColorization,
                pfOpaqueBlend
             );

if (!result.equals(S_OK)) {
    System.out.println(result);
    System.out.println(Kernel32.INSTANCE.GetLastError());
}

The problem with this is the result is non-zero with the value E_INVALIDARG and the output of GetLastError() is 127 (ERROR_PROC_NOT_FOUND).

I have zero experience with creating C/C++ or creating binding for it. But this looked fairly simple.

So what am doing wrong?


Solution

  • The function signatures are pointers:

    HRESULT DwmGetColorizationColor(
        [out] DWORD *pcrColorization,
        [out] BOOL  *pfOpaqueBlend
    );
    

    So you don't need a DWORD and BOOL, you need a DWORD * and BOOL *, pointers to the actual values stored elsewhere.

    The most direct mappings from the WinDef class would be DWORDByReference and BOOLByReference:

    WinNT.HRESULT DwmGetColorizationColor(
        WinDef.DWORDByReference pcrColorization,
        WinDef.BOOLByReference pfOpaqueBlend
    );
    

    After calling the function, you can use .getValue() on those variables to extract the returned value.

    Since a DWORD is just a 32-bit int, it can be more convenient to use IntByReference for that mapping if you choose, to save you the trouble of wrapping your int into a DWORD when constructing the DWORDByReference and an extra intValue() when fetching the returned value. Unfortunately there's no similar shortcut for boolean by reference, as the bit width is OS-dependent.