Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Ада и другие языки _ Интеграция с MOffice PowerPoint

Автор: 18192123 8.03.2009 4:06

Здравствуйте!
Скажи пожалуйста, можно ли из разрабатываемого приложения по нажатию кнопки вставить в существующую презентацию (созданную в MOffice PowerPoint) новый слайд, и кроме того - на слайд вставить картинку из Paint..??

Автор: volvo 8.03.2009 14:45

Можно... Связка Builder 2009 + PowerPoint из Office XP:

void __fastcall TForm1::Button8Click(TObject *Sender)
{
Variant vPowerPoint;
try {
// Создаем экземпляр PowerPoint-а
vPowerPoint = CreateOleObject("PowerPoint.Application");
}
catch(...) {
// Если была ошибка при создании - сообщаем об этом
ShowMessage("Error...");
}

// Делаем PowerPoint видимым
vPowerPoint.OlePropertySet("Visible", true);
// Открываем нужную презентацию
vPowerPoint.
OlePropertyGet("Presentations").
OleFunction("Open", "F:\\P.ppt", false);

// Получаем количество слайдов в ней на данный момент,
// чтоб добавить новый куда нужно
int nSlides = vPowerPoint.
OlePropertyGet("ActivePresentation").
OlePropertyGet("Slides").
OlePropertyGet("Count");
// Добавляем новый слайд после всех присутствующих
vPowerPoint.
OlePropertyGet("ActivePresentation").
OlePropertyGet("Slides").
OleProcedure("Add",nSlides + 1, 2); // ppLayoutText
// Переходим ко вновь добавленному слайду
vPowerPoint.OlePropertyGet("ActiveWindow").
OlePropertyGet("View").
OleFunction("GoToSlide", nSlides + 1);
// Вставляем изображение из буфера обмена на слайд
vPowerPoint.
OlePropertyGet("ActiveWindow").
OlePropertyGet("View").
OleProcedure("Paste");
// Сохраняем презентацию
vPowerPoint.
OlePropertyGet("ActivePresentation").
OleFunction("Save");
// Выходим и освобождаем память
vPowerPoint.OleProcedure("Quit");
vPowerPoint = Unassigned;
}
Итого: все, что тебе нужно - это чтобы к моменту нажатия на кнопку в буфере обмена Windows находилась нужная картинка (чтобы запихать из Paint-а картинку в Clipboard достаточно найти окно Paint-а и послать ему нажатия Ctrl+A и Ctrl+C)... На приведенной конфигурации это отработало, на других версиях PP или Билдера могут быть несоответствия в количестве параметров у той или иной процедуры/функции, поэтому может потребоваться незначительная переделка.

Автор: 18192123 8.03.2009 22:42

Цитата(volvo @ 8.03.2009 10:45) *

void __fastcall TForm1::Button8Click(TObject *Sender)
{
Variant vPowerPoint;
try {
// Создаем экземпляр PowerPoint-а
vPowerPoint = CreateOleObject("PowerPoint.Application");
}

}



Что-то не то с функцией CreateOleObject..
На строке с этой функцией вот такая вот ошибка:
[C++ Error] Unit1.cpp(23): E2268 Call to undefined function 'CreateOleObject'..
(тестировалось на C++ Builder 6..)

Автор: volvo 8.03.2009 22:45

#include <ComObj.hpp>
в проекте присутствует?

Автор: 18192123 8.03.2009 22:47

Цитата(volvo @ 8.03.2009 18:45) *

#include <ComObj.hpp>
в проекте присутствует?

Аа smile.gif Понятно, как раз этого и не хватало, спасибо!!

Автор: 18192123 9.03.2009 0:10

Проблема со вставкой рисунка на слайд..
Рисунок, как и нужно, находиться в буфере перед нажатием на кнопку...но приложение вылетает на строке:


// Вставляем изображение из буфера обмена на слайд
vPowerPoint.
OlePropertyGet("ActiveWindow").
OlePropertyGet("View").
OleProcedure("Paste");


Скажите пожалуйста, в чём может быть дело?


Эскизы прикрепленных изображений
Прикрепленное изображение

Автор: volvo 9.03.2009 0:19

Цитата
Рисунок, как и нужно, находиться в буфере перед нажатием на кнопку...
Уверена, что он там находится в правильном формате? Если откроешь еще один Paint и нажмешь Ctrl+V перед нажатием на кнопку, рисунок вставится?

Если вставляется, значит проблема в том, что у твоего PowerPoint-а другие методы. Сделай стандартным способом: открой свою презентацию в PowerPoint-е, выбери в меню Tools->Macro->Record New Macro..., и сделай все необходимые тебе действия по добавлению слайда и по добавлению в него картинки вручную. Когда получишь нужный результат, прекрати запись макроса, зайди в Tools->Macro->Macros... <имя записанного макроса> -> Edit, и покажи текст макроса, сгенерированного PowerPoint-ом. Будем смотреть ,что можно сделать...

Автор: 18192123 9.03.2009 0:31

Вот, что получилось:


