I'm learning the new Java FFM API. During the learning, I decided to use Windows SDK to control Taskbar.
The interface ITtaskbarList3 represents the Taskbar and provides functions to control it.
I used the jextract tool to generate necessary classes:
jextract --output target/generated-sources/jextract -t "taskbar_test.gen" -l :shell32 -l :Explorerframe -l :ole32 -I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared" -I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um" -I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\km" -I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\km\crt" "C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um\ShObjIdl_core.h" In the code below, I'm trying to obtain CLSID and IID from string and use them to obtain an instance of ITaskbarList3:
package taskbar_test; import taskbar_test.gen.CLSID; import taskbar_test.gen.ShObjIdl_core_h; import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; public class ComStart { public static final String GUID_FORMAT = "{%s}"; // CLSID of ITaskbarList3 public static final String CLSID_CONST = "56FDF344-FD6D-11d0-958A-006097C9A090"; // IID of ITaskbarList3 public static final String IID_CONST = "EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF"; public static void main(String[] args) { try (var arena = Arena.ofConfined()) { // https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-clsidfromstring#remarks // The CLSID format is {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. var clsidString = arena.allocateFrom(GUID_FORMAT.formatted(CLSID_CONST)); var iidString = arena.allocateFrom(GUID_FORMAT.formatted(IID_CONST)); var clsid = arena.allocate(CLSID.layout()); var iid = arena.allocate(CLSID.layout()); var taskbarPtr = arena.allocate(ShObjIdl_core_h.C_POINTER); int hr = ShObjIdl_core_h.CoInitializeEx(MemorySegment.NULL, ShObjIdl_core_h.COINIT_MULTITHREADED()); if (hr != ShObjIdl_core_h.S_OK()) { throw new RuntimeException("CoInitialize failed with error code: " + hr); } hr = ShObjIdl_core_h.CLSIDFromString(clsidString, clsid); if (hr != ShObjIdl_core_h.S_OK()) { throw new RuntimeException("CLSIDFromString failed with error code: " + hr); } hr = ShObjIdl_core_h.IIDFromString(iidString, iid); if (hr != ShObjIdl_core_h.S_OK()) { throw new RuntimeException("IIDFromString failed with error code: " + hr); } hr = ShObjIdl_core_h.CoCreateInstance(clsid, MemorySegment.NULL, ShObjIdl_core_h.CLSCTX_REMOTE_SERVER(), iid, taskbarPtr); if (hr != ShObjIdl_core_h.S_OK()) { if (hr == ShObjIdl_core_h.REGDB_E_CLASSNOTREG()) { System.out.println("COM class is not registered!"); } throw new RuntimeException("CoCreateInstance failed with error code: " + hr); } } finally { ShObjIdl_core_h.CoUninitialize(); } } } I expect to get the instance, but instead I get error from function CLSIDFromString that the string does not have correct format. I do not understand why, because the format is following documentation.
How the code should look like to be able to obtain instance correctly so I can manage taskbar, namely set progress value.
Thank you.
TaskbarButtonCreatedmessage before it can use theITaskBarList...interfaces.