|
| ||||||||||||
| ||||||||||||
|
2000 г
Delphi, С++Builder и COM: вопросы и ответыНаталия Елманова После публикации осенью 1998 г. цикла статей, посвященных C++Builder и COM-технологии, в адрес редакции поступило много вопросов, связанных с проблемами использования COM в приложениях Delphi и C++Builder. Данная статья посвящена ответам на некоторые наиболее часто встречающиеся из них. Уважаемая Наталия! Я только начал изучать Delphi и не могу решить простые
задачи, например, такие как инсталляция новых компонент *.ocx ("Компьютер Пресс
CD, 1999, N 3). Установка ActiveX (OCX) в палитру компонентов осуществляется
просто: из меню среды разработки нужно выбрать опцию "Component/Import ActiveX
Control". Если в полученном списке нужного элемента не окажется, нужно перед
этим его зарегистрировать из командной строки: Regsvr32 <имя *.ocx-файла><имя
*.ocx-файла> Уважаемый автор, Если имеются в виду объекты, вставляемые с помощью пункта меню Word "Вставка/Объект",
то обычно таким образом вставляются OLE-объекты, поддерживаемые так называемыми
серверами документов. Элементы ActiveX могут и не являться такими серверами.
Тем не менее, их можно вставить непосредственно в документ Word 97, используя
опцию "Элементы управления" панели инструментов Visual Basic. На диалоговой
панели "Элементы управления" следует нажать кнопку "Дополнительные элементы"
и выбрать нужный элемент ActiveX. Он должен присутствовать в списке, если он
зарегистрирован. Если же нет, его можно зарегистрировать, выбрав опцию "Зарегистрировать
элемент управления". После создания и переноса CAB-файла и Web-страницы на Web-сервер эта страница в браузере открывается, но на месте предполагаемой активной формы появляется только квадратик. Разъясните, в чем может быть проблема Причин такого поведения может быть несколько. Первая причина связана с тем,
что далеко не все браузеры поддерживают отображение ActiveX с помощью тега<OBJECT>. Для отображения ActiveX следует использовать MS Internet Explorer версии 3.0
и выше (отметим, что в комплект поставки некоторых 32-разрядных версий Windows
входит более ранняя версия этого браузера) либо Netscape Communicator, оснащенный
соответствующим модулем расширения (plug-in). Дело в том, что Netscape Communicator
позиционирует себя на рынке как многоплатформенный браузер, поэтому сам по себе
он не отображает элементов управления ActiveX, так как ActiveX есть технология,
специфичная для Windows. С удовольствием прочитал вашу статью: "Создание контроллеров автоматизации....", но по ходу дела у меня возник ряд вопросов: Как заставить управляемое приложение остаться активным после завершения контроллера. Пример: некая программа генерирует отчет, управляя редактором Word. Требуется, чтобы после того как отчет создан, окно Word не закрывалось. Я добился этого методом вызова функции AddRef применительно к управляемому объекту, но подозреваю, что этот способ не корректен. В принципе можно использовать вызов функции AddRef. Но наиболее принятый способ (если используются вариантные переменные, как в примерах из статьи "Создание контроллеров автоматизации...") - поместить вариантную переменную в глобальную область видимости приложения-контроллера. В этом случае данные, содержащиеся в этой переменной, могут существовать, пока запущено приложение-контроллер, а вместе с ними остается активным и сам COM-сервер (если, конечно, из приложения-контроллера не был вызван метод, приводящий к его закрытию, и если этой вариантной переменной не было присвоено другое значение). Я не понял, как формируется имя сервера, занесенное в реестр (Project1.MyAuto3)? MyAuto3 - мы задаем явно, а откуда берется Project1??? Project1 в данном случае есть имя исполняемого файла COM-сервера. MyAuto3 - это имя COM-объекта, реализованного в данном сервере (COM-объектов в одном сервере может быть и несколько). Мой вопрос связан с автоматизацией Excel из приложений Delphi. Например,
вполне нормально выполняется код, написанный в Delphi: var
v:variant;
begin
v := CreateOleObject('Excel.Application.8');
v.Visible:= True;
v.WorkBooks.Add;
v.Range('A2') := 12;
v.ActiveCell.FormulaR1C1 := '=RAND()';
v.ActiveCell.Font.Bold := True;
end;
Почему при этом не выполняется команда: v.Range('A2').Select; При этом появляется сообщение об ошибке: Member not found. Точно так же не выполняются и многие другие команды, которые можно найти в макросах Excel. Я экспериментировал с Visual FoxPro 5.0, и все команды (макросы) из Excel можно переносить в него практически без изменений, подставляя впереди имя переменной, например v.Range('A2').Select На самом деле в Delphi подобная команда выглядит так:
Иными словами, если Вы пользуетесь справкой по Visual Basic for Applications, нужно менять в содержащихся в ней примерах не только кавычки, но и скобки. Дело в том, что получающийся код должен удовлетворять требованиям синтаксиса языка программирования того средства разработки, на котором пишется контроллер Excel. Хотя синтаксис Pascal и позволяет создавать видимость того, что мы вызываем методы вариантной переменной (не все языки программирования позволяют это делать, например, в C++ так с вариантными переменными обращаться нельзя), из этого не следует, что в него можно включать синтаксические конструкции из Visual Basic без изменений. Что касается FoxPro - синтаксис используемого в этом средстве разработки языка с этой точки зрения (я имею в виду именно употребление скобок и кавычек в описании методов переменных, содержащих ссылки на COM-объекты), видимо, более близок к Visual Basic, чем синтаксис Pascal. Чем с точки зрения синтаксиса может при автоматизации Excel помочь импорт библиотеки типов? Если рассматривать только проблемы синтаксиса, импорт библиотеки типов полезен,
скорее, в случае С++, а не Pascal. 1) Form1.Show - этот оператор использует настоящий метод класса TForm (аналог на C++ - Form1->Show()); 2) Var V:variant;
V:=CreateOleObject('Excel.Application');
.....
V.Visible:=True; -
Здесь используется "метод" для установки "свойства" варианта, но в действительности это инициирование вызова удаленных процедур в Excel (и его внутренних методов). В данном случае внутренний метод Excel, предназначенный для показа его окна, может называться как угодно, и "Show" есть лишь внешнее опубликованное имя этого внутреннего метода. Аналог на C++ : Variant V;
V=CreateOleObject("Excel.Application");
V.OlePropertySet("Visible",true);
//!
Итак, мы видим, что на самом деле "Visible" с точки зрения C++
- это просто строка. Иными словами, и Visual Basic, и Delphi, и Visual FoxPro
просто совершают некоторые манипуляции со строками, позволяя помещать их в исходный
текст без явного указания, что это строки, и тем самым заставляя думать, что
мы вызываем методы вариантной переменной. C++ таких вещей делать не позволяет.
Зато его код иллюстрирует, что происходит на самом деле при автоматизации Excel
в Visual Basic или Delphi. Фактически "Visible" - просто строка, передаваемая
в Excel из приложения-контроллера. Импорт же библиотеки типов позволяет создать
объекты в адресном пространстве контроллера автоматизации, имеющие те же методы,
что и объекты в адресном пространстве Excel. Соответственно можно вызывать настоящие
методы этого "своего" объекта, а их реализация на самом деле будет заключаться
в вызове удаленных процедур, обращенных к Excel (даже если это локальный Excel),
которые инициируют манипуляции уже с внутренними объектами Excel. Соответственно
после этого синтаксис на любом языке будет похож (с точностью до скобок, кавычек
и указателей) на синтаксис Visual Basic. V.Visible=true становится верным. Есть ли возможность с помощью Delphi или C++Builder создать контроллер автоматизации одновременно для Excel 7 и Excel 97? Если нужно создать приложение-контроллер, совместимое и с текущей, и с прежней
версиями Excel, лучше или не импортировать библиотеку типов, или импортировать,
но использовать позднее связывание по изложенным выше причинам (в документации
к Delphi подробно описано, как это сделать), и не использовать вызовы методов,
отсутствующих в старой версии Excel.
|
|
CITForum © 1997–2025