Search code examples
delphihyperlinkpowerpoint

Adding Links in PowerPoint Slides from a Delphi Application


I've got some code in a Delphi (version 10.3) program that opens and makes some updates to an existing PowerPoint presentation. I got everything working except that I would like to create a table of contents with links to other slides, and I haven't been able to find out how to add links. It's using the PowerPoint2010 and Office 2010 units.

Here's a simplified version of my code:

{ Add header slide }
FinalDeck.Slides.Add(1, 2);
SlideOb := FinalDeck.Slides.Item(1);
for Index := 1 to SlideOb.Shapes.Count do
begin
  ShapeOb := SlideOb.Shapes.Item(Index);
  if (ShapeOb.HasTextFrame = msoTrue) then
  begin
    if (Index = 1) then
      Shapeob.TextFrame.TextRange.Text := 'Table of Contents';
    if (Index = 2) then
    begin
      TempSt := 'Section 1' + #13#10 + 'Section 2' + #13#10; + 'Section 3'
      ShapeOb.TextFrame.TextRange.Text := TempSt;
    end;
  end;
end;  { of: for Index }

So, the idea would be to add links where it says "Section 1", "Section 2", etc., to the appropriate slides, if possible. I'm also open to a different approach, if there's a better/easier way.

If anyone can point me in the right direction, that would be appreciated.


Solution

  • The key to success is to append text ranges to TextFrame one by one and configure their hyperlinks. To configure hyperlink to a slide within the presentation you set its:

    1. Address property to an empty string (this is empty by default)
    2. SubAddress property to a value in format {SlideID},{SlideIndex},{SlideTitle}. See here for further information.

    Use TextRange.ActionSettings.Item(ppMouseClick).Hyperlink to access hyperlink of a text range.

    Check out this sample code that creates new presentation with opening slide followed by ToC slide and 3 section slides.

    procedure CreatePresentation(const FileName: string);
    var
      App: PowerPointApplication;
      Presentation: PowerPointPresentation;
      SlideTOC, SlideSection: PowerPointSlide;
      FrameTOC: TextFrame;
      RangeHyperlink: TextRange;
      SectionIndex: Integer;
      SectionTitle: string;
    begin
      App := CoPowerPointApplication.Create;
      try
        Presentation := App.Presentations.Add(msoFalse);
        { Insert opening slide }
        Presentation.Slides.Add(1, ppLayoutTitle).Shapes.Item(1).TextFrame.TextRange.Text := 'The Presentation';
        { Insert table of contents }
        SlideTOC := Presentation.Slides.Add(2, ppLayoutObject);
        SlideTOC.Shapes.Item(1).TextFrame.TextRange.Text := 'Table of Contents';
        FrameTOC := SlideTOC.Shapes.Item(2).TextFrame;
        { Insert section slides }
        for SectionIndex := 1 to 3 do
        begin
          SectionTitle := 'Section ' + IntToStr(SectionIndex);
          SlideSection := Presentation.Slides.Add(Presentation.Slides.Count + 1, ppLayoutObject);
          SlideSection.Shapes.Item(1).TextFrame.TextRange.Text := SectionTitle;
          RangeHyperlink := FrameTOC.TextRange.InsertAfter(SectionTitle + sLineBreak);
          RangeHyperlink.ActionSettings.Item(ppMouseClick).Hyperlink.SubAddress :=
            IntToStr(SlideSection.SlideID) + ',' + IntToStr(SlideSection.SlideIndex) + ',' + SectionTitle;
        end;
        Presentation.SaveAs(FileName, ppSaveAsPresentation, msoFalse);
        Presentation.Close;
      finally
        App.Quit;
      end;
    end;
    

    To apply that to your use case you need to know SlideID or index of the target slide. Notice the use of FrameTOC.TextRange.InsertAfter in the loop to append the hyperlinks to the text frame of table of contents.