Sub МакросPP_Builder()
'
' Макрос записан 08.03.2009. Автор: Milagro
'

ActivePresentation.Slides.Add(Index:=17, Layout:=ppLayoutText).Select
ActiveWindow.Selection.SlideRange.Shapes("Rectangle 3").Select
ActiveWindow.Selection.ShapeRange.TextFrame.TextRange.Select
ActiveWindow.Selection.ShapeRange.TextFrame.TextRange.Characters(Start:=1, Length:=0).Select
ActiveWindow.View.Paste
End Sub



Автор: volvo 9.03.2009 1:43

В таком случае вставка из моего кода должна работать, у меня был такой макрос:

Код
    ActiveWindow.View.GotoSlide Index:=ActivePresentation.Slides.Add(Index:=2, Layout:=ppLayoutText).SlideIndex
    ActiveWindow.Selection.SlideRange.Shapes("Rectangle 3").Select
    ActiveWindow.Selection.ShapeRange.TextFrame.TextRange.Select
    ActiveWindow.Selection.Unselect
    ActiveWindow.View.Paste

, и именно он запрограммирован выше... Не знаю, в чем проблема. Что насчет правильности содержимого Clipboard-а? Какая у тебя версия PP?

Автор: 18192123 9.03.2009 2:03

Цитата(volvo @ 8.03.2009 21:43) *

Что насчет правильности содержимого Clipboard-а? Какая у тебя версия PP?

Если вставлять из одного Paint в другой - всё в порядке..
Версия - MOffice PP 2003

Автор: 18192123 10.03.2009 13:48

Уж не знаю, что изменилось, но всё сработало - спасибо большое!!

Хотелось бы узнать, как можно сохранить рисуночек из Paint не только в презентации, но и как непосредственно рисунок в определённой папке..Подскажите пожалуйста!

Автор: volvo 10.03.2009 15:32

У тебя же есть этот рисунок в ClipBoard-е, так забери его оттуда и сохрани:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
TPicture *p = new TPicture;
TJPEGImage *jpg = new TJPEGImage;

if(IsClipboardFormatAvailable(CF_BITMAP)) {
OpenClipboard(Form1->Handle);
p->LoadFromClipboardFormat(CF_BITMAP, (unsigned int)GetClipboardData(CF_BITMAP), 0);
CloseClipboard();
jpg->Assign(p->Bitmap);
jpg->SaveToFile(where_to_save);
}

delete jpg;
delete p;
}

Автор: 18192123 11.03.2009 0:43

Хм..странные вещи со вставкой рисунка на новый слайд..То работало - теперь снова проблемы..Этому можно найти какое-нибудь объяснение..?

Автор: volvo 11.03.2009 1:32

Что, на одной той же машине? Или на разных?

Что произошло перед тем, как оно заработало? Перезагрузка? Или перезагрузки не было, а оно сначала никак не работало, а потом начало работать? Возможно, у тебя что-то с COM-сервером, и он после перезагрузки какое-то время работает, а потом что-то ломается и он работать перестает?

Автор: 18192123 11.03.2009 5:42

Цитата(volvo @ 10.03.2009 21:32) *

Что, на одной той же машине? Или на разных?

Что произошло перед тем, как оно заработало? Перезагрузка? Или перезагрузки не было, а оно сначала никак не работало, а потом начало работать? Возможно, у тебя что-то с COM-сервером, и он после перезагрузки какое-то время работает, а потом что-то ломается и он работать перестает?


Уж не знаю, как связано..Но стабильно начало работать, когда в презентации я добавила слайд. вставила туда вручную картинку из буфера..Далее запустила программу - всё прекрасно..

А у меня ещё такой вопрос:
по сохранению рисунка из буфера..Скажите пожалуйста, как добиться, чтобы сохранение каждый раз было по новому адресу?
например:
1.jpg
2.jpg
..

Автор: volvo 11.03.2009 5:53

Ну, к примеру, объяви переменную - пусть будет Counter - в которую при запуске программы записывай количество JPG-файлов в нужной тебе папке (как ищутся файлы с определенным расширением, знаешь?). А потом - увеличивай Counter и сохраняй файл:

Counter += 1;
jpg->SaveToFile(IntToStr(Counter) + ".jpg");

Автор: 18192123 11.03.2009 7:01

Цитата(volvo @ 11.03.2009 1:53) *

как ищутся файлы с определенным расширением, знаешь?

Нет, не знаю..

Автор: volvo 11.03.2009 15:20

int CountJPG(AnsiString dir)
{
TSearchRec sr;
AnsiString ext;
int res = 0;

for(int r = FindFirst(dir + "*.*", faAnyFile, sr); !r; r = FindNext(sr)) {
if (sr.Attr & faDirectory) continue; // Поддиректории пропускаем
ext = UpperCase(ExtractFileExt(sr.Name));
if(ext == ".JPG") res += 1;
// Application->ProcessMessages();
}
FindClose(sr);
return res;
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Counter = CountJPG(ExtractFilePath(ParamStr(0))); // Директорию нужную в CountJPG передашь...
}