-1

I am doing some powerpoint shape building using Jacob from Java, and I am stuck on something that might be trivial, but I cannot make it work. I need to create a rectangle and change its Fill color. Here is the code from powerpoint application creation up to the change of color I want to perform.

        ActiveXComponent objPPT = new ActiveXComponent("PowerPoint.Application");
        objPPT.setProperty("Visible",new Variant(true));
        Variant presentations = objPPT.getProperty("Presentations");
        Variant presentation = Dispatch.call(presentations.getDispatch(), "Add");
        Variant slides = Dispatch.get(presentation.getDispatch(), "Slides");
        Variant slide = Dispatch.call(slides.getDispatch(), "Add",1, 12);
        Variant shapes = Dispatch.get(slide.getDispatch(), "Shapes");
        Variant rectangle= Dispatch.call(shapes.getDispatch(), "AddShape", 1, 15, 1, 20, 8);
        Variant rectangleFill = Dispatch.get(effectivity.getDispatch(), "Fill");
        Variant rectangleFillForeColor = Dispatch.get(rectangleFill.getDispatch(), "ForeColor");
        // there I would need to create Variant rgb = RGB(10, 10, 10)
        Dispatch.Put(rectangleFillForeColor.getDispatch(), "RGB", rgb);

As you can see, I miss the creation of rgb Variant (Long type underneath)

That Long value is returned by a call to RGB function (which itself take red, green and blue value as input.)

https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/rgb-function

and my problem is the following : I know how to call methods on components using Jacob (Dispatch.call) but I never called an actual function.

Do anyone knows how to do that ? Just to be clear, I know I could somehow bypass the call to RGB by computing the Long value by myself (the value is red+256*(green+256*blue)), but I am really curious about how to make a RGB call work using Jacob, just in case this happens again on a less trivial function someday :)

Zzirconium
  • 431
  • 1
  • 10
  • 32

2 Answers2

1

RGB() is a VBA function. VBA is not part of the COM standard. As a consequence, Jacob has no way to call it.

Olivier
  • 13,283
  • 1
  • 8
  • 24
1

It won't be pretty.

Since the function is part of VBA, you can't call it, just as you stated. It can be wrapped however.

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Variant;

import static com.jacob.com.Dispatch.call;
import static com.jacob.com.Dispatch.get;

public class App {
    static String rgbFunction =
            """
                Function RGB(Red As Integer, Green As Integer, Blue As Integer) As Long
                    RGB = VBA.RGB(Red, Green, Blue)
                End Function                               
            """;

    public static void main(String[] args) {
        ActiveXComponent objPPT = new ActiveXComponent("PowerPoint.Application");
        objPPT.setProperty("Visible",new Variant(true));
        Variant presentations = objPPT.getProperty("Presentations");
        Variant presentation = call(presentations.getDispatch(), "Add");
        Variant vbProject = call(presentation.getDispatch(),"VBProject");
        Variant vbComponents = get(vbProject.getDispatch(),"VBComponents" );
        Variant vbComponent = call(vbComponents.getDispatch(),"Add", 1);
        Variant codeModule =  get(vbComponent.getDispatch(), "CodeModule");
        String moduleName = get(vbComponent.getDispatch(),"Name").getString();
        call(codeModule.getDispatch(), "AddFromString",rgbFunction);
        System.out.println(
                call(
                        objPPT,
                        "Run",
                        moduleName + ".RGB",
                        10, 20, 30
                )
        );
        call(vbComponents.getDispatch(), "Remove", vbComponent);
    }

}

This adds a module to your project with a wrapper, calls it, and removes it at the end. This requires that you have allowed access to the VBA project model in Security Center.

Sam
  • 5,424
  • 1
  • 18
  • 33