79369464

Date: 2025-01-19 17:54:24
Score: 9.5 🚩
Natty:
Report link

Thanks to advices from all, I was able to create following code:

package taskbar_test;

import com.sun.glass.ui.Window;
import javafx.application.Application;
import javafx.stage.Stage;
import taskbar_test.gen.CLSID;
import taskbar_test.gen.ITaskbarList3;
import taskbar_test.gen.ITaskbarList3Vtbl;
import taskbar_test.gen.ShObjIdl_core_h;

import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FxWinTaskbar extends Application {

    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";

    @Override
    public void start(Stage stage) throws Exception {
        var button = new javafx.scene.control.Button("Click Me");
        button.setOnAction(e -> handleClick());

        var root = new javafx.scene.layout.StackPane(button);
        var scene = new javafx.scene.Scene(root, 300, 200);

        stage.setTitle("JavaFX Stage with Button");
        stage.setScene(scene);
        stage.show();
    }

    void handleClick() {
        long rawHandle = Window.getWindows().getFirst().getRawHandle();
        Executors.newSingleThreadExecutor().submit(() -> {
            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), StandardCharsets.UTF_16LE);
                var iidString = arena.allocateFrom(GUID_FORMAT.formatted(IID_CONST), StandardCharsets.UTF_16LE);
                var clsid = arena.allocate(CLSID.layout());
                var iid = arena.allocate(CLSID.layout());
                var taskbarPtr = arena.allocate(ShObjIdl_core_h.C_POINTER);
                MemorySegment windowHandle = arena.allocate(ValueLayout.ADDRESS, rawHandle);

                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_ALL(), 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);
                }
                var taskbarAddress = taskbarPtr.get(ValueLayout.ADDRESS, 0);
                var taskbarInstance = ITaskbarList3.reinterpret(taskbarAddress, arena, memorySegment -> {
                    System.out.println("Some cleanup...");
                });

                ITaskbarList3Vtbl.HrInit.Function functionHrInit = _x0 -> {
                    System.out.println("HrInit called");
                    return ShObjIdl_core_h.S_OK();
                };
                MemorySegment functionHrInitPtr = ITaskbarList3Vtbl.HrInit.allocate(functionHrInit, arena);

                var taskbarVtbl = ITaskbarList3.lpVtbl(taskbarInstance);
                hr = ITaskbarList3Vtbl.HrInit.invoke(functionHrInitPtr, taskbarVtbl);
                if (hr != ShObjIdl_core_h.S_OK()) {
                    throw new RuntimeException("HrInit failed with error code: " + hr);
                }

                ITaskbarList3Vtbl.SetProgressState.Function functionSetProgressState = (_x0, _x1, _x3) -> {
                    System.out.println("SetProgressState called");
                    return ShObjIdl_core_h.S_OK();
                };
                MemorySegment functionSetProgressStatePtr = ITaskbarList3Vtbl.SetProgressState.allocate(functionSetProgressState, arena);
                ITaskbarList3Vtbl.SetProgressState.invoke(functionSetProgressStatePtr, taskbarVtbl, windowHandle, ShObjIdl_core_h.TBPF_NORMAL());

                ITaskbarList3Vtbl.SetProgressValue.Function functionSetProgressValue = (_x0, _x1, _x2, _x3) -> {
                    System.out.println("SetProgressValue called");
                    return ShObjIdl_core_h.S_OK();
                };
                MemorySegment functionSetProgressValuePtr = ITaskbarList3Vtbl.SetProgressValue.allocate(functionSetProgressValue, arena);
                ITaskbarList3Vtbl.SetProgressValue.invoke(functionSetProgressValuePtr, taskbarVtbl, windowHandle, 50, 100);

                ITaskbarList3Vtbl.Release.Function functionRelease = _x0 -> {
                    System.out.println("Release called");
                    return ShObjIdl_core_h.S_OK();
                };
                MemorySegment functionReleasePtr = ITaskbarList3Vtbl.Release.allocate(functionRelease, arena);

                hr = ITaskbarList3Vtbl.Release.invoke(functionReleasePtr, taskbarVtbl);
                if (hr != ShObjIdl_core_h.S_OK()) {
                    throw new RuntimeException("Release failed with error code: " + hr);
                }

            } catch (Throwable ex) {
                ex.printStackTrace();

            } finally {
                ShObjIdl_core_h.CoUninitialize();
            }
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}

This code runs without any errors, but unfortunately it does not set any progress on a taskbar window. Does anyone have any advices on how to fix it?

Reasons:
  • Blacklisted phrase (0.5): Thanks
  • RegEx Blacklisted phrase (3): Thanks to advices
  • RegEx Blacklisted phrase (1.5): how to fix it?
  • RegEx Blacklisted phrase (3): Does anyone have any advices
  • Long answer (-1):
  • Has code block (-0.5):
  • Ends in question mark (2):
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Petr Štechmüller