3

Good afternoon :-), in my application I use OleContainer to view presentation from Microsoft Powerpoint.

This code I use to load and run presentation file:

with oleContainer do begin
    Parent := mediaPanel; Left := 0; Top := 0;
    Width := mediaPanel.Width; Height := mediaPanel.Height;
    CreateObjectFromFile('C:\Users\Nanik\Desktop\Present.ppt', false);
    Iconic := false; Visible := true; Run;
 end;

The presentation was created as autoplay slideshow (in Microsoft PowerPoint working), but in my application presentation was still on first slide. Run command isn't right?

Nanik
  • 603
  • 1
  • 12
  • 19

2 Answers2

5

You do not need a OleContainer to run the presentation inside a container in your application. Put a panel container to run the presentation in your form and try this routine:

procedure TForm2.Button3Click(Sender: TObject);
const
  ppShowTypeSpeaker = 1;
  ppShowTypeInWindow = 1000;
  SHOW_FILE = 'C:\Users\jcastillo\Documents\test.pps';
var
  oPPTApp: OleVariant;
  oPPTPres: OleVariant;

  screenClasshWnd: HWND;
  pWidth, pHeight: Integer;

  function PixelsToPoints(Val: Integer; Vert: Boolean): Integer;
  begin
    if Vert then
      Result := Trunc(Val * 0.75)
    else
      Result := Trunc(Val * 0.75);
  end;

begin
  oPPTApp := CreateOleObject('PowerPoint.Application');
  oPPTPres := oPPTApp.Presentations.Open(SHOW_FILE, True, True, False);
  pWidth := PixelsToPoints(Panel1.Width, False);
  pHeight := PixelsToPoints(Panel1.Height, True);
  oPPTPres.SlideShowSettings.ShowType := ppShowTypeSpeaker;
  oPPTPres.SlideShowSettings.Run.Width := pWidth;
  oPPTPres.SlideShowSettings.Run.Height := pHeight;
  screenClasshWnd := FindWindow('screenClass', nil);
  Windows.SetParent(screenClasshWnd, Panel1.Handle);
end;

I do not have documentation at hand, but my thought is Run.Width and Run.Height must be provided in points, not in pixels. My poor man solution to convert pixels to points is here, and it works for me in my tests here... to find the correct way to convert in your environment is up to you.

Is supposed you can get the Handle of the presentation window from the oPPTPres.SlideShowSettings.Run.HWND property, but that does not work here for me, hence the FindWindow call.

jachguate
  • 16,976
  • 3
  • 57
  • 98
  • If there had indeed been a HWND property, this shouldn't be considered as a hack :) But there's none ([SlideShowWindow Object](http://msdn.microsoft.com/en-us/library/aa221458%28v=office.11%29.aspx)). – Sertac Akyuz Apr 16 '11 at 12:29
  • @jachguate: How can I **stop presentations** before end and **return HWND** property back to default? – Nanik Apr 16 '11 at 19:05
  • @Nanik, I don't understand your question... I never change the HWND property, so there's no default to go back. – jachguate Apr 17 '11 at 09:02
  • @jachguate: Can I stop presentation before its end and free from view in Panel? – Nanik Apr 17 '11 at 09:08
  • @Nanik: Simple thing that comes to my mind is if you know in advance how much time the presentation will take, to use a timer to stop it. – jachguate Apr 17 '11 at 19:17
  • Is there a html/javascript variant of this? I don't know delphi :( – Ravi Gupta Jul 28 '11 at 14:56
  • Not working on delphi tokyo, Windows.SetParent Belongs to which unit??? – Linces Marques May 26 '18 at 23:13
  • For those who need to run in Delphi Berlin / Tokyo, change the line: Windows.SetParent(screenClasshWnd, Panel1.Handle); to WinApi.Windows.SetParent(screenClasshWnd, Panel1.Handle); – Linces Marques May 27 '18 at 17:48
4

Run is a method of TOleContainer, it is not a method specific to any kind of OLE object, say, a power point presentation or a bitmap image.. Documentation states "Call Run to ensure that the server application is running..".

You need to call object specific methods to operate on them, see PowerPoint Object Model Reference. Sample code:

procedure TForm1.Button1Click(Sender: TObject);
const
  ppAdvanceOnTime = $00000002;
var
  P: OleVariant;
  S: OleVariant;
  i: Integer;
begin
  P :=  OleContainer1.OleObject.Application.Presentations.Item(1);

  // below block would not be necessary for a slide show (i.e. a *.pps)
  for i := 1 to P.Slides.Count do begin
    P.Slides.Item(i).SlideShowTransition.AdvanceOnTime := True;
    P.Slides.Item(i).SlideShowTransition.AdvanceTime := 1;
  end;
  S := P.SlideShowSettings;
  S.AdvanceMode := ppAdvanceOnTime;

  S.Run;
end;


Though the above will run the presentation as a slide show, it is probably not what you'd want because it runs in full screen. I have no idea how to run it in the container window..

Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • Thanks for your solution :-). Why can't I access by: OleContainer1.OleObject.Application.Presentations.Item(1).Run? – Nanik Apr 16 '11 at 11:49
  • Is there any possibility to check the end of the play? – Nanik Apr 16 '11 at 11:50
  • 2
    @Nanik - Because a 'Presentation' does not have a 'Run' method, 'SlideShowSettings' object of a presentation does. Should be: `OleContainer1.OleObject.Application.Presentations.Item(1).SlideShowSettings.Run;`     Check the link I've provided (or the code for that matter). – Sertac Akyuz Apr 16 '11 at 12:23
  • 2
    @Nanik - The 'Application' object has a 'SlideShowEnd' event. – Sertac Akyuz Apr 16 '11 at 12:25
  • @Sertac Akyuz: Do you please know answer to my last question in jachguate's solution? – Nanik Apr 17 '11 at 14:00
  • 1
    @Nanik - You might eventually want to click the link I posted and begin using the object model documentation..  Anyway, call the 'Exit' method of the 'SlideShowView' object. For the code sample I posted it would be `S.Run.View.Exit`. For 'jachguate's code, I guess you could figure it out yourself. If all else fails simulating an 'Esc' key might do it.. – Sertac Akyuz Apr 17 '11 at 14:33