Delphi — OleContainer — PowerPoint — автозапуск

Добрый день :-), в своем приложении я использую OleContainer для просмотра презентации из Microsoft Powerpoint.

Этот код я использую для загрузки и запуска файла презентации:

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;

Презентация была создана как слайд-шоу с автоматическим воспроизведением (в Microsoft PowerPoint работает), но в моем приложении презентация была по-прежнему на первом слайде. Команда запуска неверна?


person Nanik    schedule 15.04.2011    source источник


Ответы (2)


Вам не нужен OleContainer для запуска презентации внутри контейнера в вашем приложении. Поместите панель контейнер, чтобы запустить презентацию в вашей форме, и попробуйте следующую процедуру:

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;

У меня нет документации под рукой, но я думаю, что Run.Width и Run.Height должны быть указаны в точках, а не в пикселях. Мое бедное решение для преобразования пикселей в точки здесь, и оно работает для меня в моих тестах здесь ... найти правильный способ преобразования в вашей среде зависит от вас.

Предполагается, что вы можете получить дескриптор окна презентации из свойства oPPTPres.SlideShowSettings.Run.HWND, но для меня это не работает, отсюда и вызов FindWindow.

person jachguate    schedule 16.04.2011
comment
Если бы действительно было свойство HWND, это не должно рассматриваться как взлом :) Но его нет (Объект SlideShowWindow). - person Sertac Akyuz; 16.04.2011
comment
@jachguate: Как я могу остановить презентации до их окончания и вернуть свойство HWND обратно по умолчанию? - person Nanik; 16.04.2011
comment
@ Наник, я не понимаю твоего вопроса ... Я никогда не меняю свойство HWND, поэтому по умолчанию нет возврата. - person jachguate; 17.04.2011
comment
@jachguate: Могу ли я остановить презентацию до ее окончания и убрать из Panel? - person Nanik; 17.04.2011
comment
@Nanik: Мне приходит в голову простая вещь: если вы заранее знаете, сколько времени займет презентация, используйте таймер, чтобы остановить ее. - person jachguate; 17.04.2011
comment
Есть ли вариант html/javascript? Я не знаю делфи :( - person Ravi Gupta; 28.07.2011
comment
Не работает на delphi tokyo, Windows.SetParent принадлежит какому устройству??? - person Linces Marques; 27.05.2018
comment
Для тех, кому нужно запустить в Delphi Berlin/Tokyo, измените строку: Windows.SetParent(screenClasshWnd, Panel1.Handle); в WinApi.Windows.SetParent(screenClasshWnd, Panel1.Handle); - person Linces Marques; 27.05.2018

Run — это метод TOleContainer, а не метод, специфичный для какого-либо объекта OLE, например, для презентации Power Point или растрового изображения. Документация гласит "Вызовите Run, чтобы убедиться, что серверное приложение запущено...".

Для работы с ними необходимо вызывать методы, специфичные для объекта, см. Справочник по объектной модели PowerPoint. Образец кода:

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;


Хотя в приведенном выше примере презентация будет показана в виде слайд-шоу, это, вероятно, не то, что вам нужно, потому что оно работает в полноэкранном режиме. Я понятия не имею, как запустить его в окне контейнера.

person Sertac Akyuz    schedule 15.04.2011
comment
Спасибо за ваше решение :-). Почему я не могу получить доступ с помощью: OleContainer1.OleObject.Application.Presentations.Item(1).Run? - person Nanik; 16.04.2011
comment
Есть ли возможность проверить конец спектакля? - person Nanik; 16.04.2011
comment
@Nanik - Поскольку «Презентация» не имеет метода «Выполнить», объект «SlideShowSettings» презентации имеет. Должно быть: OleContainer1.OleObject.Application.Presentations.Item(1).SlideShowSettings.Run; Проверьте ссылку, которую я предоставил (или код, если на то пошло). - person Sertac Akyuz; 16.04.2011
comment
@Nanik - объект «Приложение» имеет событие «SlideShowEnd». - person Sertac Akyuz; 16.04.2011
comment
@Sertac Akyuz: Спасибо за разъяснение :-). - person Nanik; 16.04.2011
comment
@Sertac Akyuz: Знаете ли вы ответ на мой последний вопрос в решении jachguate? - person Nanik; 17.04.2011
comment
@Nanik - Возможно, в конечном итоге вы захотите щелкнуть ссылку, которую я разместил, и начать использовать документацию по объектной модели. В любом случае вызовите метод «Выход» объекта «SlideShowView». Для примера кода, который я опубликовал, это будет S.Run.View.Exit. Что касается кода jachguate, я думаю, вы могли бы понять это сами. Если ничего не помогает, это может сделать симуляция клавиши «Esc». - person Sertac Akyuz; 17.04.2011