Borland delphi 4 0 для начинающих создание элементов управления activex


Содержание

Borland delphi 4 0 для начинающих создание элементов управления activex

procedure TFormI.mnuEditCopyClick(Sender: TObject);

Все, что происходит в мире Windows, базируется на сообщениях. Для выполнения какой-либо функции управляющие элементы часто отсылают сообщения самим себе. Так и в этом примере управление происходит путем передачи сообщения WMCOPY.

Это свойство возвращает объект TForm, имеющий фокус ввода. Если приложение неактивно, свойство указывает, какая именно форма будет иметь фокус ввода при активизации приложения. В качестве примера используем свойство для создания мигающего заголовка формы, чтобы привлечь внимание пользователя. Функция Windows API, предназначенная для этой цели, должна получить дескриптор окна:

Это свойство определяет форму указателя мыши для всего приложения. Обычно оно используется для отображения песочных часов, чтобы в то время, пока пользователь думает о сложной работе, выполняемой приложением, немного передохнуть.

for iCount:=1 to 1000000000 do;

Форму указателя можно изменить для каждого потомка TControl (включая ТForm) отдельно.

Forms и FormCount

Эти свойства возвращают список форм и их количество. Работа с ними ничем не отличается от работы со списком дочерних окон, описанных в разделе „MDIChildren и MDIChildCount“.

Это наиболее полезные свойства, возвращающие высоту и ширину экрана в пикселях. Они могут применяться во многих ситуациях, например при определении местоположения формы. Вот как поместить форму в центре экрана.

Left:= (Screen.Width — Width) div 2;

Top:= (Screen.Height — Height) div 2;

tscreen предоставляет два основных события, извещающие программу об изменении фокуса ввода. Подобно возможностям класса TApplication, возможности класса TScreen доступны лишь при выполнении.

Это событие возникает при передаче фокуса ввода от одного управляющего элемента к другому. Свойство

ActiveControl обновляется непосредственно перед вызовом события. Вы можете использовать событие, например, для вывода текста подсказки в строке состояния.

procedure TFormI.ActiveControlChangeHandler(Sender: TObject);

if (not Application.Terminated) then

Проверка связана с тем, что событие генерируется и при закрытии приложения, а при этом обращение к уже уничтоженному объекту вызовет исключительную ситуацию.

Событие генерируется при создании новой формы или передаче фокуса ввода от одной формы к другой. Обычно это событие используется в MDI-приложениях для обновления доступных функций меню и кнопок-ускорителей. Ниже приведен пример из шаблона MDI-приложения.

procedure TMainForm.UpdateMenuItems(Sender: TObject);

FileCloseItem.Enabled:= MDIChildCount 0;

FileSaveItem.Enabled:= MDIChildCount 0;

FileSaveAsItem.Enabled:= MDIChildCount 0;

Процедура UpdateMenuItems назначена в качестве обработчика событию OnActiveFormChange в обработчике

procedure TMainForm.FormCreate(Sender: TObject);

Разделяемые обработчики событий

Как вы уже знаете, каждый класс способен генерировать свои собственные события. Каждое из них имеет определенный тип, как, например, TNotifyEvent у OnClick и TCloseEvent у OnClose. Delphi позволяет написать один обработчик события и назначить его нескольким событиям одновременно.

Представьте себе объект TEdit, генерирующий события OnKeyDown и OnKeyUp. Поскольку оба события — одного типа, можете написать одну процедуру и назначить ее обоим событиям. Процедура будет вызываться дважды при каждом нажатии клавиши (при нажатии и отпускании). Или, например, вы можете создать один обработчик для событий OnCreate и OnClick.

Еще одно общее назначение разделяемых обработчиков — обработка событий от двух различных управляющих элементов, которые могут и не быть экземплярами одного класса.

Вот как создать разделяемый между классами TButton и TEdit обработчик OnClick.

Выберите из меню File/New Application для создания приложения.

Поместите TButton в форму и введите в обработчик OnClick следующий код. procedure TFormI.ButtonlClick (Sender: TObject);

Поместите TEdit в форму. В Object Inspector выберите в списке для события OnClick обработчик ButtonClick. Теперь после щелчка на кнопке и на объекте TEdit будут выполняться одни и те же действия, фокус ввода будет передаваться управляющему элементу TEdit, и весь текст в нем будет выделяться.

Поскольку множество объектов может разделять один обработчик событий, необходимо уметь выяснять, какой именно обработчик его сгенерировал. Для этого предназначен параметр Sender, передаваемый в каждый обработчик, который указывает на объект, сгенерировавший событие. Часто этот параметр используется для различных действий обработчика в зависимости от того, кто именно породил событие.

Создание одноэкземплярного приложения

Если в Windows несколько раз щелкнуть на пиктограмме приложения, по умолчанию запустится сразу несколько его копий. Чтобы избежать этого, т. е. не дать запуститься второй копии приложения, необходимо выполнить поиск по заголовкам окон.

Поиск по заголовкам окон

При создании экземпляра окна Windows требует зарегистрировать имя класса окна (window class name). Delphi использует класс формы в качестве имени класса окна, например, когда Delphi создает экземпляр Form1 класса TForm1, TForm1 используется в качестве имени для регистрации окна Form1. Каждая форма имеет свойство Caption, известное как заголовок окна (window title). Эти два параметра позволяют искать окно с помощью функции Windows API FindWindow, возвращающей дескриптор найденного окна.

Эту функцию нельзя вызывать из класса TForm1, так как к тому времени окно уже будет создано, и вы окажетесь в глупом положении, найдя сами себя. Вот код, который должен находиться в файле проекта.

if FindWindow(‘TFormi’,’Formi’) о 0 then Application.Terminate;

Поскольку вы используете функцию Windows API, проследите, чтобы был подключен модуль Windows.

Если вы запускаете это приложение из Delphi, учтите, что Form Designer уже создал такое окно, и вы всегда сможете его найти. Это приложение следует запускать отдельно, закрыв Delphi.

Изменив свойство Caption или Name, вы рискуете не найти своего окна и придется повозиться с кодом программы, чтобы отследить эти изменения. Может возникнуть ситуация, когда простое совпадение приведет к тому, что окно будет найдено в совсем другом приложении, которое будет опознано как свое.

Активизирование существующей копии

Все-таки, сказать пользователю „Ты уже запустил одну копию, теперь иди и ищи ее!“ — как-то негуманно… Более профессиональным решением будет активизировать существующую копию с помощью другой функции Windows API — SetForegroundWindow. Измените проект следующим образом.

Borland delphi 4 0 для начинающих создание элементов управления activex

Почему именно Delphi? В Delphi сделать первый шаг очень просто, она интуитивно понятна. Конечно, небольшому числу разработчиков по долгу службы нужны глубокие специфические знания, которые приходят со временем. А начинающим Delphi позволяет начать создавать программы сразу, не углубляясь в изучение внутренностей операционной системы, и даже собственной среды разработки. Поэтому программист может сразу сосредоточиться на логике работы будущей программы.

Delphi — прекрасная система визуального объектно-ориентированного проектирования, одинаково радующая и новичков в программировании, и профессионалов. Начинающим Delphi позволяет сразу, с небольшими затратами времени и сил создавать прикладные программы, которые внешне неотличимы от программ, созданных профессионалами. А для опытного программиста Delphi открывает неограниченные возможности для создания сколь угодно сложных программ любого типа, в том числе, распределённых приложений, работающих с любыми базами данных.

Более подробно о том, что такое Delphi и почему её стоит изучать, можно прочесть на специальной страничке и этом переводе статьи «Why Delphi? (Delphi For Beginners)» :

Эта статья о Delphi имеет цель объяснить, что такое Delphi и что он может сделать для вас.

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

Borland Delphi представляет собой средство разработки приложений для Microsoft Windows. Delphi является мощным и простым в использовании инструментом для создания автономных программ, обладающих графическим интерфейсом (GUI) , или 32-битных консольных приложений (программ, которые не имеют графического интерфейса).

В сочетании с Borland Kylix, программисты Delphi могут создавать из одного исходного текста приложения и для Windows и для Linux, и это открывает новые возможности и увеличивает потенциальную отдачу от усилий, вложенных в изучение Delphi. В Delphi используется кросс-платформенная библиотека компонентов CLX и визуальные дизайнеры для создания высокопроизводительных приложений для Windows, которые повторной компиляцей можно легко превратить в приложения для Linux.

Delphi является первым языком программирования, обладающим простой в использовании средой для быстрой разработки приложений, разрушающей барьеры между языками высокого уровня, и языками, на низком уровне разговаривающими с системой на языке битов и байтов.

При создании графического интерфейса приложений Delphi, у вас все возможности языка программирования Object Pascal, «завернутого» в среду RAD . Такие компоненты окна графического пользовательского интерфейса, как формы, кнопки и списки объектов, включены в состав Delphi. Это означает, что вам не нужно писать никакого кода при добавлении их в ваше приложение. Вы просто «кладёте» их на вашу Форму, как в графическом редакторе. Вы можете также добавить на Форму элементы управления ActiveX, для создания в считанные минуты специализированных программ таких, например, как веб-браузеры. Delphi позволяет разработчикам дизайна внедрять в интерфейс новые элементы и кодировать их события одним щелчком мыши.

Delphi поставляется в различных конфигурациях, настроенных на потребности различных предприятий. В Delphi вы можете писать программы для Windows быстрее и легче, чем это было возможно раньше.

Паскаль

Лучшим способом представить что такое Delphi является Object Pascal на основе визуальной среды разработки. Delphi основан на Object Pascal, языке, аналогичном объектно-ориентированному C++, а в некоторых случаях даже лучше. Для разработчиков не имеющих опыта работы в Паскале, Delphi имеет шаблоны своих структур на Паскале, что ускоряет процесс изучения языка.

Компилятор Delphi упаковывает приложения в компактные исполняемые файлы, причем нет необходимости в громоздких библиотеках DLL — большое удобство, я должен сказать.

Библиотека Visual Component Library (автономные бинарные части программного обеспечения, которые выполняют некоторые конкретные предопределенные функции), или VCL, Delphi является объектно-ориентированной базой. В этой богатой библиотеке вы найдете классы для таких визуальных объектов Windows как окна, кнопки и т.д., а также классы для пользовательских элементов управления таких как таймер и мультимедийный плеер, наряду с невизуальными объектами, такими как список строк, таблицы базы данных, потоки и т.д.

Базы данных

Delphi может получать доступ ко многим типам баз данных. Используя BDE (Borland Database Engine — механизм доступа к базам данных), формы и отчеты, которые вы создаете, получают доступ к локальным базам данных, таким как Paradox и DBase, сетевых баз данных SQL Server, InterBase, также как и SysBase, и любые источники данных, доступные даже через ODBC (открытая связь с базами данных).

Итак, Delphi — прекрасная среда разработки Windows- и Linux-программ любого типа. Поэтому единственное, что вас должно уже сейчас интересовать —

Итак, запустим Delphi. Перед нами четыре окошка. Вверху во вcю ширину экрана окно управления проектом и средой разработки — главное окно Delphi. При его сворачивании сворачиваются и все остальные. Слева — инспектор объектов. В нём задаются свойства составляющих нашу программу компонентов. И наконец, в центре одно над другим два окна, окно формы будущей программы и окно программной начинки.

В пустой форме смысла нет. Наполнить её содержанием помогут компоненты Delphi. Они располагаются на главном окне, на нескольких вкладках. Все основные компоненты находятся на первых четырёх вкладках: Standard, Additional, Win32 и System. Их названия всплывают в виде подсказок при наведении мышки на пиктограммы.

Структура программы для Windows представляет собой набор подпрограмм, каждая из которых ответственна за обработку конкретного события и вызывается только при его получении. Удобство Delphi состоит в том, что мы избавлены от необходимости получать сообщения от Windows сами, Delphi это делает за нас. Каждый компонент имеет впечатляющий набор событий, на которые он может реагировать. Программист сам определяет, какие события в программе требуется обрабатывать.

Данные в компьютере можно рассматривать как ячейки памяти, имеющие свои имена (идентификаторы). Все данные в программе на языке Delphi должны быть описаны до их первого использования. И компилятор следит, чтобы в программе они использовались в соответствии с этим описанием, что позволяет избежать ошибок.

При создании любой серьёзной программы не обойтись без дополнительных, более сложных, чем числа и строки, типов данных. В Delphi программист может для своих целей конструировать собственные типы данных. Чтобы ввести в программу (описать) новый тип данных, применяется оператор с ключевым словом type.

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

Начало. Работа с файлами важная вещь в любом языке программирования. Для начала нужно упомянуть компоненты, которые умеют работать с файлами, считывать и сохранять своё содержимое, строки типа String, в файл текстового формата. Это компоненты ListBox, ComboBox и Memo, расположенные на первой же вкладке палитры компонентов.
Продолжение. В Delphi реализовано несколько способов прямой работы с файлами. Познакомимся с классическим способом, связанным с использованием файловых переменных. Прежде всего файл должен быть открыт.
Окончание. То, что мы узнали в предыдущей части урока, позволяет работать с файлами по адресу, жёстко записанному в тексте программы. Мы же хотим просматривать любые файлы по нашему выбору. В Delphi есть компоненты, позволяющие в работающей программе осуществлять выбор файлов.
Поиск файлов в Delphi производится в три этапа. На первом этапе функция FindFirst находит первый файл, удовлетворяющий критериям отбора. На втором этапе функция FindNext в цикле поочерёдно находит остальные файлы. На третьем этапе функция FindClose освобождает память, выделенную для осуществления поиска.
Задачка. Теперь, пользуясь всем вышеизложенным материалом, можно ответить, например, на вопрос: «как средствами Delphi определить размер файла». Есть несколько альтернативных способов, как подсчитать размер файла с помощью Delphi.
Список подпрограмм используемых при работе с файлами в Delphi. Содержит функции и процедуры создания, поиска, преобразования и удаления папок и файлов.

Редкая программа обходится одной формой. Delphi позволяет с лёгкостью создавать дополнительные формы, предоставляющие возможность, например, вести диалог с пользователем, принимать и выводить любую необходимую информацию.

Всё богатство стандартных процедур и функций Delphi не исчерпывает встающих перед программистом задач. Для выполнения повторяющихся операций с меняющимися данными Delphi программист может создавать собственные подпрограммы — процедуры и функции Delphi.
Пример. Вычисление факториала. Выполняя повторяющиеся участки кода, подпрограммы эффективно заменяют циклы. Классический пример — вычисление факториала числа, демонстрирующий также использование рекурсии. Этот проект также можно скачать.

Исключительные ситуации в Delphi встречаются постоянно. Исключительная ситуация это такая ситуация, в результате которой генерируется ошибка, и выполнение программы прерывается. Например, деление на ноль — классический пример исключительной ситуации. Для контроля исключительных ситуаций ввода-вывода также могут применяться директивы компилятора <$I>.

Применение компонентов Delphi позволяет избежать рутинного ручного кодирования. Компоненты Delphi охватывают практически все аспекты применения современных информационных технологий. Конечно, для работы в Delphi прежде всего требуется изучить базовые компоненты Delphi, которые требуются при подготовке практически любого приложения.
Страница Standart
Изучение Delphi естественным образом начинается со страницы палитры компонентов Standart. На этой странице расположены стандартные для Windows интерфейсные элементы, такие как главное и всплывающее меню, кнопка, однострочный и многострочный редакторы, переключатели, метки, списки, и некоторые другие компоненты, которые применяются наиболее часто. Рассматривается пример на переопределение символов , вводимых в компонент Edit, что может использоваться в формах для ввода пароля.
Страница Additional
На страницу палитры компонентов Additional помещены дополнительные компоненты, без некоторых из которых сегодня трудно представить программу для Windows: кнопки с дополнительными свойствами, таблицы , компоненты для размещения изображений и многие другие.
Страница Win32
Страница палитры компонентов Win32 содержит компоненты, представляющие собой интерфейсные элементы для 32-разрядных операционных систем Windows 95/98/NT (В версии системы Delphi 2 эта страница называлась Win95). Использующие эти компоненты программы выглядят в стилистике последних версий операционных систем Windows.
Страница System
На странице палитры компонентов System представлены компоненты, которые имеют различное функциональное назначение (например, Timer — очень важный в любой программе компонент), в том числе компоненты, поддерживающие стандартные для Windows технологии межпрограммного обмена данными OLE и DDE.

Работа со строками Delphi позволяет извлечь из строки необходимую информацию и представить её в нужном виде. Delphi предоставляет весь спектр необходимых функций для работы со строками и преобразования строк Delphi в необходимые форматы.
Продолжение. Использование списка строк. Список строк Delphi TStringList — это структура данных, напоминающая компонент ListBox, но не визуальная, а просто хранящая в памяти и имеющая свойства и методы для работы со строками типа TString.

Создание интерфейса пользователя сводится к выбору из палитры компонентов необходимых для работы программы компонентов Delphi, служащих интерфейсом управления, а также интерфейсом отображения информации, и перенесению их на Форму с последующей компоновкой.

Работа с графикой в Delphi это не только линии и рисунки, но также и и печать текстовых документов. Поэтому в Delphi работе с графикой нужно уделить немного времени. Работа с графикой в Delphi предполагает знакомство с канвой (Canvas) компонентов. Канва это тот холст, который умеет управлять состоянием каждого своего пиксела, и это свойство позволяет программисту отобразить то, что требуется.

Потоки в Delphi выполняют функцию имитации псевдопараллельной работы приложения. Как известно, для организации многозадачности операционная система выделяет каждому приложению, выполняющемуся в настоящий момент, определённые кванты времени, длина и количество которых определяется его приоритетом. Поэтому объём работы, который приложение может выполнить, определяется тем, сколько таких квантов оно сможет получить в единицу времени.

Динамически создаваемые компоненты — это компоненты, место в памяти под которые выделяется по мере необходимости в процессе работы приложения. Этим они и отличаются от компонентов, которые помещаются на Форму при проектировании приложения. Возможность создавать компоненты динамически это очень большое удобство для программиста.

Новые Уроки Delphi будут появляться с течением времени. Кроме того, будут корректироваться уже готовые уроки с целью избавиться от всегда возможных неточностей и ошибок. Как говорится:

Borland delphi 4 0 для начинающих создание элементов управления activex

Собственно сабж.
На виби все делается компилятором, а как это делать в Д? Просветите плз.

New -> activeX library
New -> ActiveX object
View -> Type library
Далее заполняешь интерфейс методами и пропертями, нажимаешь refresh и реализуешь эти методы в классе
Ну а потом Run -> Register ActiveX Server

Спасибо.
Правильно ли я понял, что:

> New -> activeX library
> New -> ActiveX object
это COM object?

> View -> Type library
> Далее заполняешь интерфейс методами и пропертями, нажимаешь
> refresh и реализуешь эти методы в классе
> Ну а потом Run -> Register ActiveX Server
А это эквивалентно «regsvr32 «, или это делает еще что нибудь?

А не подскажите, как подключить/использовать ее в другом проекте?

Project -> Import type library
Либо Component->Install ActiveX Control, и дальше работать с ней, как с обычной компонентой

Чето у меня не получается. Чето я видимо делаю не так — создал простенькую activeX dll, зарегистрил ее, создал и заинсталил test.bpl.
Но как ее использовать ее в другом проекте никак не пойму. =8(

В васике все работает — там его носом тыкаешь какую библиотеку загрузить и все.

Помогите! Объясните, будьте так любезны.

Предыдущий вопрос снимается, разобрался.
Возник, правда, другой.

Borland delphi 4 0 для начинающих создание элементов управления activex

Статья опубликована на сайте www.citforum.ru

1 Что такое ActiveX

Технология ActiveX, рассматриваемая в данной статье, базируется на технологии Microsoft COM (Component Object Model — модель компонентных объектов), позволяющей создавать и использовать программные компоненты, предоставляющие различные сервисы другим приложениям, компонентам и операционной системе. COM представляет собой одну из реализаций концепции распределенных вычислений, базирующейся в общем случае на предоставлении возможности приложениям использовать для расширения своей функциональности готовые компоненты и объекты (иногда они называются сервисами). Технология COM позволяет использовать объектно-ориентированный подход не в рамках одного приложения, а в рамках операционной системы, но, в отличие от стандартных классов, определенных в исходном тексте и реализуемых как объекты в адресном пространстве одного процесса, эти компоненты могут в общем случае располагаться в адресных пространствах разных процессов и даже на разных компьютерах.

В настоящее время существуют три типа спецификаций COM, определенных Microsoft и включающих большое количество интерфейсов и функций:

  • OLE-документы — составные документы, содержащие внедренные или связанные объекты. Эта спецификация описывает правила создания контейнеров для таких документов с «активацией по месту». Отметим, что компонент OLEContainer Delphi и C++Builder создан с учетом этой спецификации (этой теме будет посвящена одна из следующих статей данного цикла).
  • OLE Automation. Эта спецификация описывает, как создать сервер и контроллер, управляющий его поведением с помощью скриптов или макросов. Эта спецификация также поддерживается Delphi и C++Builder (об этом также пойдет речь в ближайших статьях данного цикла).
  • Управляющие элементы ActiveX, использующие специальный вариант протокола Automation (о них-то и пойдет речь в данной статье).

Использование COM, и, в частности, технологии ActiveX, позволяет обеспечить создание приложений, собираемых из готовых компонентов — элементов управления ActiveX, отличающееся от привычной пользователям C++Builder или Delphi разработки приложений с помощью VCL-компонентов тем, что такая «сборка» не зависит от того, на каком языке написаны как готовые компоненты, так и использующее их приложение — лишь бы средство разработки поддерживало возможность использования таких компонентов в разрабатываемом приложении (такое приложение обычно называется контейнером).

Элементы управления ActiveX представляют собой библиотеки, содержащие исполняемый код. Как было сказано выше, эти библиотеки могут быть использованы в различных приложениях как встроенные элементы управления, поэтому они обладают свойствами, событиями и методами, доступными посредством автоматизации. Современные средства разработки, как правило, позволяют включать такие элементы в создаваемые с их помощью приложения. Помимо этого, элементы управления ActiveX нередко используются в качестве расширений web-броузеров с целью придания им дополнительной функциональности, например, для отображения документов, отличных от поддерживаемых данным броузером.

Как любой COM-сервер, элемент управления ActiveX обладает уникальным идентификатором GUID и должен быть зарегистрирован в реестре. На основании этой записи может быть осуществлен поиск местоположения файла с расширением *.ocx, содержащего его реализацию.

Таким образом, создав элемент управления ActiveX, обладающий интересующей Вас функциональностью, Вы можете в дальнейшем позволить его пользователям встраивать этот элемент в свои приложения (например, написанные на Visual Basic, PowerBuilder, Delphi, C++Builder и др.), отображать его в web-броузере в составе выгруженной с Вашего web-сервера HTML-страницы, включать его в состав документов MS Office, при этом Вы не обязаны предоставлять исходный текст этого компонента.

Когда следует создавать управляющие элементы ActiveX? Естественно, в тех случаях, когда функциональность, содержащаяся в таком элементе, уникальна. Нет смысла создавать ActiveX, реализующий функциональность кнопки или текстового редактора — таких элементов управления, в том числе выполненных в виде ActiveX, на рынке готовых компонентов более чем достаточно. Нет смысла также создавать ActiveX, если он будет использоваться только в C++Builder — в этом случае проще создать VCL-компонент, который будет работать в использующем его приложении значительно быстрее, чем аналогичный ActiveX. Но создание элемента управления, реализующего, к примеру, часть автоматизированного рабочего места какой-либо категории сотрудников Вашего предприятия может в ряде случаев оказаться весьма полезным, особенно в следующих двух случаях. Первый случай — использование на предприятии различных средств разработки, например, C++Builder и Visual Basic; в этом случае разработчик, использующий Visual Basic, может встраивать в свои приложения ActiveX, созданный другим разработчиком и реализующий какую-либо функциональность, используемую несколькими различными автоматизированными рабочими местами. Второй случай — широкое использование Internet или intranet при автоматизации предприятия. В этом случае ActiveX, реализующий подобную функциональность, может быть встроен в HTML-страницу и отображен в web-броузере. Такой подход существенно облегчает решение проблемы обновления версий автоматизированных рабочих мест, так как вместо установки новых версий на рабочих станциях достаточно заменить один экземпляр ActiveX, хранящийся на web-сервере. Наиболее ярким примером такого подхода может быть выполненный в виде ActiveX «тонкий» клиент, получающий данные от удаленного сервера приложений, являющегося, в свою очередь, клиентом серверной СУБД.

Такой набор преимуществ сделал эту технологию за последние два года весьма популярной, и именно поэтому многие современные средства разработки, такие, как Delphi или С++Builder, позволяют создавать элементы управления ActiveX. Эти средства обычно имеют встроенные механизмы поддержки спецификации ActiveX с помощью автоматической генерации соответствующего кода (хотя, конечно, не возбраняется писать подобный код вручную).

Спецификация ActiveX представляет собой набор правил (а именно описание стандартных интерфейсов), с помощью которых следует создавать такие элементы управления. Отметим, что текущая версия этой спецификации учитывает возможность использования в качестве контейнера web-броузеров и необходимость загрузки элементов ActiveX с удаленных web-серверов с их автоматической регистрацией.

2 Создание элементов управления ActiveX на основе VCL-компонентов

Как было сказано выше, C++Builder 3 позволяет создавать элементы управления ActiveX на основе VCL-компонентов. Для этой цели используется библиотека Microsoft ATL (Active Template Library), являющаяся на сегодняшний день индустриальным стандартом и позволяющая создавать элементы ActiveX, представляющие собой скомпилированный код и не требующие дополнительных run-time-библиотек для их выполнения. Процесс создания такого элемента управления весьма прост.

Для создания элемента управления ActiveX следует выбрать из репозитария объектов страницу ActiveX и далее — элемент ActiveX Control.

Далее следует заполнить появившуюся диалоговую панель:

Рис.1. Выбор имени ActiveX, имен модулей и базового VCL-класса

Следует выбрать VCL-компонент, на основе которого будет создан элемент ActiveX. В качестве примера выберем TCalendar.

Отметим, что при выборе опции Include Design-Time Licence автоматически будет сгенерирован файл с расширением *.lic, без которого данный ActiveX нельзя будет использовать ни в каких средствах разработки, но можно поставлять с готовыми приложениями. Использование такого файла бывает удобно в случае, когда ActiveX поставляется бесплатно его автором в составе готового продукта, но требует отдельного лицензирования при встраивании его другими пользователями в свои разработки.

В результате работы ActiveX Control Wizard будут созданы несколько модулей, сгенерирован уникальный идентификатор (GUID) будущего ActiveX, а также соответствующая библиотека типов.

Рис.2. Проект библиотеки ActiveX в С++Builder

Библиотека типов содержит сведения о свойствах, событиях и методах компонента ActiveX, унаследованных от исходного VCL-компонента.

Рис.3. Библиотека типов созданного элемента ActiveX

В коде, связанном с реализацией ActiveX, можно найти описание этих свойств и методов.

Далее следует сохранить и скомпилировать проект и зарегистрировать элемент ActiveX в реестре. Это делается с помощью выбора пункта меню Run/Register ActiveX Server.

После этого можно протестировать созданный ActiveX-компонент, открыв его, например, в Visual Basic. Отметим, что последние версии именно этого средства разработки широко используют элементы управления ActiveX в качестве составных частей создаваемых с их помощью приложений; фактически приложения Visual Basic собраны целиком из ActiveX-компонентов. Более того, спецификация ActiveX создана с учетом того, что в первую очередь Visual Basic и Visual C++ (и лишь затем остальные средства разработки) могут быть контейнерами для этих элементов управления. Поэтому тестирование поведения ActiveX в VisualBasic может более или менее гарантировать, что в других средствах разработки этот управляющий элемент будет вести себя точно так же.

В случае отсутствия Visual Basic можно воспользоваться и более широко распространенным Visual Basic for Applications. С этой целью можно запустить Microsoft Word 97, создать новый документ и выбрать на панели инструментов кнопку «Редактор Visual Basic». Далее следует выбрать в окне «Project» имя вновь созданного документа, щелкнуть по нему правой кнопкой мыши и из полученного контекстного меню выбрать опцию «Вставить/UserForm». На экране появится редактор форм Visual Basic и панель элементов. Далее нужно щелкнуть правой клавишей мыши по панели элементов и выбрать из контекстного меню опцию «Дополнительные элементы». Теперь следует из появившегося списка всех зарегистрированных элементов управления ActiveX выбрать нужный, и он автоматически окажется на панели элементов Visual Basic (можно поместить его на единственную имеющуюся страницу управляющих элементов или создать свою, выбрав опцию «Создать страницу» из контекстного меню ярлычков блокнота, расположенного на панели элементов).

После этого можно поместить наш ActiveX на форму и попытаться изменить какие-либо его свойства, используя для этой цели окно «Свойства».

Рис.4. Тестирование ActiveX в Visual Basic

И, наконец, можно вернуться в редактируемый документ, поместить на него кнопку, дважды щелкнуть по ней и в окне редактора кода создать процедуру, показывающую созданную форму, вписав в сгенерированный код строку UserForm1.Show :

Private Sub CommandButton1_Click()
UserForm1.Show
End Sub

Теперь можно нажать на панели инструментов «Visual Basic» кнопку «Выход из режима конструктора». После этого нажатие на созданную в теле документа кнопку приведет к появлению диалоговой панели с созданным нами элементом управления.

Можно было бы, конечно, протестировать поведение созданного ActiveX, установив его в палитру компонентов Delphi или C++Builder,, но это не самый лучший способ тестирования — ведь в основе создания нашего ActiveX лежит та же самая библиотека VCL, что и в основе создаваемого приложения для тестирования ActiveX. Использование для этой цели любого не имеющего отношения к VCL средства разработки, способного использовать элементы управления ActiveX в создаваемых приложениях, более оправдано. При этом следует заметить, что Visual Basic for Applications представляет собой наиболее часто встречающееся средство разработки такого класса, так как входит в состав самого популярного в нашей стране офисного пакета.

3 Создание страниц свойств

Так как элементы управления ActiveX могут быть использованы в средствах разработки, нередко они обладают набором страниц свойств, позволяющим пользователям менять те или иные свойства этого элемента управления.

Для создания страницы свойств выберем из репозитария объектов страницу ActiveX и элемент Property Page. В результате получим форму, на которой можно размещать интерфейсные элементы.

Создадим страницу для редактирования свойств CalendarDate и GridLineWidth. Для этого разместим на вновь созданной форме два компонента TStaticText и два компонента TEdit.

Рис.5. Страница свойств на этапе проектирования

В созданной форме имеются сгенерированные прототипы обработчиков событий UpdatePropertyPage и UpdateObject. Добавим в них соответствующий код:

Далее следует создать ссылку на странице свойств в модуле, описывающем реализацию элемента ActiveX. С этой целью следует модифицировать h-файл .Модификация кода заключается во вставке строки, указывающей на необходимость регистрации страницы свойств:

Следует также включить ссылку на h-файл страницы свойств в h-файл реализации ActiveX.

Далее следует заново скомпилировать библиотеку ActiveX и зарегистрировать ее.

Если теперь в среде разработки Visual Basic поместить на пользовательскую форму наш ActiveX и выбрать страницу свойств «Специальные», получим созданную нами страницу:

Рис.6. Страница свойств на этапе тестирования ActiveX

При изменении значений в компонентах TEdit можно убедиться, что изменяются и соответствующие свойства элемента ActiveX.

Рис.7. Результат использования страницы свойств

4 Создание активных форм

Активная форма — это элемент управления ActiveX, содержащий несколько VCL-компонентов. Возможность создания таких элементов управления позволяет существенно расширить круг доступных для элементов ActiveX функциональных возможностей. Создание такого ActiveX происходит примерно так же, как и создание обычного приложения.

Попробуем создать простейший пример такого элемента управления. Для его создания следует выбрать со страницы ActiveX репозитария объект ActiveForm, ответить на вопросы об имени компонента, после чего в дизайнере форм получим пустую форму — заготовку будущего ActiveX. Добавим на эту форму компоненты TCheckBox, TButton, TImage и TOpenPictureDialog.

Рис.8. Активная форма на этапе проектирования

Создадим обработчики событий, связанных с TCheckBox и TButton:

Теперь можно скомпилировать приложение, зарегистрировать созданный ActiveX и протестировать его указанным выше способом.

Рис.9. Тестирование активной формы в Visual Basic

Можно также протестировать созданный ActiveX c помощью отображения его в Internet Explorer. Для этой цели можно выбрать пункт меню Project/Web Deployment Options и на странице Project в полях Target dir, Target URL, HTML dir этого диалога указать имя какого-нибудь локального каталога.

Затем можно выбрать опцию Project/Web Deploy и по окончании работы Web Deployment Wizard открыть в Internet Explorer автоматически сгенерированную С++Builder html-страницу c именем, совпадающим с именем созданного проекта:

Рис.10. Тестирование активной формы в Internet Explorer

Отметим, что для успешного отображения ActiveX в броузере требуется Microsoft Internet Explorer версии 3.0 и выше, при этом настройки уровня безопасности должны позволять запуск активного содержимого, расположенного в Intranet-зоне. Если в качестве броузера используется Netscape Navigator, он должен быть оснащен модулем расширения (plug-in), позволяющим интерпретировать тег языка HTML как элемент управления ActiveX (естественно, такая возможность существует только для версий Navigator, выполняющихся под управлением 32-разрядных версий Windows). Отметим также, что сгенерированную автоматически страницу можно в дальнейшем отредактировать с помощью любого html-редактора (или даже любого текстового редактора).

При поставке ActiveX через Web процедура аналогична описанной, но вместо локальных каталогов в строке URL следует указать Internet-адрес Web-сервера:

Рис.11. Настройка опций поставки ActiveX через Internet

Помимо этого, следует обратить внимание на дополнительные «пакеты» или другие файлы, которые следует включить в поставку, если опции проекта таковы, что требуют использования каких-либо дополнительных библиотек.. Разделение ActiveX на несколько файлов и выделение отдельных пакетов может быть использовано для того, чтобы уменьшить в целом время загрузки ActiveX через Internet, например, в случае предстоящей необходимости обновления версии ActiveX или при поставке нескольких разных ActiveX — в этом случае часть «пакетов» может быть установлена один раз, а далее производится поставка лишь небольшой содержательной части элемента ActiveX. Впрочем, не возбраняется создавать ActiveX и в виде одного файла. Отметим также, что при выборе опции Include CAB File compression можно собрать используемые файлы в один файл с расширением *.cab, фактически представляющий собой архив, что также уменьшает примерно в два раза время загрузки файлов через Internet.

Следует отметить, что в активных формах можно использовать практически все компоненты C++Builder, кроме TMainMenu. Возможна также динамическая генерация дополнительных форм на этапе выполнения, при этом дополнительные формы уже не будут содержаться в контейнере, а будут представлять собой обычные формы Windows (и, естественно, могут содержать в том числе и TMainMenu).

В заключение отметим, что, редактируя библиотеку типов, можно к созданным ActiveX добавлять свойства и методы и затем описывать их реализацию в соответствующем модуле. Более подробно о библиотеках типов, их назначении, создании, редактировании будет рассказано в последующих статьях данного цикла.

Дополнительную информацию Вы можете получить в компании Interface Ltd.

Программирование Delphi

Все о программировании.

Главное меню

Как импортировать управление ActiveX в Delphi

Давайте разберемся как добавить управление ActiveX в Ваши проекты Delphi.

  1. Запустите Delphi и выберите Component->Import ActiveX Control.
  2. Найдите управление ActiveX, которое Вы хотите импортировать (диалоговое окно отображает все ActiveX управления, зарегистрированные в Вашей системе). Назовем его SomeActiveX
  3. Выберите положение на Палитре Компонентов, куда Вы хотите поместить выбранную библиотеку
  4. Возможно лучше оставить выбранную опцию ActiveX
  5. Нажмите Install
  6. Выберите пакет, куда новый компонент должен быть установлен или
  7. Создайте новый пакет для нового управления TSomeActiveX
  8. Нажмите OK
  9. Delphi спросит Вас, хотите ли Вы перестроить измененный/новый пакет или нет
  10. Нажмите Да
  11. После того, как пакет откомпилируется, Delphi выведет сообщение, что новый компонент TSomeActiveX был зарегистрирован и уже доступен как часть VCL
  12. Закройте окно, позволяя Delphi сохранить изменения
  13. Теперь компонент доступен на вкладке ActiveX (если Вы не меняли эту настройку в шаге 3)
  14. Теперь просто поместите компонент на форму и используйте его

Примечание: эта оболочка будет интегрирована в исполняемый файл (или пакет во время выполнения), но .OCX файл для этого компонента должен быть зарегистрирован на Вашем компьютере в системе перед использованием.

Инсталляционные программы, типа InstallShield Express автоматизируют этот процесс регистрации.

Образовательный блог — всё для учебы

Расширение возможностей СОМ технологии привело к идее компонентного построения программ, что позволяет использовать только те части программы, которые нужны в настоящий момент для выполнения поставленной задачи.

С течением времени возможность создания элементов управления ActiveX была включена и в другие системы быстрой разработки приложений, включая и Delphi.

К настоящему времени пользователям доступны сотни управляющих элементов, разработанных десятками компаний, включая электронные таблицы, элементы для доступа к данным и многое другое. Используя технологию ActiveX, можно сегодня создавать приложения, собираемые из готовых компонентов.

Работа элементов ActiveX основана на реализации двух основных интерфейсов: lOleControl и lOleControlSite.

Технология создания ActiveX в Delphi (DAX) включает следующие возможности:
• создание элементов управление ActiveX;
• создание активных форм ActiveForm;
• инсталляцию готового элемента управления ActiveX в среду Delphi.

Основы работы управляющих элементов

Элементы управления ActiveX представляют собой динамические библиотеки-серверы, содержащие исполняемый код и исполняемые в адресном пространстве клиентского приложения (контейнера). Они включают уникальный идентификатор GUID и должны обладать возможностью саморегистрации в реестре Windows, которая фактически является основным отличием элементов управления ActiveX от СОМ-объектов.

Естественно, что взаимодействие между СОМ-субъектами: управляющим элементом и его контейнером определяется интерфейсами.

Спецификация управляющих элементов включает следующие аспекты их функционирования, для реализации которых предназначены свои группы интерфейсов:
• обеспечивающие пользовательский интерфейс;
• вызывающие методы управляющих элементов контейнером;
• посылающие события контейнеру;
• получающие данные о свойствах среды контейнера и обеспечивающие
доступ к свойствам управляющего элемента и их модификации
а) Для обеспечения пользовательского интерфейса предназначены такие интерфейсы, как: IOlelnPlaceActiveObject, IOlelnPlaceObject, IOleObject, IDa-
taObject, IViewObject2, IOleCache2, IRunnableObject, IPersistStorage.
б) Для обеспечения возможности вызова методов достаточно включить интерфейс IDispatch, с помощью метода Invoke которого можно вызывать необходимые методы. Фактически методы можно вызывать через виртуальную таблицу (раннее связывание) или через Dispatch интерфейс (позднее связывание).
в) Для обеспечения возможности посылки событий контейнеру следует
включить поддержку таких интерфейсов, как: IProvideClasslnfo2, IConnection-PointContainer, IConnectionPoint.
г) В элементы управления ActiveX добавлена возможность работы со свойствами, которых нет в OLE Automation.

Основы работы контейнеров

Контейнеры предназначены для включения управляющих элементов в приложения
Для решения проблемы взаимодействия компонентов и контейнеров введены понятия категорий компонентов (component categories), позволяющие управляющему элементу информировать компоненты о своих возможностях, помещая в реестр идентификаторы категорий — GUID (category identifier — CATID), гарантирующих способность выполнять некоторые функции. Анализируя CATID без создания экземпляров компонентов, контейнеры могут получать сведения о возможностях управляющих компонентов.

Контейнер должен иметь клиентский узел (client site), с помощью которого происходит связывание элемента ActiveX с контейнером.

Создание управляющих элементов ActiveX

Для создания управляющего элемента в Delphi можно воспользоваться соответствующим конструктором, позволяющим создавать элементы ActiveX из компонентов Delphi, являющихся наследниками класса TWinControl. Фактически конструктор позволяет создать необходимую «оболочку» вокруг компонента для превращения его в управляющий элемент.

Процесс создания элемента ActiveX состоит из следующих этапов:
• Создать с помощью конструктора «каркас» библиотеки, выполнив команды:
File\New\ ActiveX Library
• Запустить конструктор, создающий элемент ActiveX из VCL компонента:
File\New\ ActiveX Control.
• Выбрать компонент и заполнить сведения об элементе Для этого в открывшемся окне ActiveX Control Wizard из раскрывающегося списка VCL
Class Name следует выбрать зарегистрированный в Delphi компонент, который предполагается использовать для создания элемента управления ActiveX
• Скомпилировать и зарегистрировать элемент управления ActiveX, ко
мандами:
RunVRegister ActiveX Server
Созданный в результате компиляции файл получит расширение * Осх.

Создание активных форм

Delphi предоставляет также возможность создавать Active-формы, позволяющие помещать в нее несколько компонентов и все целиком использовать как элемент управления ActiveX.

Процесс создания элемента ActiveX состоит из следующих этапов:
• Создать экранную форму, выполнив команды: File\New\ ActiveForm
• Далее следует расположить на экранной форме нужные компоненты, написать соответствующий программный код и сохранить заготовку экран
ной формы.

Созданный файл получит расширение *.Осх.

Инсталляция управляющих элементов ActiveX
ComponetUmport ActiveX Control…
Откроется окно Import ActiveX, в верхней части которого будет представлен список библиотек элементов управления ActiveX, зарегистрированных в Windows. После выбора нужной из библиотек, Delphi прочитает ее библиотеку типов и составит список элементов управления.

Новые книги

Эта книга содержит рекомендации и методы, основанные на научных исследованиях, экспериментах, опросах потребителей и статистики. Автор использует знания из математики, социальной психологии, меметики и других наук и объясняет, почему и, что еще важнее, каким образом следует адаптировать для достижения максимальных результатов свои стратегии интернет-маркетинга: ведение блога, присутствие в соцсетях, почтовый маркетинг и вебинары.

На русском языке публикуется впервые.

Казалось бы, нет ничего сложного в том, чтобы создать хорошую презентацию: подбираем слайды поэстетичнее, используем по максимуму PowerPoint и продумываем как выгоднее преподнести себя. Но Саймон Мортон, основатель Eyeful Presentations, утверждает, что все это не главное. Неважно, насколько «дзенскими» являются ваши слайды, насколько выразительны и пластичны были ваши жесты и интонация в ходе выступления, какие сногсшибательные трюки вы применили: если в итоге слушатели так и не осознали, в чем состояла ваша ключевая мысль, – значит, ваша презентация провалилась.

На протяжении десятилетия Eyeful Presentations, одна из ведущих мировых компаний в области подготовки и проведения презентаций, разрабатывала и отлаживала свою методику под названием «Оптимизации презентации», в центре которой находится взаимодействие со слушателями и качество восприятия ими информации. И хотя в Eyeful никогда не делали секрета из своих наработок, только благодаря книге, которую вы держите в руках, эта методика, изложенная последовательно, полно и красочно, становится по-настоящему доступной для широкого круга выступающих.

Глава 13. Создание элементов управления ActiveX

Примечание
Несмотря на то, что мастер ActiveX Control не дает возможности автоматически создавать элементы управления ActiveX из компонентов, не являющихся потомками TWinControl, разработчик может создать такой элемент управления самостоятельно при помощи системы разработки Delphi ActiveX (DAX).

Вызовем мастера ActiveX Control. Появится окно мастера создания элемента ActiveX из оконного компонента Delphi (рис. 3.26).
В процессе использования данного мастера вам нужно выполнить следующее:
1. Выбрать компонент VCL из выпадающего списка VCL Class Name (Имя класса VCL).

Примечание
Как вы, вероятно, заметили, в выпадающем списке находятся далеко не все компоненты VCL. В данный список внесены только те компоненты, которые удовлетворяют следующим требованиям: находятся в текущем пакете, который используется в процессе разработки (следовательно, находятся в палитре компонентов); являются потомками компонента TWinControl; не исключаются из данного списка при помощи процедуры RegisterNonActiveX.

Многие из компонентов исключены из списка из-за того, что они либо не могут быть элементами управления ActiveX (например, компонент TDBGrid, т. к. для его работы нужен другой VCL-класс TDataSource), либо необходимо самостоятельно скорректировать их перед запуском мастера, чтобы они могли функционировать как элементы ActiveX (например, TTreeView, т. к. узлы компонента очень сложно представлять в ActiveX).
2. Выбрать новое имя ActiveX в поле для ввода New ActiveX Name (Новое имя ActiveX), если вас не устраивает имя, предлагаемое Delphi автоматически.
3. Выбрать имя модуля реализации создаваемого элемента ActiveX в поле для ввода Implementation Unit (Модуль реализации).
4. Выбрать имя проекта в поле для ввода Project Name (Имя проекта).
5. Выбрать потоковую модель в выпадающем списке Threading Model (Модель потока).
6. После этого вы можете установить три дополнительные опции:
Include About Box (Включить окно «О программе») — включить в проект диалоговое окно, которое будет содержать информацию о разработчике. Данное диалоговое окно представляет собой обычную форму Delphi;
Include Version Information (Включить информацию о версии) — включить в проект информацию о версии элемента управления ActiveX (данный пункт требуется для некоторых контейнеров, например, созданных в Visual Basic 4.0);
Make Control Licensed (Включить лицензионную информацию) — включить в проект лицензионную информацию (в случае коммерческого распространения элемента управления). В результате использовать данный элемент управления смогут только те разработчики, которые имеют лицензионный ключ, причем данное ограничение будет работать во всех средах разработки (Delphi, Visual Basic и др.). При установке данного флажка вместе с проектом элемента управления должен быть сгенерирован файл лицензии, имеющий расширение LIC. Чтобы дать возможность другим разработчикам использовать этот ActiveX, вам придется передавать лицензионным пользователям файл лицензии вместе с элементом управления ActiveX (имеющим расширение OCX).

Рис. 3.26. Мастер преобразования компонентов VCL Delphi в ActiveX
После внесения необходимых значений в поля, мастер автоматически создаст все файлы, которые нужны для поддержания данного элемента управления. В число таких файлов входят: сам проект, библиотека типов и файл реализации. Обратите внимание на то, что все элементы ActiveX являются либо библиотеками DLL, либо файлами OCX (что, в принципе, одно и то же).
Рассмотрим действия, которые выполняет мастер в процессе создания элемента управления ActiveX из компонента:
— мастер определяет, в каком модуле содержится элемент управления VCL. Данный модуль передается компилятору, который создает специальную символьную информацию для описания свойств, событий и методов элемента управления VCL;
— генерируется библиотека типов для проекта;
— мастер анализирует всю символьную информацию об элементе управления VCL и добавляет подходящие свойства и методы к интерфейсу и в библиотеку типов;

Примечание
Для определения, подходит ли данное свойство, метод или событие для включения в библиотеку типов, мастер проверяет, совместим ли с автоматизацией тип свойства, его параметры, а также возвращаемые значения событий и методов. С автоматизацией совместимы следующие типы: Byte, Smallint, Integer, Single, Double, Currency, TDateTime, WideString, WordBool, PSafeArray, TDecimal, OleVariant, lUnknown, IDispatch. Кроме перечисленных, разрешены параметры типов TStrings, TPicture и TFont. Для данных типов мастер создаст промежуточные объекты, которые позволят им быть инкапсулированными в IDispatch или Dispinterface.

— редактор библиотеки типов генерирует файл преобразованной библиотеки типов в соответствии с добавленными свойствами, событиями и методами;
— мастер создает файл реализации элемента управления ActiveX. Данный файл содержит элемент управления TActivexcontroi. Кроме того, мастер автоматически создает так называемые пересылки (forwarders) свойств и методов интерфейса. Пересылки направляют вызовы метода из элемента управления ActiveX в элемент управления VCL, а события — из элемента управления VCL в элемент ActiveX.
Листинг 3.7 содержит код файла проекта элемента управления ActiveX, созданного на основе компонента TRichEdit.

Листинг 3.7
library RichEditXControll;
uses
ComServ,
RichEditXControllJTLB in ‘RichEditXControllJTLB.pas’,
RichEditlmpll in ‘RichEditlmpll.pas’ ;
<$E ocx>
exports
DllGetClassObject, DllCanUnloadNow, DllRegisterServer, DllUnregisterServer;
<$R *.TLB>
<$R *.RES>
begin
end.

Описывать данный листинг не имеет особого смысла, т. к. его содержание достаточно очевидно.
Листинг 3.8 содержит код реализации элемента ActiveX.

Листинг 3.8
unit RichEditlmpll;
interface
uses
Windows, ActiveX, Classes, Controls, Graphics, Menus, Forms, StdCtrls, ComServ, StdVCL, AXCtrls, RichEditXControllJTLB, ComCtrls;
type
TRichEditX = class(TActiveXControl, IRichEditX)
private
< Private declarations >
FDelphiControl: TRichEdit;
FEvents: IRicnEditXEvents;
procedure ChangeEvent(Sender: TObject);
procedure KeyPressEvent(Sender: TObject; var Key: Char);
procedure ProtectChangeEvent(Sender: TObject; StartPos, EndPos:
Integer;
var AllowChange: Boolean);
procedure SaveClipboardEvent(Sender: TObject; NumObjects, NumChars: Integer; var SaveClipboard: Boolean);
procedure SelectionChangeEvent(Sender: TObject);
protected
< Protected declarations >
procedure DefinePropertyPages(DefinePropertyPage: TDefinePropertyPage); override;
procedure EventSinkChanged(const EventSink: lUnknown); override;
procedure InitializeControl; override;
function Get_Alignment: TxAlignment; safecall;
function Get_BorderStyle: TxBorderStyle; safecall;
function Get_CanUndo: WordBool; safecall;
function Get_Color: OLE_COLOR; safecall;
function Get_Ctl3D: WordBool; safecall;
function Get_Cursor: Smallint; safecall;
function Get_DoubleBuffered: WordBool; safecall;
function Get_DragCursor: Smallint; safecall;
function Get_DragMode: TxDragMode; safecall;
function Get_Enabled: WordBool; safecall;
function Get_Font: IFontDisp; safecall;
function Get_HideScrollBars: WordBool; safecall;
function Get_HideSelection: WordBool; safecall;
function Get_ImeMode: TxImeMode; safecall;
function Get_ImeName: WideString; safecall;
function Get_Lines: IStrings; safecall;
function Get_MaxLength: Integer; safecall;
function Get_Modified: WordBool; safecall;
function Get_ParentColor: WordBool; safecall;
function Get_ParentCtl3D: WordBool; safecall;
function Get_PlainText: WordBool; safecall;
function Get_ReadOnly: WordBool; safecall;
function Get_ScrollBars: TxScrollStyle; safecall;
function Get_SelLength: Integer; safecall;
function Get_SelStart: Integer; safecall;
function Get_SelText: WideString; safecall;
function Get_Text: WideString; safecall;
function Get_Visible: WordBool; safecall;
function Get_VisibleDockClientCount: Integer; safecall;
function Get_WantReturns: WordBool; safecall;
function Get_WantTabs: WordBool; safecall;
function Get_WordWrap: WordBool; safecall;
procedure _Set_Font(const Value: IFontDisp); safecall;
procedure Set_Alignment(Value: TxAlignment); safecall;
procedure Set_BorderStyle(Value: TxBorderStyle); safecall;
procedure Set_Color(Value: OLE_COLOR); safecall;
procedure Set_Ctl3D(Value: WordBool); safecall;
procedure Set_Cursor(Value: Smallint); safecall;
procedure Set_DoubleBuffered(Value: WordBool); safecall;
procedure Set_DragCursor(Value: Smallint); safecall;
procedure Set_DragMode(Value: TxDragMode); safecall;
procedure Set_Enabled(Value: WordBool); safecall;
procedure Set_Font(var Value: IFontDisp); safecall;
procedure Set_HideScrollBars(Value: WordBool); safecall;
procedure Set_HideSelection(Value: WordBool); safecall;
procedure Set_ImeMode(Value: TxImeMode); safecall;
procedure Set_ImeName(const Value: WideString); safecall;
procedure Set_Lines(const Value: IStrings); safecall;
procedure Set_MaxLength(Value: Integer); safecall;
procedure Set_Modified (Value: WordBool); safecall;
procedure Set_ParentColor(Value: WordBool); safecall;
procedure Set_ParentCtl3D(Value: WordBool); safecall;
procedure Set_PlainText(Value: WordBool); safecall;
procedure Set_ReadOnly(Value: WordBool); safecall;
procedure Set_ScrollBars(Value: TxScrollStyle); safecall;
procedure Set_SelLength(Value: Integer); safecall;
procedure Set_SelStart(Value: Integer); safecall;
procedure Set_SelText(const Value: WideString); safecall;
procedure Set_Text(const Value: WideString); safecall;
procedure Set_Visible(Value: WordBool); safecall;
procedure Set_WantReturns(Value: WordBool); safecall;
procedure Set_WantTabs(Value: WordBool); safecall;
procedure Set_WordWrap(Value: WordBool); safecall;
end;
implementation
uses ComObj;
< TRichEditX >
procedure TRichEditX.DefinePropertyPages(DefinePropertyPage: TDefinePropertyPage);
begin
Например, DefinePropertyPage(Class_RichEditXPage); >
end;
procedure TRichEditX.EventSinkChanged(const EventSink: lUnknown);
begin
FEvents := EventSink as IRichEditXEvents;
end;
procedure TRichEditX.InitialiZeControl;
begin
FDelphiControl :=* Control as TRichEdit;
FDelphiControl.OnChange := ChangeEvent;
FDelphiControl.OnKeyPress := KeyPressEvent;
FDelphiControl.OnProtectChange := ProtectChangeEvent;
FDelphiControl.OnSaveClipboard := SaveClipboardEvent;
FDelphiControl.OnSelectionChange := SelectionChangeEvent;
end;
function TRichEditX.Get_Alignment: TxAlignment;
begin
Result := Ord(FDelphiControl.Alignment);
end;
function TRichEditX.Get_BorderStyle: TxBorderStyle;
begin
Result := Ord(FDelphiControl.BorderStyle);
end;
function TRichEditX.Get_CanUndo: WordBool;
begin
Result := FDelphiControl.CanUndo;
end;
function TRichEditX.Get_Color: OLE_COLOR;
begin
Result := OLE_COLOR(FDelphiControl.Color);
end;
function TRichEditX.Get_Ctl3D: WordBool;
begin
Result := FDelphiControl.Ctl3D;
end;
function TRichEditX.Get_Cursor: Smallint;
begin
Result := Smallint(FDelphiControl.Cursor);
end;
function TRichEditX.Get_DoubleBuffered: WordBool;
begin
Result := FDelphiControl.DoubleBuffered;
end;
function TRichEditX.Get_DragCursor: Smallint;
begin
Result := Smallint(FDelphiControl.DragCursor);
end;
function TRichEditX.Get_DragMode: TxDragMode;
begin
Result := Ord(FDelphiControl.DragMode);
end;
function TRichEditX.Get_Enabled: WordBool;
begin
Result := FDelphiControl.Enabled;
end;
function TRichEditX.Get_Font: IFontDisp;
begin
GetOleFont(FDelphiControl.Font, Result) ;
end;
function TRichEditX.Get_HideScrollBars: WordBool;
begin
Result := FDelphiControl.HideScrollBars;
end;
function TRichEditX.Get_HideSelection: WordBool;
begin
Result := FDelphiControl.HideSelection;
end;
function TRichEditX.Get_ImeMode: TxImeMode;
begin
Result := Ord(FDelphiControl.ImeMode);
end;
function TRichEditX.Get_ImeName: WideString;
begin
Result := WideString(FDelphiControl.ImeName);
end;
function TRichEditX.Get_Lines: IStrings;
begin
GetOleStrings(FDelphiControl.Lines, Result);
end;
function TRichEditX.Get_MaxLength: Integer;
begin
Result := FDelphiControl.MaxLength;
end;
function TRichEditX.Get_Modified: WordBool;
begin
Result := FDelphiControl.Modified;
end;
function TRichEditX.Get_ParentColor: WordBool;
begin
Result := FDelphiControl.ParentColor;
end;
function TRichEditX.Get_ParentCtl3D: WordBool;
begin
Result := FDelphiControl.ParentCtlSD;
end;
function TRichEditX.Get_PlainText: WordBool;
begin
Result := FDelphiControl.Plaintext;
end;
function TRichEditX.Get_ReadOnly: WordBool;
begin
Result := FDelphiControl.Readonly;
end;
function TRichEditX.Get_ScrollBars: TxScrollStyle;
begin
Result := Ord(FDelphiControl.ScrollBars);
end;
function TRichEditX.Get_SelLength: Integer;
begin
Result := FDelphiControl.SelLength;
end;
function TRichEditX,Get_SelStart: Integer;
begin
Result := FDelphiControl.SelStart;
end;
function TRichEditX.Get_SelText: WideString;
begin
Result := WideString(FDelphiControl.SelText);
end;
function TRichEditX.Get_Text: WideString;
begin
Result := WideString(FDelphiControl.Text);
end;
function TRichEditX.Get_Visible: WordBool;
begin
Result := FDelphiControl.Visible;
end;
function TRichEditX.Get_VisibleDockClientCount: Integer;
begin
Result := FDelphiControl.VisibleDockClientCount;
end;
function TRichEditX.Get_WantReturns: WordBool;
begin
Result := FDelphiControl.WantReturns;
end;
function TRichEditX.Get_WantTabs: WordBool;
begin
Result := FDelphiControl.WantTabs;
end;
function TRichEditX.Get_WordWrap: WordBool;
begin
Result := FDelphiControl.Wordwrap;
end;
procedure TRichEditX._Set_Font(const Value: IFontDisp);
begin
SetOleFont(FDelphiControl.Font, Value);
end;
procedure TRichEditX.ChangeEvent(Sender: TObject);
begin
if FEvents <> nil then FEvents.OnChange;
end;
procedure TRichEditX.KeyPressEvent(Sender: TObject; var Key: Char);
var
TempKey: Smallint;
begin
TempKey := Smallint(Key);
if FEvents <> nil then FEvents.OnKeyPress(TempKey);
Key := Char(TempKey);
end;
procedure TRichEditX.ProtectChangeEvent(Sender: TObject; StartPos, EndPos: Integer; var AllowChange: Boolean);
var
TempAllowChange: WordBool;
begin
TempAllowChange := WordBool(AllowChange);
if FEvents <> nil then FEvents.OnProtectChange(StartPos, EndPos, TempAllowChange);
AllowChange := Boolean(TempAllowChange);
end;
procedure TRichEditX.SaveClipboardEvent(Sender: TObject; NumObjects, NumChars: Integer; var SaveClipboard: Boolean);
var
TempSaveClipboard: WordBool;
begin
TempSaveClipboard := WordBool(SaveClipboard);
if FEvents <> nil then FEvents.OnSaveClipboard(NumObjects, NumChars, TempSaveClipboard); SaveClipboard := Boolean(TempSaveClipboard);
end;
procedure TRichEditX.SelectionChangeEvent(Sender: TObject);
begin
if FEvents <> nil then FEvents.OnSelectionChange;
end;
procedure TRichEditX.Set_Alignment(Value: TxAlignment);
begin
FDelphiControl.Alignment := TAlignment(Value) ;
end;
procedure TRichEditX.Set_BorderStyle(Value: TxBorderStyle);
begin
FDelphiControl.BorderStyle := TBorderStyle(Value);
end;
procedure TRichEditX.Set_Color(Value: OLE_COLOR);
begin
FDelphiControl.Color := TColor(Value);
end;
procedure TRichEditX.Set_Ctl3D(Value: WordBool);
begin
FDelphiControl.Ctl3D := Value;
end;
procedure TRichEditX.Set_Cursor(Value: Smallint);
begin
FDelphiControl.Cursor := TCursor(Value);
end;
procedure TRichEditX.Set_DoubleBuffered(Value: WordBool);
begin
FDelphiControl.DoubleBuffered := Value;
end;
procedure TRichEditX.Set_DragCursor(Value: Smallint);
begin
FDelphiControl.DragCursor := TCursor(Value);
end;
procedure TRichEditX.Set_DragMode(Value: TxDragMode);
begin
FDelphiControl.DragMode := TDragMode(Value);
end;
procedure TRichEditX.Set_Enabled(Value: WordBool);
begin
FDelphiControl.Enabled := Value;
end;
procedure TRichEditX.Set_Font(var Value: IFontDisp);
begin
SetOleFont(FDelphiControl.Font, Value);
end;
procedure TRichEditX.SetJHideScrollBars(Value: WordBool);
begin
FDelphiControl.H >end;
procedure TRichEditX.Set_HideSelection(Value: WordBool);
begin
FDelphiControl.H >end;
procedure TRichEditX.Set_ImeMode(Value: TxImeMode);
begin
FDelphiControl.ImeMode := TImeMode(Value);
end;
procedure TRichEditX.Set_ImeName(const Value: WideString);
begin
FDelphiControl.ImeName := TImeName(Value);
end;
procedure TRichEditX.Set_Lines(const Value: IStrings);
begin
SetOleStrings(FDelphiControl.Lines, Value);
end;
procedure TRichEditX.Set_MaxLength(Value: Integer);
begin
FDelphiControl.MaxLength := Value;
end;
procedure TRichEditX.Set_Modified(Value: WordBool);
begin
FDelphiControl.Modified := Value;
end;
procedure TRichEditX.Set_ParentColor(Value: WordBool);
begin
FDelphiControl.ParentColor := Value;
end;
procedure TRichEditX.Set_ParentCtl3D(Value: WordBool);
begin
FDelphiControl.ParentCtl3D := Value;
end;
procedure TRichEditX.Set_PlainText(Value: WordBool);
begin
FDelphiControl.PlainText := Value;
end;
procedure TRichEditX.Set_ReadOnly(Value: WordBool);
begin
FDelphiControl.Readonly := Value;
end;
procedure TRichEditX.Set_ScrollBars(Value: TxScrollStyle);
begin
FDelphiControl.ScrollBars := TScrollStyle(Value);
end;
procedure TRichEditX.Set_SelLength(Value: Integer);
begin
FDelphiControl.SelLength := Value;
end;
procedure TRichEditX.Set_SelStart(Value: Integer);
begin
FDelphiControl.SelStart := Value;
end;
procedure TRichEditX.Set_SelText(const Value: WideString);
begin
FDelphiControl.SelText := String(Value);
end;
procedure TRichEditX.Set_Text(const Value: WideString>;
begin
FDelphiControl.Text := TCaption(Value);
end;
procedure TRichEditX.Set_Visible(Value: WordBool);
begin
FDelphiControl.Visible := Value;
end;
procedure TRichEditX.Set_WantReturns(Value: WordBool);
begin
FDelphiControl.WantReturns := Value;
end;
procedure TRichEditX.Set_WantTabs(Value: WordBool);
begin
FDelphiControl.WantTabs := Value;
end;
procedure TRichEditX.Set_WordWrap(Value: WordBool);
begin
FDelphiControl.Wordwrap := Value;
end;
initialization
TActiveXControlFactory.Create (ComServer, TRichEditX,TRichEdit,Class_RichEditX,
1,
»
0,
tmApartment);
end.

Описанный в данном файле класс TRichEditx является потомком TActivexcontrol. Этот класс применяется для установки соответствия между бывшим компонентом Delphi TRichEdit и контейнерами, в которых будет размещаться созданный элемент управления.
На рис. 3.27 показано окно редактора библиотеки типов для данного элемента управления ActiveX. Листинг 3.9 содержит код файла библиотеки типов.

Рис. 3.27. Элемент управления RichEdit в редакторе библиотеки типов

Листинг 3.9
unit RichEditXControllJTLB;
// Внимание
// Типы, объявленные в этом файле, были сгенерированы из данных
// библиотеки типов. Если библиотека типов явно или неявно (ссылается
// на эту библиотеку через другую) реимпортирована или с помощью команды
// ‘Refresh’ в окне Type Library Editor активизирована во время
// редактирования библиотеки типов, содержимое данного файла должно быть
// регенерировано, а все внесенные вручную изменения могут быть утеряны.
*****************************************************
// PASTLWTR : $Revision: 1.88 $
// Файл создан 15.02.2001 18:30:46 из библиотеки типов, описанной ниже.
*****************************************************
// Type Lib: C:\Program
Files\Borland\Delphi5\Projects\. \RichEditXControll.tlb (1)
// IIDXLCID: \0
// Helpfile:
// DepndLst:
// (1) v2.0 stdole, (C:\WINDOWS\SYSTEM\stdole2.tlb)
// (2) v4.0 StdVCL, (C:\WINDOWS\SYSTEM\STDVCL40.DLL)
*****************************************************
<$TYPEDADDRESS OFF>// Модуль должен быть откомпилирован без проверки
// типов указателей,
interface
uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL;
//***********************************************
// GUIDS объявлены в TypeLibrary. Используются следующие префиксы:
// Type Libraries : LIBID_xxxx
// CoClasses : CLASS_xxxx
// DISPInterfaces : DIID_xxxx
// Non-DISP interfaces: IID_xxxx
//***********************************************
const
RichEditXControllMajorVersion = 1; RichEditXControllMinorVersion =0; ‘
LIB ;
I ;
DI ;
;
//***********************************************
// Объявление перечислений, определенных в библиотеке типов
//***********************************************
// Константы для TxAlignment
type
TxAlignment = TOleEnum;
const
taLeftJustify = $00000000;
taRightJustify = $00000001;
taCenter = $00000002;
// Константы для TxBorderStyle
type
TxBorderStyle = TOleEnum;
const
bsNone = $00000000;
bsSingle = $00000001;
// Константы для TxDragMode
type
TxDragMode = TOleEnum;
const
dmManual = $00000000;
dmAutomatic = $00000001;
// Константы для TxImeMode
type
TxImeMode = TOleEnum;
const
imDisable = $00000000;
imClose = $00000001;
imOpen = $00000002;
imDontCare = $00000003;
imSAlpha = $00000004;
imAlpha = $00000005;
imHira = $00000006;
imSKata = $00000007;
imKata = $00000008;
imChinese = $00000009;
imSHanguel = $OOOOOOOA;
imHanguel = $OOOOOOOB;
// Константы для TxScrollStyle
type
TxScrollStyle = TOleEnum;
const
ssNone = $00000000;
ssHorizontal = $00000001;
ssVertical = $00000002;
ssBoth = $00000003;
// Константы для TxMouseButton
type
TxMouseButton = TOleEnum;
const
mbLeft = $00000000;
mbRight = $00000001;
mbM > type
// Предварительное объявление типов, определенных в библиотеке типов
//***********************************************
IRichEditX = interface;
IRichEditXDisp = dispinterface;
IRichEditXEvents = dispinterface;
//***********************************************
// Объявление CoClasses, определенных в библиотеке типов
//***********************************************
RichEditX = IRichEditX;
//***********************************************
// Объявление структур, союзов и альянсов.
//***********************************************
PPUserTypel = A IFontDisp; <*>
//***********************************************
// Interface: IRichEditX
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: <86f5c46c-cda6-4279-8bf4-f69f1a051ed7>
//***********************************************
IRichEditX = interface(IDispatch)
[‘<86f5c46c-cda6-4279-8bf4-f69f1a051ed7>‘]
function Get_Alignment: TxAlignment; safecall;
procedure Set_Alignment(Value: TxAlignment); safecall;
function Get_BorderStyle: TxBorderStyle; safecall;
procedure Set_BorderStyle(Value: TxBorderStyle); safecall;
function Get_Color: OLE_COLOR; safecall;
procedure Set_Color(Value: OLE_COLOR); safecall;
function Get_Ctl3D: WordBool; safecall;
procedure Set_Ctl3D(Value: WordBool); safecall;
function Get_DragCursor: Smallint; safecall;
procedure Set__DragCursor'(Value: Smallint); safecall;
function Get_DragMode: TxDragMode; safecall;
procedure Set_DragMode(Value: TxDragMode); safecall;
function Get_Enabled: WordBool; safecall;
procedure Set_Enabled(Value: WordBool); safecall;
function Get_Font: .IFontDisp; safecall;
procedure _Set_Font(const Value: IFontDisp); safecall;
procedure Set_Font(var Value: IFontDisp); safecall;
function Get_HideSelection: WordBool; safecall;
procedure Set_HideSelection(Value: WordBool); safecall;
function Get_HideScrollBars: WordBool; safecall;
procedure Set_HideScrollBars(Value: WordBool); safecall;
function Get_ImeMode: TxImeMode; safecall;
procedure Set_ImeMode(Value: TxImeMode); safecall;
function Get_ImeName: WideString; safecall;
procedure Set_ImeName(const Value: WideString>; safecall;
function Get_Lines: IStririgs; safecall;
procedure Set_Lines(const Value: IStrings); safecall;
function Get_MaxLength: Integer; safecall;
procedure Set_MaxLength(Value: Integer); safecall;
function Get_ParentColor: WordBool; safecall;
procedure Set_ParentColor(Value: WordBool); safecall;
function Get_ParentCtl3D: WordBool; safecall;
procedure Set_ParentCtl3D(Value: WordBool); safecall;
function Get_PlainText: WordBool; safecall;
procedure Set_PlainText(Value: WordBool); safecall;
function Get_ReadOnly: WordBool; safecall;
procedure Set_ReadOnly(Value: WordBool); safecall;
function Get_ScrollBars: TxScrollStyle; safecall;
procedure Set_ScrollBars(Value: TxScrollStyle); safecall;
function Get_Visible: WordBool; safecall;
procedure Set_Visible(Value: WordBool); safecall;
function Get_WantTabs: WordBool; safecall;
procedure Set_WantTabs(Value: WordBool); safecall;
function Get_WantReturns: WordBool; safecall;
procedure Set_WantReturns(Value: WordBool); safecall;
function Get_WordWrap: WordBool; safecall;
procedure Set_WordWrap(Value: WordBool); safecall;
function Get_CanUndo: WordBool; safecall;
function Get_Modified: WordBool; safecall;
procedure Set_Modifled(Value: WordBool); safecall;
function Get_SelLength: Integer; safecall;
procedure Set_SelLength(Value: Integer); safecall;
function Get_SelStart: Integer; safecall;
procedure Set_SelStart(Value: Integer); safecall;
function Get_SelText: WideString; safecall;
procedure Set_SelText(const Value: WideString); safecall;
function GetJText: WideString; safecall;
procedure Set_Text(const Value:.WideString); safecall;
function Get_DoubleBuffered: WordBool; safecall;
procedure Set_DoubleBuffered(Value: WordBool); safecall;
function Get_VisibleDockClientCount: Integer; safecall;
function Get_Cursor: Smallint; safecall;
procedure Set_Cursor(Value: Smallint); safecall;
property Alignment: TxAlignment read Get_Alignment write Set_Alignment ;
property BorderStyle: TxBorderStyle read Get_BorderStyle write Set_BorderStyle;
property Color: OLE_COLOR read Get_Color write Set_Color,;
property CtlSD: WordBool read Get_Ctl3D write Set_Ctl3D;
property DragCursor: Smallint read Get_DragCursor write Set_DragCursor;
property DragMode: TxDragMode read Get_DragMode write Set_DragMode;
property Enabled: WordBool read Get_Enabled write Set_Enabled;
property Font: IFontDisp read Get_Font write _Set_Font;
property HideSelection: WordBool read Get_HideSelection write Set_HideSelection;
property HideScrollBars: WordBool read Get_HideScrollBars write Set_HideScrollBars;
property ImeMode: TxImeMode read Get_ImeMode write Set_ImeMode;
property ImeName: WideString read Get_ImeName write Set_ImeName;
property Lines: IStrings read Get_Lines write Set_Lines;
property MaxLength: Integer read Get_MaxLength write Set_MaxLength;
property ParentColor: WordBool read Get_ParentColor write Set_ParentColor;
property ParentCtlSD: WordBool read Get_ParentCtl3D write Set_ParentCtl3D;
property PlainText: WordBool read Get_PlainText write Set_PlainText;
property Readonly: WordBool read Get_ReadOnly write Set_ReadOnly;
property ScrollBars: TxScrollStyle read Get_ScrollBars write Set_ScrollBars;
property Visible: WordBool read Get_Visible write Set_Visible;
property WantTabs: WordBool read Get_WantTabs write Set_WantTabs;
property WantReturns: WordBool read Get_WantReturns write SetJWantReturns;
property Wordwrap: WordBool read Get_WordWrap write Set_WordWrap;
property CanUndo: WordBool read Get_CanUndo;
property Modified: WordBool read Get__Modified write Set_Modified;
property SelLength: Integer read Get_SelLength write Set_SelLength;
property SelStart: Integer read Get_SelStart write Set_SelStart;
property SelText: WideString read Get_SelText write Set_SelText;
property Text: WideString read Get_Text write Set_Text;
property DoubleBuffered: WordBool read Get_DoubleBuffered write Set_DoubleBuffered;
property VisibleDockClientCount: Integer read Get_VisibleDockClientCoxint;
property Cursor: Smallint read Get_Cursor write Set_Cursor;
end;
//***********************************************
// Displntf: IRichEditXDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: <86f5c46c-cda6-4279-8bf4-f69f1a051ed7>
//***********************************************
IRichEditXDisp = dispinterface
[‘<86f5c46c-cda6-4279-8bf4-f69f1a051ed7>‘]
property Alignment: TxAlignment dispid 1;
property BorderStyle: TxBorderStyle dispid 2;
property Color: OLE_COLOR dispid -501;
property Ctl3D: WordBool dispid 3;
property DragCursor: Smallint dispid 4;
property DragMode: TxDragMode dispid 5;
property Enabled: WordBool dispid -514;
property Font: IFontDisp dispid -512;
property HideSelection: WordBool dispid 6;
property HideScrollBars: WordBool dispid 7;
property ImeMode: TxImeMode dispid 8;
property ImeName: WideString dispid 9;
property Lines: IStrings dispid 10;
property MaxLength: Integer dispid 11;
property ParentColor: WordBool dispid 12;
property ParentCtl3D: WordBool dispid 13;
property PlainText: WordBool dispid 14;
property Readonly: WordBool dispid 15;
property ScrollBars: TxScrollStyle dispid 16;
property Visible: WordBool dispid 17;
property WantTabs: WordBool dispid 18;
property WantReturns: WordBool dispid 19;
property Wordwrap: WordBool dispid 20;
property CanUndo: WordBool readonly dispid 34;
property Modified: WordBool dispid 35;
property SelLength: Integer dispid 36;
property SelStart: Integer dispid 37;
property SelText: WideString dispid 38;
property Text: WideString dispid -517;
property DoubleBuffered: WordBool dispid 39;
property VisibleDockClientCount: Integer readonly dispid 40;
property Cursor: Smallint dispid 49;
end;
//***********************************************
// Displntf: IRichEditXEvents
// Flags: (0)
// QUID: <21ab5f94-7d87-4fco-ab5a-9bce1d05af8b>
//***********************************************
IRichEditXEvents = dispinterface
[‘<21ab5f94-7d87-4fco-ab5a-9bce1d05af8b>‘]
procedure OnChange; dispid 1;
procedure OnKeyPress(var Key: Smallint); dispid 8;
procedure OnProtectChange(StartPos: Integer; EndPos: Integer; var AllowChange: WordBool); dispid 16;
procedure OnSaveClipboardfNumObjects: Integer; NumChars: Integer; var SaveClipboard: WordBool); dispid 18;
procedure OnSelectionChange; dispid 19;
end;

Илон Маск рекомендует:  Данные, их представление и формы пользовательского интерфейса

// Объявление класса OLE Control Proxy
// Control Name TRichEditX
// Help String RichEditX Control
// Default Interface IRichEditX
// Def. Intf. DISP? No
// Event Interface IRichEditXEvents
// TypeFlags (34) CanCreate Control
//***********************************************
TRichEditXOnKeyPress = procedure(Sender: TObject; var Key: Smallint) of object;
TRichEditXOnProtectChange = procedure(Sender: TObject; StartPos: Integer; EndPos: Integer;
var AllowChange: WordBool) of object;
TRichEditXOnSaveClipboard = procedure(Sender: TObject; NumObjects: Integer; NumChars-: Integer;
var SaveClipboard: WordBool) of object;
TRichEditX = class(Telecontrol)
private
FOnChange: TNotifyEvent;
FOnKeyPress: TRichEditXOnKeyPress;
FOnProtectChange: TRichEditXOnProtectChange;
FOnSaveClipboard: TRichEditXOnSaveClipboard;
FOnSelectionChange: TNotifyEvent;
FIntf: IRichEditX;
function GetControlInterface: IRichEditX;
protected
procedure CreateControl;
procedure InitControlData; override/function Get_Lines: IStrings;
procedure Set_Lines(const Value: IStrings);
public
property Controllnterface: IRichEditX read GetControlInterface;
property Defaultlnterface: IRichEditX read GetControlInterface;
property CanUndo: WordBool index 34 read GetWordBoolProp;
property Modified: WordBool index 35 read GetWordBoolProp write SetWordBoolProp;
property SelLength: Integer index 36 read GetlntegerProp write SetlntegerProp;
property SelStart: Integer index 37 read GetlntegerProp write SetlntegerProp;
property SelText: WideString index 38 read GetWideStringProp write SetWideStringProp;
property Text: WideString index -517 read GetWideStringProp write SetWideStringProp;
property DoubleBuffered: WordBool index 39 read GetWordBoolProp write SetWordBoolProp;
property VisibleDockClientCount: Integer index 40 read GetlntegerProp;
published
property Alignment: TOleEnum index 1 read GetTOleEnumProp write SetTOleEnumProp stored False;
property BorderStyle: TOleEnum index 2 read GetTOleEnumProp write SetTOleEnumProp stored False;
property Color: TColor index -501 read GetTColorProp write SetTColorProp stored False;
property Ctl3D: WordBool index 3 read GetWordBoolProp write SetWordBoolProp stored False;
property DragCursor: Smallint index 4 read GetSmallintProp write SetSmallintProp stored False property DragMode: TOleEnum index 5 read GetTOleEnumProp write SetTOleEnumProp stored False;
property Enabled: WordBool index -514 read GetWordBoolProp write SetWordBoolProp stored False;
property Font: TFont index -512 read GetTFontProp write SetTFontProp stored False;
property HideSelection; WordBool index 6 read GetWordBoolProp write SetWordBoolProp stored False;
property HideScrollBars: WordBool index 7 read GetWordBoolProp write SetWordBoolProp stored False;
property ImeMode: TOleEnum index 8 read GetTOleEnumProp write SetTOleEnumProp stored False;
property ImeName: WideString index 9 read GetWideStringProp write SetWideStringProp stored False;
property Lines: IStrings read Get_Lines write Set_Lines stored False property MaxLength: Integer index 11 read GetlntegerProp write SetlntegerProp stored False
property ParentColor: WordBool index 12 read GetWordBoolProp write SetWordBoolProp stored False;
property ParentCtlSD: WordBool index 13 read GetWordBoolProp write SetWordBoolProp stored False;
property PlainText: WordBool index 14 read GetWordBoolProp write SetWordBoolProp stored False;
property Readonly: WordBool index 15 read GetWordBoolProp write SetWordBoolProp stored False;
property ScrollBars: TOleEnum index 16 read GetTOleEnumProp write SetTOleEnumProp stored False;
property Visible: WordBool index 17 read GetWordBoolProp write SetWordBoolProp stored False;
property WantTabs: WordBool index 18 read GetWordBoolProp write SetWordBoolProp stored False;
property WantReturns: WordBool index 19 read GetWordBoolProp write SetWordBoolProp stored False;
property Wordwrap: WordBool index 20 read GetWordBoolProp write SetWordBoolProp stored False;
property Cursor: Smallint index 49 read GetSmallintProp write SetSmallintProp stored False;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnKeyPress: TRichEditXOnKeyPress read FOnKeyPress write FOnKeyPress;
property OnProtectChange: TRichEditXOnProtectChange read FOnProtectChange write FOnProtectChange;
property OnSaveClipboard: TRichEditXOnSaveClipboard read FOnSaveClipboard write FOnSaveClipboard;
property OnSelectionChange: TNotifyEvent read FOnSelectionChange write FOnSelectionChange;
end;
procedure Register; implementation uses ComObj;
procedure TRichEditX.InitControlData; const
CEventDisp > $00000001, $00000008, $00000010, $00000012, $00000013); CTFontlDs: array [0..0] of DWORD = (
$FFFFFEOO); CControlData: TControlData2 = (
ClassID: ‘<7c731eeo-d98d-4040-8fe1-eocb9e54c58b>‘;
EventHD: ‘<21ab5f94-7d87-4fco-ab5a-9bce1d05af8b>‘;
EventCount: 5;
EventDispIDs: @CEventDispIDs;
LicenseKey: nil (*HR:$80040154*);
Flags: $00000020;
Version: 401;
FontCount: 1;
FontlDs: @CTFontIDs);
begin
ControlData := @CControlData;
TControlData2(CControlData).FirstEventOfs := Cardinal(SSFOnChange) — Cardinal(Self);
end;
procedure TRichEditX.CreateControl;
procedure DoCreate;
begin
FIntf := lUnknown(OleObject) as IRichEditX;
end;
begin
if FIntf = nil then DoCreate;
end;
function TRichEditX.GetControlInterface: IRichEditX;
begin
CreateControl;
Result := FIntf;
end;
function TRichEditX.Get_Lines: IStrings;
begin
Result := DefaultInterface.Get_Lines;
end;
procedure TRichEditX.Set_Lines(const Value: IStrings);
begin
Defaultlnterface.Set_Lines(Value);
end;
procedure Register;
begin
RegisterComponents(‘ActiveX’,[TRichEditX]);
end;
end.

Как вы можете видеть, приведенные выше листинги имеют достаточно большой размер. Но тот факт, что Delphi берет на себя такую большую работу, позволяет даже непрофессионалу в разработке элементов управления ActiveX создавать свои ActiveX при помощи мастера. Мастер в данном случае генерирует полностью функциональный элемент управления ActiveX с интерфейсами, библиотекой типов и событиями, при этом разработчику не нужно вводить собственный код!
Для установки данного элемента управления в палитру компонентов Delphi нужно сделать следующее:
1. Откомпилировать проект с помощью пункта главного меню Project/Compile (Проект/Компилировать ), при этом будет создана библиотека OCX.
2. С помощью пункта главного меню Component/Import ActiveX Control (Компонент/Импорт элемента управления ActiveX) открыть окно импорта нового элемента ActiveX.
3. В диалоговом окне импорта ActiveX нажать кнопку Add (Добавить), перейти в каталог, содержащий созданный файл OCX, и выбрать его двойным щелчком, элемент управления появится в списке диалогового окна импорта ActiveX.
4. Выбрать данный элемент управления в списке и нажать кнопку Install (Установить).
5. Выбрать файл пакета и нажать кнопку ОК.
После выполнения данной последовательности шагов в палитре компонентов Delphi появится ваш элемент управления ActiveX.
Следует заметить, что создание элементов управления ActiveX из стандартных компонентов Delphi применяется очень редко. Вы можете использовать данную процедуру преобразования компонента в ActiveX к самостоятельно созданному компоненту, что значительно расширит его функциональность и позволит использовать ваш компонент разработчиками в других средах программирования.
Создание ActiveX из форм
Данный способ создания элементов управления позволяет на базе собственной формы приложения создать элемент ActiveX. Этот способ носит название ActiveForms.
Попробуем создать элемент управления ActiveX из формы. Выполним следующие шаги:
1. Вызовем мастер ActiveForm. Для этого выберем пункт главного меню File/New (Файл/Новый), и перейдя на вкладку ActiveX выберем пиктограмму ActiveForm. Появится окно мастера (рис. 3.28).
Как можно видеть, данный мастер очень похож на мастера преобразования компонента VCL Delphi в элемент управления ActiveX. Но отличие сразу бросается в глаза. В поле имени класса VCL Class Name (Имя класса VCL) мастер автоматически устанавливает значение TActiveForm.

Рис. 3.28. Диалоговое окно мастера ActiveForm
2. В поле New ActiveX Name (Новое имя ActiveX) нам нужно ввести имя создаваемого элемента управления ActiveX. Введем имя MyForm, при этом автоматически произойдут изменения в других полях (они описаны выше для мастера ActiveX Control).
3. После нажатия кнопки ОК мастер создает все необходимые заготовки для элемента управления ActiveX (практически так же, как и в предыдущем случае). Поверхность формы MyForm становится рабочей поверхностью. Вы можете размещать на ней произвольные компоненты, описывать методы и события компонентов и формы, устанавливать их свойства.
Разместим на форме MyForm два компонента CоmВох, как показано на рис. 3.29.

Рис. 3.29. Форма MyForm
Внесем в свойство items для первого компонента СотЬоВох значения, соответствующие названиям месяцев с января по декабрь. В свойство items второго компонента СотЬоВох внесем значения, которые соответствуют названиям дней недели с понедельника по воскресенье. Итак, при нажатии на первый список в нем должны отображаться названия месяцев, а при нажатии кнопки второго списка — названия дней недели.
В принципе, мы уже создали элемент управления ActiveX. Но данный элемент управления будет бесполезным, т. к. нам необходимо, чтобы выбранные в списках значения передавались пользователю. Для этого нужно создать интерфейс с пользователем элемента управления.
Для решения данной задачи нам необходимо добавить в библиотеку типов элемента управления в интерфейс IMyForm два новых свойства. Назовем их, например, Month и Day. Откроем редактор библиотеки типов при помощи пункта главного меню View/Type Library (Просмотр/Библиотека типов). Работать с ней нам уже приходилось, поэтому не будет сложным добавить к интерфейсу IMyForm свойства Month и Day (рис. 3.30).
Теперь нужно обновить модуль реализации MyFormImpl1. Для чего необходимо нажать кнопку Refresh Implementation (Обновить реализацию) в верхней панели инструментов редактора библиотеки типов. При этом в обоих файлах проекта появляются описания новых свойств, а в файле реализации — заготовки кода (листинг 3.10).

Листинг З.10
function TMyForm.Get_Day: Integer;
begin
end;
function TMyForm.Get_Month: Integer;
begin
end;
procedure TMyForm.Set_Day(Value: Integer);
begin
end;
procedure TMyForm.Set_Month(Value: Integer);
begin
end;

Рис. 3.30. Редактор библиотеки типов с добавленными в интерфейс IMyForm свойствами Month и Day
Как мы видим, были добавлены две заготовки для функций Get и две заготовки для процедур set. Функции Get предназначены для передачи значения свойства в программу, вызвавшую данную функцию. Процедуры Set служат для передачи и установки необходимых параметров.
Заполним эти заготовки следующим образом (листинг 3.11):

Листинг 3.11
function TMyForm.Get_Day: Integer;
begin
Result:=ComboBox2.Itemlndex;
end;
function TMyForm.Get_Month: Integer;
begin
Result: =ComboBoxl. Itemlndex;
end;
procedure TMyForm.Set_Day(Value: Integer);
begin
ComboBox2.Itemlndex:=value;
end;
procedure TMyForm.Set_Month(Value: Integer);
begin
ComboBoxl.Itemlndex:=value;
end;

Передаваемые и принимаемые значения свойств Day и Month в нашем случае имеют тип integer, хотя вы могли присвоить данным свойствам другой тип в редакторе библиотеки типов в процессе создания этих свойств.
Вот и все. Мы создали элемент управления ActiveX на основе формы. Теперь осталось лишь откомпилировать проект и установить элемент управления в палитру компонентов (как это сделать, описано в конце предыдущего раздела).
Попробуем использовать данный элемент управления ActiveX в своем приложении. Создадим новый проект. Разместим на нем элемент управления ActiveX MyForm. Кроме того, расположим на форме четыре кнопки и два компонента Edit (рис. 3.31).

Рис. 3.31. Внешний вид приложения, использующего элемент управления ActiveX MyForm
На листинге 3.12 приведен код для приложения, внешний вид которого представлен на рис. 3.31.

Листинг 3.12
unit Unitl;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, OleCtrls, MyFormProjlJTLB;
type
TForml = class(TForm)
MyForml: TMyForm;
GetMonth: TButton;
Editl: TEdit;
GetDay: TButton;
Edit2: TEdit;
SetMonth: TButton;
SetDay: TButton;
Label1: TLabel;
Label2: TLabel;
procedure GetMonthClick(Sender: TObject);
procedure GetDayClick(Sender: TObject);
procedure SetMonthClick(Sender: TObject)’;
procedure SetDayClick(Sender: TObject);
private
< Private declarations >
public
< Public declarations >
end;
var
Forml: TForml;
implementation <$R *.DFM>
procedure TForml.GetMonthClick(Sender: TObject);
begin
Editl.Text:=IntToStr(MyForml.Month+1);
end;
procedure TForml.GetDayClick(Sender: TObject);
begin
Edit2.Text:=IntToStr(MyForml.Day+1);
end;
procedure TForml.SetMonthClick(Sender: TObject);
begin
MyForml.Month:=StrToInt(Edit1.Text)-1;
end;
procedure TForml.SetDayClick(Sender: TObject);
begin
MyForml.Day:=StrToInt(Edit2.Text)-1;
end;
end.

При нажатии на любую из двух кнопок, размещенных на форме слева (GetMonth и GetDay), вы получите порядковый номер значения из нужного списка компонента MyForm (т. к. нумерация элементов списка CоmВох на чинается с нуля, то мы прибавляем к получаемому значению единицу) в соответствующее поле редактирования Edit. Нажатие любой из кнопок справа на форме (setMonth и setDay) приведет к передаче значения из необходимого поля редактирования Edit в элемент управления ActiveX. При этом произойдет установка соответствующего свойства элемента MyForm.
Работу данного приложения иллюстрирует рис. 3.32.

Рис. 3.32. Приложение, использующее ActiveX в процессе исполнения

indbooks

Читать онлайн книгу

Часто задаваемые вопросы по Borland Delphi

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

Условные обозначения, используемые в данном FAQ:

Материал относительно Delphi 1.0

Пример (исходный текст программы) для Delphi 1.0

Материал относительно Delphi 2.0

Пример (исходный текст программы) для Delphi 2.0

Материал относительно Delphi 3.0

Пример (исходный текст программы) для Delphi 3.0

Общие вопросы по Delphi и данному FAQ (часть 1)
Введение

1. Какова цель этого FAQ?

Этот FAQ предназначен для ответов на некоторые вопросы относительно новой cреды разработки Borland International, называемой Delphi. Этот документ, в действительности, не FAQ в полном смысле этого термина, потому что некоторые из вопросов, на которые здесь есть ответы, не очень часто задают на самом деле.

Вначале мы выпускали FAQ, куда помещали все доступные сведения о Delphi в текстовом виде. Далее была промежуточная версия в формате WinHelp. Теперь, после ряда трансформаций FAQ обличен в форму HTML.

2. Как я могу получить последнюю версию FAQ?

Проще всего зайти на наш WWW-сервер (www.demo.ru) и загрузить оттуда свежие версии всех имеющихся материалов, которые, кстати, помимо Delphi, охватывают весь спектр продуктов, выпускаемых фирмой Borland International. Также вы можете получить текстовую версию данных материалов, загрузив файл delfaqs.zip.

Вопросы общего характера

1. Что такое Delphi?

Delphi — это достаточно новый продукт Borland International для быстрого создания приложений (RAD). Высокопроизводительный инструмент визуального построения приложений, работающих с базами данных в архитектуре клиент-сервер, Internet/Intranet, а также для локальных машин и файл-серверной архитектуры. Этот инструментарий включает в себя настоящий компилятор кода и предоставляет средства визуального программирования, несколько похожие на те, что можно обнаружить в Microsoft Visual Basic или в других инструментах визуального проектирования. Лежащий в основе Delphi язык — Object Pascal, который является расширением объектно-ориентированного языка Pascal (Turbo/Borland Pascal, начиная с версии 5.5). В Delphi также входят локальный SQL-сервер InterBase 4.0, генераторы отчетов, библиотеки визуальных компонентов, и прочее хозяйство, необходимое для того, чтобы чувствовать себя совершенно уверенным при профессиональной разработке информационных систем или просто программ для Windows-среды. Поскольку в архитектуре клиент-сервер де-факто сложилось такое положение, что клиентские станции работают, как правило, в Windows-среде, а SQL-сервер — в операционной системе UNIX, Delphi Client-Server может служить удобным инструментом для скоростной разработки приложений.

2. Для кого предназначен Delphi?

Прежде всего профессиональным разработчикам, желающим очень быстро разрабатывать приложения в архитектуре клиент-сервер. Delphi производит небольшие по размерам (до 15-30 Кбайт в Delphi 3.x!) высокоэффективные исполняемые модули (.exe и .dll), поэтому в Delphi должны быть прежде всего заинтересованы те, кто разрабатывает продукты на продажу. С другой стороны небольшие по размерам и быстро исполняемые модули означают, что требования к клиентским рабочим местам существенно снижаются — это имеет немаловажное значение и для конечных пользователей. Помимо стандартных клиентских приложений (Delphi 1.0 и 2.0), Delphi 3.x также имеет средства для созданий приложений в многозвенной архитектуре.

3. Преимущества Delphi по сравнению с аналогичными программными продуктами.

• Быстрота разработки приложения.

• Высокая производительность разработанного приложения.

• Hизкие требования разработанного приложения к ресурсам компьютера.

• Hаращиваемость за счет встраивания новых компонент и инструментов в среду Delphi.

• Возможность разработки новых компонент и инструментов собственными средствами Delphi (существующие компоненты и инструменты доступны в исходниках)

• Удачная проработка иерархии объектов

• Де-факто уже доступно огромное количество визуальных компонентов третьих фирм, часть из которых freeware, часть shareware, часть — коммерческие.

4. Какие есть версии Delphi?

В феврале 1995 года была выпущена первая версия Delphi, которая генерировала код, исполняемый под операционной системой Windows 3.1x.

В начале февраля 1996 года объявлено о выходе второй версии продукта, которая генерирует уже 32-разрядный код для Windows 95 и Windows NT и использует все преимущества 32-разрядных приложений — более высокая скорость обработки данных, большее количество возможностей для приложения и др. Вторая версия Delphi предлагается уже в трех вариантах: Delphi Desktop, Delphi Developer и Delphi Client/Server Suite. Версии Desktop и Developer включают в себя Delphi Desktop 1.0, а Client/Server Suite — Delphi Client/Server 1.0.

В ближайшем будущем ожидается версия Delphi 3.0, которая также будет создавать 32-разрядные приложения со встроенной поддержкой стандартов COM/DCOM, ActiveX, улучшенными средствами работы с базами данных и т.д. Варианты поставки, судя по всему, будут аналогичны второй версии.

5. Сколько дискового пространства, памяти, и т.д., нужно для работы Delphi?

Минимальная установка Delphi 1.0 требует приблизительно 30 Мбайт на диске, и полная установки — 80 Мбайт. Чтобы Delphi работал хорошо, нужен 486 процессор с 8 Мбайт ОЗУ, хотя мы рекомендовали бы 16 Мбайт. Практика показывает, что скорость CPU не является критическим параметром.

Для 32-разрядных версий Delphi требования увеличиваются. Полная установка занимает чуть более 100 Мбайт, оперативной памяти желательно иметь не менее 16 Мбайт. 32 Мбайт ОЗУ достаточно, чтобы комфортно работать и отлаживать программы в Delphi, используя при этом загруженный на этой же машине Local Interbase.

6. Сколько занимает места программа, выводящая текст «Hello, World!», изготовленная на Delphi?

Меньше 170Кб, если имеется в виду программа, «собранная» обычным для Delphi способом. При этом сразу же подключается стандартная поддержка форм и пр. Тем не менее при помощи Паскаля, поддержимаемого Delphi, можно написать программу, которая ничем по своим качествам не будет отличаться от программы, написанной в BP7.0. (То есть размер такой программы может быть около 15Кб) Рекорд — 3.5 Кб!!

Но и это еще не все. Концепция пэкиджей (paсkages), введенная в Delphi 3.0, позволяет создавать программы, код которых будет составлять всего несколько килобайт + разделяемые между всеми приложениями библиотеки времени выполнения, оформленные в виде DLL.

7. Hасколько трудно научиться работе с Delphi?

Если вам повезло, то вы уже имеете большой опыт работы и с Borland Pascal With Objects, и с Visual Basic. Если вам подходит данное описание, тогда Delphi будет для вас сразу понятен. А теперь для остальных: Чтобы полностью использовать возможности среды Delphi, вы должны знать Pascal , вы должны иметь некоторые знания об объектно-ориентированном программировании и вы должны знать о программировании событий. Если вы преодолели эти три препятствия, то вы имеете все необходимые знания. С другой стороны , большинству людей не нужно полностью использовать все возможности среды. Если вы хотите создать приложение, которое не делает ничего особенно причудливого, то даже без особого программирования вы в течение 5-10 минут сможете собрать из визуальных компонент Delphi что-нибудь достаточно мощное и на удивление работоспособное.

Приложения, созданные в среде Delphi, отличаютя повышенной надежностью. Встроенные механизмы RTTI и обработки исключений вместе со строго типизированным языком Object Pascal изначально закладывают в программы устойчивость к всевозможным сбоям, которые могут произойти в операционной системе, на SQL-сервере или непосредственно в вашей программе. Даже ничего не делая самому, всегда можно как минимум узнать, что произошла ошибка и где, а зачастую и получить исчерпывающую дополнительную информацию. Во многом это заслуга и компилятора Borland с языка Pascal, история которого насчитывает более 13 лет.

8. Можно ли создавать многопользовательские приложения для баз данных в Delphi Desktop или Developer?

Используя Delphi Desktop 1.0 или Delphi Developer 2.0, можно разработать приложение, которое общается с каким-нибудь SQL сервером, используя ODBC драйвер. Hе было особых проблем, чтобы заставить работать ODBC, и скорость доступа к данным была вполне приемлема. Тем не менее те, кто уже успел опробовать оба варианта, в один голос утверждают, что через IDAPI работать быстрее. В Delphi Desktop 2.0 работа через ODBC не поддерживается.

9. Какова история появления Delphi?

Delphi — потомок Турбо-Паскаля , который впервые появился в 1983г для операционной системы CP/M . Турбо-Паскаль был перенесен в MS-DOS в начале 1984г. Hа протяжении всего начала истории IBM PC, Турбо-Паскаль был действительно наиболее популярным языком для серьезных разработок — главным образом потому, что это был настоящий компилятор, включающий редактор текстов программ и все необходимое, что стоило $19.95 и выполнялось на компьютере со 128 Кбайт. Borland представил Турбо-Паскаль для Windows в 1990г. Последней версией Borland Pascal (как это стало называться), не считая Delphi, был версии 7.0 в конце 1992г.

Delphi 1.0 разрабатывался что-то около 18 месяцев или двух лет. Выпускались различные beta-версии и пререлизы, включая несколько сотен копий, которые отдали во время выставки Software Development ’95. Delphi официально анонсирован в США 14 февраля 1995г, и первые копии были разосланы 28 февраля. В России Delphi появился в первых числах апреля, хотя ранее действовала программа раннего ознакомления (EEP) в рамках которой те, кто спешил начать осваивать новый продукт, получали бета-версию Delphi и пререлиз документации.

После выпуска первой версии продукта компания Borland направила свои усилия на перенос Delphi в 32-разрядные операционные системы — Windows 95 и Windows NT. Этот процесс успешно завершился и 10 февраля 1996г. Borland Intrenational объявил о выходе второй версии продукта, которая генерирует уже 32-разрядный код для Windows 95 и Windows NT и использует все преимущества 32-разрядных приложений — более высокая скорость обработки данных, большее количество возможностей для приложения и др.

На данный момент ожидается выход третьей версии Delphi, окончательный которой предположительно появится в конце весны-начале лета 1997г. На основании предварительных версий можно сказать, что Delphi 3.0 — это еще более мощный продукт, чем Delphi 2.0, который позволяет использовать в своих разработках все основные стандарты, имеющиеся на платформе Win32/Intel — ActiveX, COM/DCOM, ISAPI/NSAPI и т.д.

10. Где можно приобрести копию Delphi?

У любого дилера Borland, а сейчас Delphi Desktop продаются, кажется, даже в книжных магазинах. Тем не менее перед приобретением Delphi поинтересуйтесь, какую поддержку обеспечивает дилер. Delphi — это довольно большой продукт, и его поддержка всегда будет нелишней.

11. Приведите сравнение производительности IDAPI и других аналогичных продуктов.

Демо-центр такими исследованиями не занимался, в них не было ни интереса ни необходимости. Однако кто-то такие тесты проводил, например по данным Jin Mai (mwj@pipeline.com) на одной таблице с 60 тыс. записей производительность операции SELECT следующая [1] :

Инструмент Формат базы данных Время в секундах
Delphi Paradox 22
VB Access 60
Delphi ODBC to Access 30
Access ODBC to local Watcom 48
VB ODBC to local Watcom 33

Hесмотря на весьма странные данные во второй строке (VB/Access), автор тестов их подтверждает.

12. Как можно войти в контакт с представителями Borland?

Если вы имеете соответствующие возможности, вы можете получать информацию прямо из Borland:

• anonymous to ftp.borland.com.

Телефоны Borland АО — российского представительства Borland International:

(095)-366-4298

• (095)-366-3973

Вы можете поговорить с представителями Демо-центра по клиент-серверным технологиям Borland (компания Epsylon Technologies) по телефонам:

(095)-913-5608

• (095)-913-2934

• (095)-459-1333

• (095)-535-0319

• (095)-535-5349

Можете отправить письмо с вопросами по адресу:

13. Какую техническую поддержку может получить покупатель Delphi?

Можете звонить напрямую в Borland International, все необходимые адреса есть в сопроводительных документах в коробке с Delphi.

Можете направить письмо по электронной почте в Borland International по адресу techinfo@borland.com, однако следует отметить, что качество поддержки в большой степени зависит от дилера.

Hачала свою деятельность Ассоциация пользователей Delphi. В Борланд АО организованы семинары (пока бесплатные). Раз в две недели по средам с 14:00 до 16:00 проходит тематический семинар о Delphi и других продуктах Borland. Его проводят практические специалисты по Delphi из различных организаций, в том числе и из демо-центра. Даже если вы издалека, имеет смысл посетить семинар — наверняка вы услышите что-либо интересное для себя. Тематика семинаров — самая разнообразная.

Для того, чтобы попасть на семинар, надо позвонить в Демо-центр по телефону: 913-5608, и записаться на семинар.

Методические материалы для проведения таких семинаров сохраняются, так что тем, кто желает у себя в регионе организовать нечто подобное, звоните в Демо-центр Александру Сергееву.

14. Выйдет ли версия Delphi, где в качестве компилятора будет использоваться BC++?

Вопрос устарел. Такой продукт (Borland C++Builder) вышел 4 февраля 1997г. По своим возможностям он практически равноценен Dehlpi 2.0. Получить более подробную информацию о данном продукте вы можете получить на страничках нашего сервера, посвященных C++Builder.

15. Сколько стоит Delphi в России?

Полная стоимость текущих версий продукта составляет:

Delphi 1.02 Client/Server $
Delphi 1.02 for Windows (Desktop) $
Delphi 2.01 Client/Server Suite $
Delphi 2.0 Developer $
Delphi 2.0 Desktop $

Цены на Delphi 3.0 не объявлены (продукта пока нет), но предполагается, что они будут на уровне Delphi 2.0. Полный список цен на продукты, а также всевозможных вариантов Upgrade приведен в нашем прайс-листе.

16. Что можно, и чего нельзя разработать в среде Delphi? В частности, можно ли разработать в Delphi внутреннюю структуру данных для SQL-cервера, хранимые процедуры и пр.?

Понятно, что для такого открытого инструмента, как Delphi, границы «дозволенного» весьма условны. В частности, хороший пример — появление в более поздних версиях визуального компонента для работы с хранимыми процедурами. То есть это было нельзя для FieldTest 4 и стало возможным для пререлиза.

Второй пример, который появился только с версии 1.15 Delphi FAQ. В стандартной поставке Delphi не существует визуального компонента, поддерживающего обработку event alerts (событий) в InterBase. Тем не менее оказалось, что изготовить такой компонент не так уж и трудно. В Delphi 2.0 есть пример аналогичного компонента, который на самом деле оказался весьма кривым и потребовал существенной доработки для возможности нормального использования.

Вышли компоненты, позволяющие проводить процедуру инсталляции разработанного вами приложения, проводить сетевой обмен, обмениваться данными через cc:mail или Lotus Notes.

Появились компоненты, реализующие прямые линки к BTrieve, AS/400, мэйнфреймам, Informix.

17. Чем можно воспользоваться для создания инсталляционных версий приложений, разработанных в Delphi?

Для Delphi 1.0 можно, например, попробовать:

1. Wise. Он неплохо подходит и для VB, и для BC++.

2. Kurt. Создает иконы, меняет INI, распаковывает сжатые файлы.

3. Существует несколько компонентов, которые помогают в создании инсталляторов и Shareware-версий продукта. Однако, последнее время практически стандартом стал инсталлятор InstallShield . Его 32-разрядный вариант для Delphi ( InstallShield Express for Delphi ) входит в стандартную поставку всех версий Delphi 2.0.

18. Должен ли я знать все относительно Windows API, чтобы использовать Delphi?

Может возникнуть чувство, что вы должны знать относительно Windows API в Delphi больше, нежели в Visual Basic. Это не так; вы можете работать в обеих средах с минимальным пониманием внутренней организации Windows. Однако, в обоих случаях, вы должны знать, по крайней мере, кое-что относительно Windows API, чтобы «выжать» максимум из того, что у вас есть. Различие в том, что Delphi предоставляет вам гораздо больше возможностей, чтобы делать все эти интересные вещи.

19. Должен ли я знать объектно-ориентированное программирование, чтобы использовать Delphi?

Хорошо бы. Инструментальные средства проектирования интерфейса пользователя Delphi производят объектно-ориентированный код. Однако, если вы знакомы с Visual Basic или Powerbuilder, вы, вероятно, имеете достаточное понимание OOP (Object Oriented Programming). Вы можете сделать многое в Delphi без необходимости создавать ваши собственные объекты; но при создании новых объектов действительно важно знать тонкости OOP.

Совместимость

1. Какие операционные системы Delphi поддерживает?

Версия Delphi 1.0 предназначается для Windows 3.1x. Hет причин, по которым Delphi 1.0 не работал бы в системах, которые обеспечивают эмуляцию Windows 3.1, подобно OS/2 Warp, Windows NT, UnixWare 2.0 и т.д.

Delphi 2.0 предназначена для работы под Win32/Intel — на данный момент это Windows 95 (в т.ч. OSR2), Windows NT (3.5 и 4.0).

Delphi 3.0 также работает под Win32, но на данный момент некоторые возможности, предоставляемые продуктом можно использовать только в ОС Windows NT 4.0. Возможно, очередная версия Windows 95 (Windows 97), будет обладать этими функциями.

2. Какие средства управления проектом совместимы с Delphi?

Delphi 1.0 Client/Server поддерживает совместимость с PVCS компании InterSolv.

Delphi 2.0 Client/Server Suite включает в себя комплект PVCS, интегрированный в IDE.

Кроме того, должна быть возможность совмещения с большинством систем контроля исходных текстов. Однако, формы в Delphi сохраняются в двоичном формате, так что пакет управления исходными текстами должен поддерживать двоичные данные для того, чтобы это работало с Delphi . Если у вас есть администратор исходных текстов, который просто не может иметь дело с двоичными файлами, то согласно документам, вы может сохранять формы в виде ASCII текста для редактирования или в целях контроля за версиями. Файлы ASCII могут также загружаться и снова сохраняться в двоичном *.DFM формате.

MKS Source Integrity (MKS SI — 2-ой на рынке администраторов исходного текста для PC/PCLAN с более чем 35,000 разработчиками, использующими SI) также предлагает средства интеграции в Delphi. Эти средства в настоящее время поставляются наряду с MKS SI.

3. Можно ли в Delphi использовать DLL, разработанные в C или C ++?

Delphi способен вызывать и получать обратные вызовы (callback) из любого стандартного модуля DLL для Windows.

4. Можно ли вызывать код, созданный в Delphi из C или C ++?

Delphi может генерировать DLL, которые можно вызывать из C, C++, Visual Basic, PowerBuilder, или чего-нибудь еще, что понимает стандартные Windows DLL. Имеется пример DLL в каталоге DEMOS\DB\DLL из комплекта Delphi.

5. Что известно о пакетах других фирм, которые работают (или не работают) с Delphi?

6. Есть ли поддержка Dynamic Data Exchange (DDE), VBX, OLE, OCX, OpenDoc?

Да, Delphi позволяет с разной степенью комфорта использовать все технологические стандарты, имеющиеся в Windows.

7. Можно ли на Delphi написать VBX или OCX?

Можно. Ведь по сути дела VBX — это .dll, написанная по определенным правилам. Однако скорее всего вам потребуется дополнительно соответствующий SDK от компании Microsoft. Существует даже статья, где обсуждаются все аспекты такой работы.

Относительно OCX все то же самое, что и относительно VBX.

Delphi 3.0 позволяет визуально создавать элементы ActiveX.

8. Какие генераторы отчетов можно использовать с Delphi кроме ReportSmith?

В порядке предпочтения:

1. Имеется QuickReport — генератор отчетов, сделанный в виде компонентов и встраиваемый непосредственно в приложение. Успех 16-разрядной версии привел к тому, что начиная с версии Delphi 2.0 32-разрядный QuickReport входит в стандартный вариант поставки.

2. Crystal Reports — подключается через VBX.

3. R&R Report Writer — хорошо работает с Delphi, позволяет выполнять запросы, preview, вызовы DLL, передачу параметров. (производитель — Concentric Data Systems)

4. Также есть еще несколько генераторов отчетов, выполненных аналогично QuickReport в виде компонентов.

Следует также заметить, что на данный момент Borland International продал ReportSmith другой фирме, так что его присутствие в Delphi 3.0 под вопросом.

Базы данных — Interbase и локальные данные

1. Каково определение IDAPI? Что такое SQL Links?

IDAPI это Integrated Database Application Program Interface. BDE (Borland Database Engine) — средство доступа ко множеству источников данных через один API. IDAPI — это просто API для BDE. IDAPI включает все функции, необходимые для доступа к данным, манипулирования ими и т.д. Delphi, Borland C++, C++Builder, Intrabulder, dBASE for Windows, и Paradox for Windows используют эти функции. Вы можете использовать их в своих программах. Вы получите документацию, если купите BDE. Там перечислены все доступные функции и что они делают. Если посмотреть на исходники VCL в Delphi, то можно увидеть, как они используются. Они начинаются с «Dbi» (e.g. DbiCreateTable ).

SQL Links — набор родных драйверов (native drivers), которые нужны для работы с удаленными серверами баз данных.

2. Hеобходим ли IDAPI для доступа к данным в Delphi? Можно ли включить IDAPI внутрь EXE, чтобы распространять программу без установки IDAPI на пользовательском компьютере?

IDAPI необходим для доступа к данным в Delphi. Сам IDAPI во внутрь исполняемого файла ни коим образом не встраивается (да это было бы и не целесообразно). Вместе с Delphi поставляется редистрибутивный вариант BDE, которая устанавливает на «чистую» машину лишь только BDE. может создавать инсталляторы, которые устанавливают на машину как ваше приложение, так и BDE.

InstallShield Express for Delphi

Delphi 3.0 включает средства для создания «тонких» клиентов, работающих на машине, на которой не установлен BDE. Подробности смотрите в FAQ по Delphi 3.0.

3. Где можно найти описание функций и типов данных BDE?

DBIPROCS.INT в директории DELPHI\DOC\ содержит список функций BDE, передаваемые параметры, возвращаемое значение и краткое описание каждой. DBITYPES.INT — список типов, используемых функциями BDE. Для вызова любой функции BDE добавьте следующие модули в раздел uses: DBITYPES, DBIPROCS и DBIERRS.

Delphi 2.0 включает в себе описание функций BDE в формате WinHelp. Также все три модуля из Delphi 1.0 (DBITYPES.DCU, DBIPROCS.DCU и DBIERRS.DCU) теперь объединены в единый BDE.DCU.

4. Можно ли программным образом добавить псевдоним (alias) в IDAPI.CFG?

В BDE есть для этого функция DbiAddAlias .

В Delphi 2.0 данная функциональность находится внутри компонента TSession (методы AddAlias , AddStandardAlias ).

5. Я получаю сообщение от BDE при редактировании записи ‘Multiple records found but only one expected’. Что бы это значило?

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

6. Обработка исключений (exceptions) BDE.

Информация об ошибке BDE может быть получена для использования в приложении из объекта EDBEngineError . Исключительная ситуация EDBEngineError обрабатывается в программе с помощью конструкции try … except. Когда возникает исключительная ситуация BDE, то может быть создан объект EDBEngineError и различные поля этого объекта могут быть использованы для программного определения, что не в порядке и что требуется для исправления ситуации. Далее, для данной исключительной ситуации может быть сгенерировано несколько сообщений об ошибках. Это требует организации перебора сообщений об ошибках для получения нужной информации.

7. Какому стандарту SQL соответствует SQL в InterBase?

SQL в Local & Remote InterBase соответствует SQL-92 с элементам SQL III (более поздними расширениями).

8. Как удалить генераторы (GENERATORS) из базы данных InterBase?

Никак. К сожалению, в существующих версиях InterBase это невозможно.

9. Как выбрать протокол при соединении с InterBase из Delphi?

В Server Manager (ibmgr.exe), Windows interactive SQL (wisql.exe) и Communication Diagnostic Tool (comdiag.exe) Вы отдельно задаете имя сервера, протокол и ‘путь на базу’ (локальный путь на сервере, а не путь до базы с Вашей машины)

А в BDE Configuration Utility все немного не так — на странице Drivers у драйвера Interbase есть параметр SERVER NAME, заполненный как IB_SERVER:/PATH/DATABASE.GDB, а у любого InterBase Alias есть параметры SERVER NAME и PATH, но ни у драйвера ни у алиаса нет протокола. Для Interbase протокол указывается стилем написания пути к базе:

Протокол SERVER NAME Пример
TCP/IP IB_SERVER:PATH\DATABASE.GDB nt:c:\ib\base.gdb; unix:/ib/base.gdb
IPX/SPX IB_SERVER@PATH\DATABASE.GDB nw@sys:ib\base.gdb
NETBEUI \\IB_SERVER\PATH\DATABASE.GDB \\nt\c:\ib\base.gdb

10. Можно ли использовать какие-нибудь ODBC драйверы, которые получены с другими СУБД?

В общем, да. Мы не столкнулись с какими-то ODBC драйверами, которые не работают с Delphi, но, с другой стороны, мы не пробовали действительно экзотические драйверы. Основные трудности вызвали специфические ODBC-драйверы от Microsoft. Похоже, что ODBC и ODBC от Microsoft — это разные вещи.

11. Проблемы с именами таблиц в ODBC-драйверах.

При использовании ODBC-драйверов, если у вас появляются ошибки при открытии таблицы — установите порядок сортировки (SORT ORDER) хотя-бы Paradox ASCIIi. Это, например, помогает при доступе к базам данных Lotus Notes (ODBC-драйвер фирмы Casahl).

12. Какой формат данных предпочесть в Delphi? dBase или Paradox?

Если вам действительно все равно, то вот несколько пунктов ‘за’ формат Paradox:

1. Широкий выбор типов полей, включая автоинкремент, BLOBs, и т.п.

2. Соблюдение целостности данных, контроля данных, обновления индексов на уровне ядра BDE.

3. Первичный индекс таблицы автоматически соблюдает уникальность записей, вторичные индексы обеспечивают отсортированный «вид» на записи таблицы.

13. Как нужно писать функцию «change password» для таблицы Парадокса?

Нет способа сделать это в пределах Delphi VCL. Кажется, это довольно серьезное упущение. Однако, есть возможность сделать это напрямую через Borland Database Engine через интерфейс предоставляемый модулями DBIPROCS.DCU и DBITYPES.DCU () или BDE.DCU (). Нужно использовать функцию DbiDoRestructure .

14. Есть ли какая-нибудь процедура для перестройки разрушенного индекса, типа TUTILITY.EXE из PdoxWin?

BDE включает функцию для этого — DbiRegenIndexes .

15. Есть ли какая-нибудь процедура для упаковки таблицы dBase?

В BDE есть функция DbiPackTable .

16. Как для .dbf таблицы создать индекс по выражению?

Нужно использовать процедуру AddIndex с параметром ixExpression , например:

Table1.AddIndex(‘NewIndex’,‘Field1 * Field2 + Field3’, [ixExpression]);

17. Как создать в Paradox вторичный индекс с упорядочиванием по убыванию?

Используйте флаг ixDescending :

Table1.AddIndex(‘NewIndex’, ‘CustNo;CustName’, [ixDescending]);

18. Хочу узнать номер текущей записи, как это сделать?

В общем случае — никак. В случае таблицы Paradox — есть в BDE функция DbiGetSeqNo , которая возвращает логический номер записи. Но при использовании на форме TDBGrid она может давать не всегда правильные значения.

19. Как посмотреть удаленные записи в таблице .dbf? А как их восстановить?

Для того, чтобы удаленные записи были доступны, нужно установить соответствующее свойство для курсора с помощью функции BDE DbiSetProp :

DbiSetProp(hObj(Table1.Handle), curSoftDeleteOn, 1);

Проверка удалена запись или нет производится через функцию чтения записи DbiGetRecord . Для восстановления записи применяется функция DbiUndeleteRecord .

20. Упаковка таблицы.

Упаковать таблицу DBF можно открыв ее компонентом TTable и вызвав функцию BDE DbiPackTable :

Result := DbiPackTable(Table1.DbHandle, Table1.Handle, nil, szDBase, True);

21. Почему я получаю ошибку ‘Index out of range’ когда использую TTable.FindNearest и TTable.FindKey для таблицы dBase с индексом по выражению?

Методы TTable.FindKey и TTable.FindNearest не могут работать с таким видом индексов. Вместо этих методов используйте TTable.GotoKey и TTable.GotoNearest , которые прекрасно работают с ними.

22. Как программным образом создать таблицу Paradox с автоинкрементным полем?

Вам следует использовать компонент TQuery и SQL-предложение типа:

CREATE TABLE «PDoxTbl.db» (ID AUTOINC, Name CHAR(255), PRIMARY KEY(ID));

23. Почему я не могу использовать опцию ixUnique при создании индекса в таблице Paradox с помощью метода AddIndex компонента TTable?

Опции, используемые в методе AddIndex компонента TTable зависят от типа таблиц. Например, опция ixUnique работает с таблицей dBase, но не с Paradox. Следующая таблица показывает, как эти опции используются для таблиц dBase и Paradox.

Index Options dBase Paradox
ixUnique *
ixExpression *
ixDescending * *
ixNonMaintained * *
ixPrimary *
ixCaseInsensitive *

24. Генерация уникальных идентификаторов для таблиц.

Для более полного ознакомления с этим вопросом рекомендуется обратится к статье Максима Михеенкова в 1-ом номере российского журнала СУБД за 1995 год. А коротко можно сказать следующее.

Для таблиц Paradox вы можете пользоваться специальными типами полей, гарантирующими уникальность значения поля в записи — типы AutoIncrement и TimeStamp (с использованием функций DateXXX — модуль SysUtils).

Для Interbase вы можете использовать генераторы, которые возвращают уникальное значение.

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

25. Можно ли использовать Crystal Report с таблицами формата Paradox 5.0?

Да, можно, только если вам удастся получить ODBC-драйвер для таблиц Paradox. Во всяком случае на Crystal BBS находится файл bde.zip, который и содержит этот драйвер.

26. Как открыть таблицу dBase, у которой поврежден (утерян) индексный MDX файл?

Как я могу использовать таблицу dBase без необходимого для нее MDX файла?

При создании таблицы dBASE с индексным файлом MDX в заголовке DBF файла устанавливается байт со смещением 28 (десятичное) от начала файла. При открытии таблицы, у которой данный байт установлен, также происходит попытка открыть MDX файл; если это не удается, то возникает исключение (exception). Для решения проблемы достаточно прописать в DBF файл 0 по указанному смещению.

27. Как определить номер текущей записи для набора данных?

Если набор данных основан на таблицах Paradox или dBASE, то номер записи можно определить с помощью вызовов BDE. BDE не поддерживает номер записи для наборов данных на SQL сервере; если ваш сервер поддерживает нумерацию записей, вам нужно обратиться к его документации.

Базы данных — прочие SQL сервера

1. Как осуществляется доступ к базе данных из Delphi?

Сначала вы должны в утилите BDE Configuration Utility (bdecfg или bdecfg32) определить псевдоним для базы данных, с которой вы хотите работать. Это позволит вам избежать написания сложного пути к базе данных в вашем приложении; вы теперь только ссылаетесь на псевдоним. Затем вы создаете минимум три объекта на форме: TTable или TQuery , который фактически общается с базой данных через псевдоним и получает данные; объект TDataSource , который связывает данные и визуальные компоненты; по крайней мере один компонент, отображающий данные.

Если вы потратили несколько часов, чтобы заставить все это работать, но ничего не получилось, попробуйте установить свойство Active у TTable или TQuery в True . Это откроет таблицу в базе данных.

2. Какие серверы данных поддерживает Delphi?

Delphi (в старших вариантах поставки) напрямую работает с Oracle, Informix, InterBase, DB/2, Sybase, MS SQL Server. Вы можете использовать ODBC драйверы третьих фирм, чтобы работать с любым сервером. Наиболее известные производители качественных ODBC драйверов:

Есть специализированный вариант Delphi 2.0 — Delphi/400, который ориентирован исключительно на работу с AS/400.

3. Cуществует ли способ работать из Delphi с AS/400, исключая ODBC?

В состав Delphi 1.0 не входит, но доступен отдельно визуальный 16-разрядный компонент компании Gerald Limited.

Есть специализированный вариант Delphi 2.0 — Delphi/400, который ориентирован исключительно на работу с AS/400.

4. Cуществует ли способ работать из Delphi с Lotus Notes (IBM Notes), за исключением ODBC?

Существует только 16-разрядный линк для Notes. В состав Delphi он не входит (разработан компанией Brainstorm) и поставляется отдельно по каналам Borland. Спрашивайте дилеров Borland.

5. Можно ли создавать с помощью Delphi сетевые приложения не для схемы клиент-сервер, а для схемы с разделяемыми файлами (как, например, в FoxPro)?

Компонент TTable имеет свойство Exclusive ; если Exclusive=False , то одну и ту же таблицу могут просматривать и редактировать несколько пользователей. При редактировании таблицы текущая запись автоматически блокируется. Если есть необходимость заблокировать несколько записей или всю таблицу, то для этого придется использовать функции BDE — модуль DBIPROCS (

). Кстати, существенно, что это можно делать и на Delphi Desktop — отсюда вывод: сетевые приложения (в файл-серверной архитектуре) можно делать и на Delphi Desktop.

6. Можно ли работать при помощи Delphi не с IDAPI — или ODBC-драйверами, а с «родными» API каких-либо СУБД?

Да, можно. Это еще один пример открытости Delphi. В одном из проектов Демо-центра появилась необходимость прямого обращения к API SQL-сервера. Был написан соответствующий интерфейс поверх Borland InterBase API — и все заработало. Аналогично: существуют написанные компоненты для работы с AS/400 и для мэйнфреймов.

7. Какие версии Informix (Online, I-NET) поддерживают SQL Links?

BDE версии до 2.51 поддерживает работу с клиентской частью Informix ESQL/C I*NET 4.x. BDE версии 2.51-2.52 поддерживается ESQL/C I*NET 5.x.

32 SQL Link версии 3.5 и выше поддерживает ESQL/C I*NET 7.x.

8. Как работать с таблицами в виде текстовых файлов (ASCII)?

Информацию об этом вы можете найти в каталоге DELPHI\DOC. Файл называется ASCIIDRV.TXT.

9. Как правильно указать имя сервера Oracle?

Пишите имя по правилам Oracle — перед именем не забудьте поставить @.

10. Что такое транзакции (Transactions)?

SQL database серверы обрабатывают запросы в ‘логических единицах работы’ которые и называются транзакциями. То есть транзакция — это группа связанных операций (SQL запросов) которые все должны быть выполнены успешно перед тем, как сервер закончит (commit) изменение базы данных. Либо вся это группа будет выполнена, либо нет. Транзакции обеспечивают целостность базы данных …

11. Как в Delphi управлять транзакциями?

В Delphi может управлять транзакции так:

1. Implicitly — сам стартует и коммитит транзакции по необходимости, когда программа вызывает метод Post .

2. Explicitly

1. StartTransaction , Commit & RollBack методы TDatabase .

2. При помощи SQL запросов через TQuery — это зависит от конкретного SQL сервера.

Неявные (1) транзакции выполняют TTable & TQuery .

Для явных (2.1) транзакций требуется TDatabase .

Для явных (2.2) транзакций требуется TQuery .

Важно:

При определении параметров драйвера SQLPASSTHRU MODE — определяет будут ли passthrough SQL (PSQL) & стандартные вызовы BDE (BDEC) использовать один и тот же connect к SQL серверу.

1. NOT SHARED — PSQL & BDEC используют разные соединения с базой и следовательно влияют (интерферируют) друг на друга также как разные пользователи одной базы (см. Transaction isolation levels)

1. SHARED AUTOCOMMIT — PSQL & BDEC используют одно соединение с базой, каждый PSQL запрос автоматически коммитятся.

2. SHARED NOAUTOCOMMIT — PSQL & BDEC используют одно соединение с базой, PSQL запросы коммитятся ‘вручную’ (способом 2.1).

Еще важнее:

Если Вы все-таки решили управлять транзакциями при помощи SQL запросов через TQuery , то SQLPASSTHRU MODE должно быть NOT SHARED, иначе Implicit & Explicit транзакции могут влиять друг на друга и привести к ‘неожиданным результатам’!

12. Использование формата Access 2.0 в Delphi.

Подробное описание подключения:

• Откройте Windows Control Panel, откройте икону ODBC.

• Добавьте драйвер Access в список доступных, если он не указан в списке текущих драйверов.

• Укажите какое-либо имя в «Data Source Name».

• Выберите файл БД кнопкой Select Database.

• Если вы хотите создать новый — выполните пункт Create Database

• Запустите Database Engine Configuration

• Нажмите кнопку New ODBC Driver

• Выберите драйвер типа ACCESS DATA

• В качестве Default Data Source Name выберите предложенное.

• Создайте новый псевдоним в разделе Alias

• Укажите тип драйвера, путь и имя к нужному файлу БД Access.

• Сохраните изменения и закройте Database Engine Configuration

Примечание: избегайте русских названий имен таблиц, использования пробела в именах таблиц, а также русских имен полей в DB Access.

13. Можно ли при помощи Delphi реализовывать проекты, не имеющие отношения к базам данных? Если да, то имеет ли это смысл?

В таком случае стоит воспользоваться вариантом Delphi Desktop или Developer. Выигрыш по скорости разработки очевидно будет значительным; в частности, разработка интерфейса программы под Windows производится действительно скоростными методами. Хороший пример — Screen Saver для Windows.

Общие вопросы по Delphi и данному FAQ (часть 2)
Базы данных — компоненты и VCL.

1. Какие визуальные компоненты для работы с данными входят в Delphi?

Различные версии Delphi содержат следующие наборы компонентов:

Компоненты Краткое описание Версии Delphi
TDBGrid Представление данных в виде таблицы (очень сложный и наиболее популярный компонент) 1 2 3
TDBEdit Редактирования одного поля 1 2 3
TDBNavigator Как видно из названия, компонент позволяет перемещаться по таблице 1 2 3
TDBLabel Статическое отображение содержимого поля 1 2 3
TDBMemo Редактирования текста в поле типа BLOB 1 2 3
TDBImage Отображение картинок из BLOB-а 1 2 3
TDBRadioGroup, TDBCheckBox Дополнительные средства отображения данных 1 2 3
TDBComboBox, TDBListBox Упрощают ввод данных, предлагая несколько заранее определенных вариантов 1 2 3
TDBLookupListBox, TDBLookupComboBox То же самое, но возможные варианты выбираются из другой таблички 1 2 3
TDBCtrlGrid Вариант представления записей с произвольным расположением полей 2 3
TDBChart Компонент для построение графиков и диаграмм на основании данных, хранящихся в таблице 3
TDecisionGrid, TDecisionChart Компоненты для поддержки принятия решений 3

2. Использование псевдонимов в запросе SQL.

Я делаю запрос по двум таблицам разных форматов, находящихся по разным псевдонимам.

SELECT DB1.Column1, DB2.Column2 FROM :Alias1:DB1, :Alias2:DB2

но в результате получаю ошибку ‘неизвестный тип поля «Alias1:DB1″‘

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

SELECT D1.Column1, D2.Column2 FROM «:Alias1:DB1» D1, «:Alias2:DB2» D2

Вообще экспериментировать с SQL-запросами проще следующим образом — создайте запрос QBE, настройте его так, как вам нужно, а затем оттранслируйте его в SQL. В результате вы получите правильный текст нужного вам SQL-запроса. Владельцы Delphi Client/Server могут использовать также и Visual Query Builder. Однако, не все QBE-запросы могут быть оттранслированы в SQL.

3. Ошибка в SQL запросе.

У меня есть TQuery и TDataSource . В свойстве SQL для TQuery я пишу

SELECT * FROM dbo.AnyTable

база данных на MS SQL Server. Когда я устанавливаю Active в True , то получаю ошибку: ‘Token not found. Token :dbo. line number:1’ . Что не так?

Если свойство RequestLive=True , то имя таблицы нужно брать в кавычки:

SELECT * FROM «dbo.table»

Если свойство RequestLive=False , кавычек не требуется:

SELECT * FROM dbo.table

4. Проблемы при работе с MS Access через TQuery.

Я безуспешно пытался использовать данные из Microsoft Access иначе, нежели просто с помощью TTable . Используя TQuery я могу только читать результат, но не могу редактировать. После «login screen» возникает сообщение типа ‘Passthrough SQL connection must be shared’ .

Измените в настройке псевдонима (alias) пункт ‘SQLPASSTHRU MODE’ на ‘SHARED AUTOCOMMIT’.

5. Как создать таблицу при помощи SQL (или почему не работает TQuery.Open)?

TQuery.Open возвращает результат в виде курсора, в связи с этим он работает только для тех выражений, которые возвращают курсор. CREATE TABLE возвращает только результат операции — поэтому для выполнения этого выражения необходимо использовать TQuery.ExecSQL . Но и это может не сработать, если конкретный драйвер БД не поддерживает операцию создания таблиц — для получения характеристик драйвера используйте функции BDE ( DbiOpenDriverList , DbiGetDriverDesc ).

6. Возврат значения select max() и подобных SQL-выражений.

Я хочу выполнить SQL-выражение и получить результат в свою переменную, что-то типа

SELECT MAV(FieldA) FROM TableB INTO :VariableC;

Вам не нужно использовать оператор INTO для программного доступа к результату — его можно получить используя свойства Fields или FieldByName соответствующего компонента TQuery .

TQuery1.Add(‘ SELECT MAX(FiledA) FROM TableB ‘);

Или, если результат нужно визуально отобразить, достаточно подключить к используемому TQuery компоненты TDataSource и TDBText .

7. Автоматический подсчет сумм при помощи TQuery.

Меня интересует возможность подсчета суммы по таблицам, которые уже находятся на форме.

Есть очень простой способ — предположим, что у вас есть на форме Query1 , DataSource1 , DBGrid1 . Добавьте на эту же форму компоненты Query2 , DataSource2 , DBText1 . Установите property Query2.DataSource=DataSource1 . В Query2.SQL напишите

SELECT SUM(FieldName) FROM TableName

где TableName — имя той же таблицы что и у Query1 , а FieldName — имя столбца по которому производится подсуммирование. Далее свяжите между собой Query2 , DataSource2 и DBText1 .

При изменении Query1 (если конечно Query1.RequestLive=True ) Query2 будет автоматически перевыполняться. Это решение хоть и простое, но неэкономичное — особенно при большом количестве записей в исходной таблице. Более того, запрос Query2 должен иметь WHERE идентичный Query1 .

Для подсчета сумм правильнее использовать событие TQuery.OnCalcFields . Хорошим примером является X:\DELPHI\DEMOS\DB\MASTAPP\MASTAPP.DPR.

8. Использование кавычек в параметризированном запросе.

Мой запрос получает параметр. Проблема в том, что строка параметра содержит » (двойную кавычку), которая приводит к Runtime Error.

Вам необходимо использовать динамический SQL-запрос, иначе при указании например

WHERE TABLE.FIELD = ‘let»ter’

вы получите ошибку.

9. Как создать отдельный компонент TTable?

Легко и просто — точно также как и обычный компонент. При этом в качестве параметра конструктору можно передавать значение nil.

var

begin

MyTable := TTable.Create(nil);

try

MyTable.DatabaseName := ‘MyDB’;

MyTable.TableName := ‘MyTable.db’;

Mytable.IndexName := ‘MyIndex’;

finally

end;

end;

10. Как узнать, какая ячейка при просмотре TDBGrid текущая?

Здесь процедура для сохранения текущего номера строки и колонки. Следующий код в методе MyDBGridDrawDataCell обновляет переменные Col и Row (которые не должны быть локальными для этого метода) каждый раз, когда таблица перерисовывается. Используя этот код, вы можете считать, что Col и Row указывают на текущую колонку и строку соответственно.

var

Col, Row: Integer;

procedure TForm1.MyDBGridDrawDataCell(Sender: TObject; const Rect: TRect;

Field: TField; State: TGridDrawState);

var

begin

if gdFocused in State then

begin

RowHeight := Rect.Bottom — Rect.Top;

Row := (Rect.Top div RowHeight) — 1;

end;

end;

11. Как выделить цветом текущую строку в TDBGrid?

Для TDBGrid в свойстве Options установите dgRowSelect в True .

12. Как изменить цвет ячейки в TDBGrid?

Введите следующий код в обработчике события OnDrawDataCell :

procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;

Field: TField; State: TGridDrawState);

begin

if gdFocused in State then

with (Sender as TDBGrid).Canvas do

begin

TextOut(Rect.Left, Rect.Top, Field.AsString);

end;

end;

Установите свойство DefaultDrawing в True . Здесь перерисовывается только выделенная ячейка. Если установить DefaultDrawing в False , то вы должны самостоятельно перерисовать все ячейки аналогично примеру.

13. Как узнать, что пользователь перешел на другую запись, например, в TDBGrid?

Переход на новую запись — это событие, которое относится не к визуальному компоненту, а к источнику данных. Соответствующее событие называется OnDataChange и имеется у компонента TDataSource .

14. Как устанавливать собственный цвет или шрифт для столбца TDBGrid?

Выключите property DefaultDrawing , и обрабатывайте событие OnDrawDataCell :

procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;

Field: TField; State: TGridDrawState);

begin

if Field.FieldName = ‘Name’ then DBGr >

DBGrid1.DefaultDrawDataCell(Rect, Field, State);

end;

Это приведет к тому, что содержимое столбца ‘Name’ будет показываться жирным шрифтом.

В Delphi 2.0 вы можете использовать редактор столбцов для той же самой цели.

15. Почему указатель ползунка в TDBGrid не показывает текущее положение в таблице?

Дело в том, что TDBGrid предполагает многопользовательский доступ к таблице. В этом случае другие пользователи этой же таблицы могут добавлять или удалять записи, в результате информация о количестве записей на текущий момент становится неопределенной.

Конечно, в однопользовательском варианте количество записей всегда известно, но поскольку TDBGrid работает через промежуточный источник данных DataSource , ему неизвестен конкретный способ доступа к данным — навигационный или SQL. Например, для SQL существует только один способ узнать количество записей — выполнить специальный запрос с их подсчетом, а на это может потребоваться значительное время.

По всем этим причинам TDBGrid является универсальным средством для просмотра таблиц, которое работает во всех случаях и с любыми источниками данных.

16. Как установить фокус на определенное поле в TDBGrid?

17. Как создать обработчик события OnClick для TDBGrid?

Как и всякий TControl (иерархия наследования TControlв†’TWinControlв†’TCustomControlв†’TCustomGridв†’TCustomDBGridв†’TDBGrid ) у TDBGrid есть событие OnClick , но оно protected. Так что можно либо создать новый класс, производный от TDBGrid , в котором объявить это свойство как published, либо использовать другой вариант. Например, вы можете использовать событие OnColEnter .

18. Как создать маску для TDBEdit?

Маска относится к полю в таблице (компонент TField ) а не к самому TDBEdit . Дважды щелкните мышкой на TTable и в FieldEditor’е добавьте все нужные вам поля. Когда поле выбрано в списке, его свойства показаны в Object Inspector, включая маску ввода. Связывание TDBEdit и любых других компонентов с этим TTable будет вызывать наложение маски на соответствующее поле.

19. Хотелось бы иметь для OLE объектов, сохраненных в базе данных, компонент вроде TDBImage.

В стандартном наборе такого компонента действительно нет. Возможно, кто-нибудь скоро напишет что-нибудь в этом роде. В принципе, можно обойтись и без данного компонента. Например, есть табличка .db с BLOB полем для OLE объекта. При движении по записям можно OLE сохранять в базе, уничтожать, создавать новый, считывать из базы.

• создать поток, связанный с BLOB полем

• для OLE контейнера выполнить чтение/запись с потоком ( SaveToStream и LoadFromStream )

Естественно, OLE объект должен быть Embedded.

20. Что нужно сделать, чтобы при открытии запароленной таблицы не появлялся диалог запроса пароля?

Просто дайте этот пароль объекту Session перед открытием таблицы:

Session.AddPassword(‘PASSWORD’);

После закрытия таблицы, пароль можно удалить RemovePassword(‘PASSWORD’) , можно удалить все пароли: RemoveAllPasswords .

Если ваш компонент доступа к данным ( TTable или TQuery ) связан с сессий, отличной от той, которая выставляется по умолчанию, то добавлять пароль нужно именно у этого компонента TSession .

21. Как определить реальный размер поля типа BLOB, которое сохранено в таблице?

Ниже приведена функция GetBlobSize , которая возвращает размер данного BLOB или MEMO поля.

function GetBlobSize(Field: TBlobField): Longint;

begin

with TBlobStream.Create(Field, bmRead) do

try

Result := Seek(0, 2);

finally

end;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

end;

22. Как осуществить поиск по неиндексированному полю в таблице?

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

Locate(Table1, Table1LName, ‘Beman’);

Table1 — компонент TTable , Table1LName — TField , который вы добавили с помощью Fields Editor и ‘Beman’ — имя, которое вы хотите найти.

23. Как узнать, что изменилась текущая запись?

Событие TDataSource.OnDataChange когда State=dsBrowse .

24. Как считать даты для вычисляемых полей?

При вычислении дат важно удостовериться в том, что все используемые значения подходят по типу. В документации не совсем явно отражен тот факт, что на самом деле тип TDataTime эквивалентен типу Double , который можно использовать далее.

В примере, D1 и D2 (поля в Table1 ) могут быть типа или Date , или TDateTime , а D3 — поле типа Integer .

procedure TForm1.Table1CalcFields(DataSet: TDataset);

var

T1, T2: TDateTime;

begin

Table1D3.AsInteger := Trunc(Double(T1) — Double(T2));

end;

Компоненты и VCL

1. Почему возникает ошибка компиляции при обращении к объекту Sender в обработчике события?

Я в обработчике события OnChange для компонента TEdit пытаюсь получить содержимое его текстового буфера. Однако, следующая конструкция вызывает ошибку компиляции ‘неизвестный идентификатор’:

Если вы рассматривали декларацию, объект Sender имеет тип TObject , который является классом, который наследуется почти всеми остальными объектами. Вы, вероятно, пробуете обращаться к свойству, которое не определено в TObject , вроде Text или Caption . По этой причине, выражение Sender.Text вызовет ошибку, но если (для примера) вы знаете, что Sender имеет тип TEdit, тогда вы можете использовать выражение:


Caption := (Sender as TEdit).Text;

Если вы не уверены, что объект Sender будет всегда иметь данный тип, то рекомендуется предварительно проверить это:

if Sender is TEdit then

2. Проблемы с полями класса типа TObject, TTable и т.д.

Я объявляю поле класса как TTable , но при обращении к нему происходит ошибка.

Дело в том, что в Delphi все экземпляры объектов, объявленых как class, являются динамическими. Соответственно поле MyTable, объявленное как

type

public

constructor Create;

destructor Destroy; override;

end;

является указателем на класс TTable , и должно быть инициализировано в конструкторе вашего объекта и соответственно разрушено в деструкторе следующим образом:

constructor TMyClass.Create;

begin

MyTable := TTable.Create(nil);

MyTable.DatabaseName := ‘DBDEMOS’;

end;

destructor TMyClass.Destroy;

begin

end;

Подробнее см. Changes in Object Pascal Language в документации или on-line help.

3. Как закрыть модальную форму (ShowModal)? И вообще, каков лучший способ закрыть любую форму?

Вообще говоря, нужно вызывать метод Close для формы. Close вызывает событие OnClose (обработчик которого может решить, что форму нельзя закрывать, например, если имеются несохраненные данные). Close не освобождает память, связанную с формой, если вы, конечно, не поместите в обработчик события вызов метода Release .

Илон Маск рекомендует:  Алгоpитм соpтиpовки шелла

Если вы хотите уничтожить форму без вызова события OnClose , используйте метод Release . Этот метод работает подобно Free , но позволяет всем обработчикам событий данной формы закончить работу перед тем, как память будет освобождена.

Модальные формы «прекращают свой модальный статус», когда вы устанавливаете свойство ModalResult формы в любое значение, отличное от нуля. Если вы поместите кнопку на модальную форму и установите свойство ModalResult для кнопки в некоторое значение, то, когда пользователь нажмет на эту кнопку, форма закроется с результатом, который вы определили. Этот результат можно узнать вызывая ShowModal как функцию. То есть:

4. Перемещение существующих компонентов на TPanel, TGroup и т.п.

Я поместил кнопку (или что-то другое) на форму, затем поместил панель, и решил переместить кнопку на панель, но ничего не получилось.

Действительно, чтобы поместить кнопку на панель, необходимо на форму сначала поместить панель, выбрать ее, а затем уже помещать кнопку.

Но и в вашей ситуации есть решение. Скопируйте (Copy) или вырежьте (Cut) нужный компонент, выберите панель, и сделайте вставку (Paste). Рекомендуется предварительно «подогнать» копируемый компонент в левый верхний угол формы, иначе компонент на панели может выпасть из «пределов видимости» панели (или любого другого группового компонента).

Если компонент все-таки «выпал» из пределов видимости — найдите этот компонент в Инспекторе Объектов, и установите нужные значения его свойств Left и Top .

Используя группы компонент можно огранизовать форму-шаблон, на которой можно складывать (например в Notebook) компоненты с предварительно заданными свойствами, отличными от стандартных. Это решение проще чем добавлять такие компоненты в палитру компонент — не увеличивается размер библиотеки компонентов DCL (Delphi 3.0 не считается), не загромождается палитра компонент.

Учтите, что при таком копировании компонент их имена меняются на новые ( Button1 , Button2 и т.д.).

5. Как можно добавить новый компонент на страницу TTabbedNoteBook во время выполнения программы? Как нужно определить свойство Parent для этого компонента?

Для того, чтобы добавить компонент на страницу TabbedNotebook , свойству Parent нового компонента нужно присвоить указатель на требуемую страницу. Способ для доступа к любой странице TTabbedNotebook во время выполнения — массив свойств Objects у свойства Pages компонента TTabbedNotebook . Другими словами, страницы сохранены в виде объектов в свойстве Pages (тип TStringList ). Пример демонстрирует создание кнопки TButton на второй странице TabbedNotebook1 :

var

begin

То же самое справедливо и для компонента TNotebook .

6. Как включить символ & в надпись (Caption)?

7. Как сделать окно (TForm) без заголовка (Caption)?

Попробуйте использовать следующий код:

constructor TPanelForm.Create(AOwner: TComponent);

var

begin

inherited Create(AOwner);

LStyle := GetWindowLong(Handle, GWL_STYLE);

LStyle := LStyle and not WS_CAPTION;

SetWindowLong(Handle, GWL_STYLE, LStyle);

end;

procedure TPanelForm.ForceRepaint;

var

WWidth, WHeight: Integer;

begin

SetWindowPos(Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE);

SetWindowPos(Handle, HWND_TOP, 0, 0, WWidth, WHeight, SWP_NOMOVE);

end;

Можно поступить другим способом — выставить у формы свойство BorderStyle = bsNone , и написать следующий обработчик OnPaint :

procedure TForm1.FormPaint(Sender: TObject);

begin

Canvas.Rectangle(0, 0, Width, Height);

end;

8. Почему некоторые компоненты типа TPanel и TEdit не имеют свойства Canvas?

Все наследники TCustomControl имеют Canvas , однако, в большинстве случаев это свойство объявлено protected для предотвращения рисования ‘чужаками’ на компоненте. Наследники компонента всегда могут получить доступ к унаследованным protected свойствам (типа Canvas ), но пользователь компонента — никогда.

type

TCanvasPanel = class(TPanel)

public

property Canvas;

end;

Если вы хотите рисовать на компоненте, у которого нет public свойства Canvas , то используйте, например, компонент TPaintBox : положите его на панель TPanel , сделайте Align = Client и рисуйте на TPaintBox.Canvas .

9. Почему при уничтожении компонента в методе OnClick происходит ошибка?

Допустим, вы поместили на форму кнопку, и создали метод OnClick в котором вызываете Button1.Free . Вы видите, что это метод формы — казалось бы, какие препятствия для правильного уничтожения кнопки?

На самом деле Button1.OnClick является свойством и после запуска вашего приложения содержит адрес метода Form1.Button1Click . Именно кнопка вызывает этот метод как свой собственный. А это означает, что кнопка не может удалить себя в своем-же методе. Даже если вы попытаетесь удалить ссылку в OnClick :

Button1.OnClick := nil;

то это не поможет — стек настроен на возврат в обработчик TButton , который и вызвал OnClick . Поскольку к моменту возврата объект разрушен — возникает GPF или Access Violation.

10. Есть ли у TDBGrid события OnMouseDown, OnMouseUp и OnMouseMove?

Они есть, но не объявлены published. Вы можете создать наследника TDBGrid и сделать их published.

11. Поиск компонента в форме по имени.

Я хочу делать текущими в форме произвольные компоненты. Как выставить фокус у конкретного компонента ясно — ListBox1.SetFocus . А если я хочу обращаться к некоему компоненту по имени (свойство Name )?

Свойство TForm.Components — массив компонентов формы, который и нужен вам. Вы можете перемещаться по этому массиву пока не найдете компонент с нужным Name . Например:

procedure TForm1.DooDah;

var

begin

while (Count ‘Button1’) do Inc(Count);

end;

procedure TForm1.DooDah;

var

begin

Target := FindComponent(‘Button1’);

end;

Оба этих примера показывают как найти компонент TButton с именем Button1 , и вызвать его метод SetFocus .

12. Как получить горизонтальный ScrollBar на ListBox?

Пошлите сообщение LB_SETHORIZONTALEXTENT в ListBox . Например, сообщение может быть отослано в момент создания формы:

procedure TForm1.FormCreate(Sender: TObject);

begin

SendMessage(Listbox1.Handle, LB_SETHORIZONTALEXTENT, 1000, Longint(0));

end;

13. Как определить текущую колонку и строку каретки в компоненте TMemo?

Вы можете использовать сообщения Windows API EM_LINEFROMCHAR и EM_LINEINDEX для определения положения.

var

begin

LineNum := SendMessage(Memo1.Handle, EM_LINEFROMCHAR, Memo1.SelStart, 0);

CharsBeforeLine := SendMessage(Memo1.Handle, EM_LINEINDEX, LineNum, 0);

Label1.Caption := ‘Line ‘ + IntToStr(LineNum + 1)

Lebel2.Caption := ‘Position ‘ + IntToStr(Memo1.SelStart — CharsBeforeLine + 1);

end;

14. Постранична прокрутка TMemo, реализация Undo и определение строки курсора.

Как прокрутить содержимое компонента TMemo ?

Приведенная ниже процедура предполагает, что фокус находится на Edit1 и осуществляет прокрутку в соответствии с нажатыми клавишами.

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

begin

if Key = VK_F8 then

else if Key = VK_F7 then SendMessage(Memo1.Handle, WM_VSCROLL, SB_PAGEUP, 0);

end;

Если определено всплывающее (popup) меню для TMemo ,и заданы клавиши для операций Cut, Copy, Paste, то я могу обрабатывать эти события, вызывая методы CutToClipboard, CopyToClipboard, и т.д. Однако, если я поместили пункт Undo в меню (обычно Ctrl+Z), то как дать знать TMemo , что нужно выполнить Undo?

Если встроенного Undo достаточно, то это очень просто:

Memo1.Perform(EM_UNDO, 0, 0);

Для переключения свойства Enabled пункта меню Undo1 :

Undo1.Enabled := Memo1.Perform(EM_CANUNDO, 0, 0) <> 0;

Как можно определить, на какой строке в TMemo находится курсор?

Весь фокус в сообщении EM_LINEFROMCHAR . Попробуйте:

procedure TMyForm.BitBtn1Click(Sender: TObject);

var

begin

ILine := Memo1.Perform(EM_LINEFROMCHAR, $FFFF, 0);

MessageDlg(‘Line Number: ‘ + IntToStr(ILine), mtInformation, [mbOK], 0);

end;

15. Как поместить BLOB Memo в компонент TMemo?

procedure TForm1.Button1Click(Sender: TObject);

var

begin

S := TBlobStream.Create(Table1BBBMemo, bmRead);

end;

1. Table1BBBMemo — имя поля BLOB Memo ( TMemoField ).

2. Memo1 — имя компонента TMemo . Естественно, что этим же способом можно обмениваться информацией с BLOB-полями произвольного типа.

16. Как показать содержимое Memo поля в TDBGrid?

Используйте следующий код для обработки события OnDrawDataCell у TDBGrid . (Перед запуском программы создайте объект TMemoField для memo поля в Fields Editor).

procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect; Field: TField; State: TGridDrawState);

var

P: array [0..1023] of Char;

S: string;

begin

if Field is TMemoField then

with (Sender as TDBGrid).Canvas do

begin

BS := TBlobStream.Create(Table1Notes, bmRead);

FillChar(P, SizeOf(P), #0);

while Pos(#13, S) > 0 do S[Pos(#13, S)] := ‘ ‘;

while Pos(#10, S) > 0 do S[Pos(#10, S)] := ‘ ‘;

TextOut(Rect.Left, Rect.Top, S);

end;

end;

17. Не возникает событие TSpeedButton.OnDblClick.

Я создаю событие на SpeedButton1.OnDblClick , но оно, похоже, вообще никогда не возникает. OnClick работает. Что делать?

На самом деле работает, только в определенных ситуациях. Если вы помещаете на панель несколько кнопок, то по умолчанию они независимы и соответственно не фиксируются в нажатом состоянии. Поскольку одиночное нажатие мыши на кнопку отрабатывается немедленно, двойной щелчок мыши воспринимается как два нажатия и отпускания. Поэтому OnDblClick и не срабатывает.

Если же кнопки связаны в группу ( GroupIndex <> 0 ), то они могут фиксироваться, и соответственно могут воспринимать двойной щелчок мыши.

18. Как разделить обработку OnClick и OnDblClick? Ведь OnClick будет вызываться всегда, и перед DblClick.

Именно так и происходит в Windows — посылаются оба сообщения. Для того чтобы обработать только какое-то одно событие необходимо чуть «задержать» выполнение OnClick . Сделать это можно следующим способом:

procedure TForm1.ListBox1Click(Sender: TObject);

var

begin

TargetTime := GetTickCount + GetDoubleClickTime;

while GetTickCount

if PeekMessage(Msg, ListBox1.Handle, WM_LBUTTONDBLCLK, WM_LBUTTONDBLCLK, WM_NOREMOVE)

then Exit;

MessageDlg(‘Single clicked’, mtInformation, [mbOK], 0);

end;

19. Как определить из обработчика события OnClick в Popup.MenuItem, для какого объекта это произошло?

Используйте свойство PopupComponent компонента TPopupMenu для определения, где была нажата правая кнопка.

procedure TForm1.PopupItem1Click(Sender: TObject);

begin

end;

Свойство ActiveControl для формы тоже можно использовать, однако, ActiveControl не обязательно является тем элементом, для которого произошло событие.

20. Как использовать case, чтобы определить, какой объект вызвал процедуру?

Используйте свойство Tag . Установите значение Tag свое у каждого объекта для опознания. (Использование констант, которые описывают объект — идеально подходит).

case (Sender as TComponent).Tag of

end;

Таким образом вы можете обрабатывать события как от однотипных компонент, так и от компонент разного типа.

21. Как обрабатывать события от множества однотипных компонентов.

На моей форме находится примерно 10 кнопок. Я хочу обрабатывать нажатие на любую из них одним событием, но как их отличить внутри обработчика события?

Для этого базовый класс VCL TComponent имеет поле Tag типа Longint . В момент разработки вы можете присвоить этому полю любое значение, а в момент исполнения использовать его (или переопределять). В вашей ситуации достаточно присвоить полю ButtonX.Tag значение от 1 до 10 (или от 0 до 9, как удобнее), а в обработчике написать примерно следующее:

procedure MyForm.Button1Click(Sender: TObject);

begin

case (Sender as TComponent).Tag of

end;

end;

22. Использование TPanel в качестве «индикатора».

Я пытаюсь использовать TPanel как индикатор процесса обновления БД. Однако надпись на панели не обновляется пока не закончится цикл обработки БД. В цикле вызывается Panel.Caption := …

После присвоения Panel.Caption вызывайте Panel.Refresh или Application.ProcessMessages (второй вариант предпочтительней, так как позволяет перерисовать себя всем клмплнентам, которые в этом нуждаются).

23. Включение и выключение подсказок (Hints) для всех элементов на форме.

Если ваша форма содержит панель подсказки в нижней части формы, то вы можете определить подменю для этой панели, и выставлять Form.ShowHint в True или False в зависимости от состояния Checked элемента меню.

Например, в TMenuItem.OnClick напишите:

ShowHint := not (Sender as TMenuItem).Checked;

В результате на локальном меню панели будет видно, включены подсказки для всех элементов или нет.

24. Как в меню поместить bitmap?

Можно поступить таким образом:

var

begin

Bmp1.LoadFromFile(‘C:\WHERE\B1.BMP’);

SetMenuItemBitmaps(MenuItemTest.Handle, 0, MF_BYPOSITION, Bmp1.Handle, Bmp1.Handle);

end;

• MenuItemTest — имя пункта меню (горизонтальная строка)

• 0,1 … — позиция пункта меню, в который надо вставить BMP

• первый Handle — для показа невыбранного пункта меню (Unchecked)

• второй Handle — для выбранного (Checked). Они могут быть разные

Код можно вставить в обработчик OnCreate для формы. При уничтожении меню TBitmap не уничтожается, это надо делать отдельно.

25. Каким образом можно поместить двумерный массив в TImage?

Представим, что данные находятся в массиве:

TestArray: array [0..127, 0..127] of Byte;

Картинка будет иметь размер 128Г—128 точек:

Вызываем функцию Windows API для формирования bitmap:

SetBitmapBits(Image1.Picture.Bitmap.Handle, SizeOf(TestArray), @TestArray);

Однако, если вы используете свою палитру, то ее нужно создавать специально.

26. Как из программы ‘открыть’ TComboBox?

У TComboBox есть run-time свойство, не упомянутое в on-line help — DroppedDown .

Для открытия ComboBox напишите:

Естественно, False закроет его.

27. Как заменить надпись ‘Read only’ в компонентах TSaveDialog и TOpenDialog?

Попробуйте посмотреть в Windows API Help разделы, связанные с lpTemplateName . Вообще говоря, вы можете заменить стандартный Open Dialog Box своим собственным шаблоном.

28. Проблема в использовании компонента TCustomGrid.

1. Создаю новый компонент при помощи Эксперта Компонент

2. Имя класса TSampleCalendar

3. Имя родителя TCustomGrid

4. Использую страницу ‘Samples’

5. Сохраняю модуль с именем CALSAMP.PAS

6. Подключаю к Палитре компонент

7. Создаю форму, помещаю новый компонент на форму и получаю Runtime Error 210 В чем дело?

Проблема в том, что TCustomGrid имеет метод DrawCell , который является абстрактным. То, что его безусловно надо переписывать у любого наследника TCustomGrid , к сожалению, не отражено в документации. Создайте этот метод (пусть даже пустой) и ваша проблема исчезнет.

29. Как установить формат для поля таблицы?

В Fields Editor выберите поле для форматирования. Используя свойства DisplayFormat и EditFormat сделайте то, что нужно. DisplayFormat работает для поля, на которое не установлен фокус. EditFormat работает для поля, на которое фокус установлен. Форматирование аналогично первому параметру в функции FormatFloat , но без скобок.

30. Можно ли использовать клавишу ENTER при вводе данных для перехода от поля к полю?

Используйте данный код для события OnKeyPress компонента TEdit .

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);

begin

if Key = #13 then

begin

SelectNext(Sender as TWinControl, True, True);

Key := #0;

end;

end;

Теперь Enter ведет себя как Tab. Затем, выберите все объекты, которые должны вести себя как Edit1 (за исключением кнопок) и в Object Inspector установите обработчик OnKeyPress в Edit1KeyPress . Каждый выбранный вами объект воспринимает Enter как Tab. Если вы хотите обрабатывать событие на уровне формы (а не в каждом отдельном компоненте), уберите обработчики события у всех компонент и создайте FormKeyPress — обработчик OnKeyPress для формы:

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);

begin

if Key = #13 then

begin

SelectNext(Sender as TWinControl, True, True);

Key := #0;

end;

end;

Все объекты на форме будут воспринимать Enter как Tab.

Общие вопросы по Delphi и данному FAQ (часть 3)
Object Pascal и Windows API

1. Как работает информация времени выполнения (RTTI)?

Имеются два новых оператора: as и is. as — оператор защищенного преобразования типов (typecasting). Вы можете использовать его, чтобы заставить компилятор преобразовать объект из одного типа в другой, но, если в во время выполнения эти типы окажутся несовместимыми, то вы получите ошибку. Hапример, если вы имеете класс TSport , с потомоками TBasketball и TFootball , вам может потребоваться переменная типа TSport ; далее может так случиться, что в программе эта переменная будет фактически содержать экземпляр типа TFootball . Тогда вы можете обратиться к этой переменной

(MySport as TFootball)

чтобы получить доступ к специфическим свойствам из типа TFootball . Однако, если вы ошиблись и на самом деле это экземпляр типа TBasketball , то при обращении к несуществующим свойствам будет возникать ошибка. Оператор is определяет, принадлежит ли экземпляр объекта к данному классу, либо к классу одного из его предков, и используется для проверки, сработает ли преобразование типов с данным объектом. Если вы имеете переменную MySport типа TSport , и в настоящее время она содержит экземпляр TBasketball , тогда следующие выражения истинны:

(MySport is TSport)

(MySport is TBasketball)

not (MySport is TFootball)

Следует иметь ввиду, что компилятор разрешает использовать данные конструкции только для выполнения преобразования типов, связанных родственными отношениями. Так, конструкция (Button1 as TEdit) (переменная Button1 имеет тип TButton ) вызовет ошибку компиляции, так как ни при каких условиях не может быть выполнено преобразование типов от TButton к TEdit или наоборот. Комбинация двух операторов может привести к выражению типа следующего :

function PlayerGoodness(var MySport: TSport): Integer;

begin

if (MySport is TBasketball) then

Result := (MySport as TBasketball).ReboundShots

else if (MySport is TFootball) then

Result := (MySport as TFootball).TotalYardage;

end;

Также, базовый класс TObject имеет набор методов, которые возвращают информацию, созданную компилятором в момент компиляции текста для поддержки RTTI. Hапример, метод TObject.ClassName возвращает имя класса любого объекта, наследованного от TObject . Hапример, TButton.ClassName вернет значение ‘TButton’ .

2. Как работает обработка исключительных ситуаций в Delphi?

Основная структура выглядит примерно так:

try

try

except

raise;

end;

finally

end;

Первая строка распределяет большой блок памяти. Затем, в блоке try, выполняется несколько операторов, каждый из которых может вызвать ошибку, или, другими словами, «вызвать исключительную ситуацию». Если возникает ошибка, оставшаяся часть блока try пропускается, и выполняются блоки except и finally. Если ошибок нет, то после выполнения всех операторов в блоке try выполнится блок finally. В любом случае, блок памяти будет освобожден. Блок try … finally ловит все, включая Windows GPF или Access Violation. Обратите внимание на вызов raise в блоке try … except. Он снова вызывает исключительную ситуацию, которая вызовет сообщение об ошибке после того, когда закончится блок finally. Если не вызвать raise, то считается, что вы обработали исключительную ситуацию самостоятельно в пределах блока except.

3. Есть ли простой способ перехватить exception?

Создайте метод для формы, перехватывающий исключения. Этот метод будет вызываться обработчиком OnException объекта Application . В вашем методе проверьте, тот ли это исключение, что вы ожидаете, например EDatabaseError . Почитайте on-line help для события OnException . Там есть информация, как вызвать собственный метод для события.

procedure TForm1.MyExcept(Sender: TObject; E: Exception);

begin

if E is EDatabaseError then MessageDlg(‘Поймали exception’, mtInformation, [mbOk], 0)

else raise E;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

end;

4. Delphi используют строки в стиле Pascal или C?

И те и другие. Delphi имеет два различных набора функций манипулирования строками, один — для PChar ; но в Delphi также есть функция MessageDlg , которая принимает строки типа Pascal.

Delphi 2.0 добавляет так называемые длинные строки ( AnsiString ), которыми можно манипулировать как обычными строками в Pascal, но они имеют динамически изменяющийся размер и могут быть размером до 4Гбайт. Можно выполнять преобразования от PChar к AnsiString и наоборот. Старый строковый тип теперь называется ShortString . По умолчанию кличевое слово string соответствует типу AnsiString .

5. Есть ли в Delphi битовые множества?

В явном виде битовых множеств в языке Object Pascal нет. Но вместо этого можно использовать обычные множества, которые на самом деле и хранятся как битовые. Если множество вам нужно для проверки, установлен ли какой то бит в слове (байте и т.д.) можно попробовать такую конструкцию:

type

TByteSet = set of Byte;

var

if 3 in PByteSet(@W)^ then .

В Delphi 2.0 есть специальный класс TBitSet , который ведет себя как битовое множество.Для Delphi 1.0 вы можете написать такой класс самостоятельно.

6. Проблема с числом типа Single в DLL.

Я написал на C++ DLL, в которой у меня функция использует число типа float, передал из Delphi число типа Single и получил GPF ‘Invalid Opcode’. Что неправильно?

Если вы используете числа с плавающей точкой, лучше передавать их не по значению, а по ссылке (указатель в C++). Вероятно DLL написана на MS Visual C++, так как Microsoft и Borland используют разные соглашения о передаче параметров при работе с сопроцессором. В случае Borland C++ и Delphi должны использовать одинаковый способ передачи параметров и значений (через стек сопроцессора). В любом случае вместо Single лучше использовать Double (double или long float в C++), так как вообще говоря, реальный тип, который соответствует типу Single точно не определен и может измениться в будущем.

7. Как заставить приложение Delphi отвечать на сообщения Windows?

Используем сообщение WM_WININICHANGED в качестве примера. Объявление метода в TForm позволит вам обрабатывать сообщение WM_WININICHANGED :

procedure WMWinIniChange(var Message: TMessage); message WM_WININICHANGE;

Код в implementation может выглядеть так:

procedure TForm1.WMWinIniChange(var Message: TMessage);

begin

inherited;

end;

Вызов inherited метода очень важен. Обратите внимание также на то, что для функций, объявленных с директивой message (обработчиков событий Windows) после inherited нет имени наследуемой процедуры, потому что она может быть неизвестна или вообще отсутствовать (в этом случае вы в действительности вызываете процедуру DefaultHandler).

8. Как обработать события от других приложений?

Попробуйте сделать это следующим образом:

type

TForm1 = class(TForm)

private

procedure WMNCActivate(var Msg: TMessage); message WM_NCACTIVATE;

end;

procedure TForm1.WMNCActivate(var Msg: TMessage);

begin

end;

9. Как перехватить сообщения Windows и обработать их перед тем, как выполнится строка Application.Run?

Пример проекта показывает, как получить сообщения Windows в данном случае. Это редкий случай, в большинстве случаев переопределение процедуры Application.OnMessage будет делать то же самое.

program Project1;

uses

Unit1 in ‘UNIT1.PAS’ < Form1 >,

Messages, WinTypes, WinProcs,

var

function NewWndProc(hWndAppl: HWnd; Msg, wParam: Word; lParam: Longint): Longint; export;

begin

Result := CallWindowProc(OldWndProc, hWndAppl, Msg, wParam, lParam);

end;

begin

OldWndProc := TFarProc(GetWindowLong(Application.Handle, GWL_WNDPROC));

SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(@NewWndProc));

end.

10. Проблема с DragDrop для внешних программ.

Я пишу небольшую программку — «мусорную корзину». В FormCreate вызывается DragAcceptFiles(HANDLE, True) . Проблема в том, что когда размер окна восстанавливается и затем минимизируется Drag and Drop перестает работать. Я безуспешно пробовал помещать DragAcceptFiles в разные методы формы. Однако если сделать вызов DragAcceptFiles(Application.Handle, True) в MainForm.Create , то все работает. Как перехватить событие WM_DROPFILES ?

Это можно сделать так:

type

TMainForm = class(TForm)

procedure FormCreate(Sender: TObject);

private

procedure DropFiles(var Msg : TWMDropFiles); message WM_DROPFILES;

end;

procedure TMainForm.DropFiles(var Msg : TWMDropFiles);

begin

NrOfFiles := DragQueryFile(Msg.Drop, Word(-1), FileName, BufSize);

DragQueryFile(Msg.Drop, 0, FileName, BufSize);

end;

procedure TMainForm.FormCreate(Sender: TObject);

begin

end;

Подробнее о перехвате событий Windows см. Главу 7 руководства Component Writers Guide.

11. Как обрабатывать WM_DROPFILES (Drag/Drop)?

Следующий код показывает как обрабатывать это событие. Обрабатываются имена всех «брошенных» файлов. Для загрузки каждого файла вызывается CreateChild(FName) . В обработчике OnCreate данной формы вы должны вызвать DragAcceptFiles .

type

TFrameForm = class(TForm)

protected

procedure WMDropFiles(var Msg: TMessage); message WM_DROPFILES;

end;

procedure TFrameForm.WMDropFiles(var Msg : TMessage);

var

FName: string;

begin

N := DragQueryFile(HDrop, $FFFF, nil, 0);

for I := 0 to (N-1) do

begin

Size := DragQueryFile(HDrop, I, nil, 0);

if Size

begin

DragQueryFile(HDrop, I, @FName[1], Size+1);

end;

end;

inherited;

end;

12. Как может выделить время CPU другим задачам , подобно «DoEvents» в VB?

Эквивалент в Delphi — Application.ProcessMessages .

Если вы выполняете долгие вычисления, то вызов данного метода позволит в Win 16 выполняться параллельно другим приложениям, а в Win 32 — корректно перерисовываться вашему приложению.

13. В каком порядке происходят события при создании и показе окна?

При создании окна обработчики событий выполняются в следующем порядке:

14. UpCase для русского языка.

Данная функция (UpCase) производит преобразование только латинских символов в верхний регистр. Для правильного преобразования необходимо использовать функции Windows API, поскольку именно Windows должна «знать» о кодировке национальных символов. Причем к конфигурации BDE кодровка Windows не имеет никакого отношения — имея английские Windows без русификатора и выставив в BDE кодировку Paradox ANSII Cyrillic нормальных русских букв получить не удастся.

А функции для преобразования следующие — OemToAnsi, AnsiToOem, OemToAnsiBuf, AnsiToOemBuf в Win16 (модуль WinProcs) и OemToChar, CharToOem, OemToCharBuf и CharToOemBuf в Win32 (модуль Windows)..

15. Приложение, написанное на Delphi, не запускается минимизированным.

Проверьте глобальную переменную CmdShow для того чтобы определить, в каком состоянии запускается приложение, и модифицируйте ее как вам необходимо:

procedure TForm1.FormCreate(Sender: TObject);

begin

if CmdShow = SW_SHOWMINNOACTIVE then WindowState := wsMinimized;

end;

Например, если необходимо запускать приложение либо минимизированным, либо максимизированным, используйте следующий код:

procedure TForm1.FormCreate(Sender: TObject);

begin

if CmdShow = SW_SHOWMINNOACTIVE then WindowState := wsMinimized

else WindowState := wsMaximized;

end;

16. Объясните разницу в помещении uses в секцию interface или implementation.

Секция interface — интерфейсная. Туда попадают объявления констант, типов (в т.ч. и объектов или классов) переменных, процедур и функций. Поэтому для этой части uses должен содержать ссылки на те модули, которые используются для объявлений в этой части.

Секция implementation — описание реализации интерфейсной части, здесь в uses должны быть упомянуты те модули, которыми вы пользуетесь для написания кода. Например, Вы хотите в модуле пользоваться функциями API Windows, для этого добавьте в объявлении implementation строку uses WinTypes, WinProcs; или uses Windows;. Таким образом, вы явно указываете что данными модулями будете пользоваться только в секции реализации.

Конечно, можно упоминать модули только в части interface, но правильная расстановка имен модулей в соответствующем uses гарантирует исключение циклических ссылок, а также улучшает читаемость программы.

17. Как спрятать окна MDI Child?

Я пытаюсь это сделать, выставляя Form1.Visible := False , но это не помогает.

Windows не позволяет прятать окна MDI Child.

18. Как убрать заголовок у формы MDIChild?

Как убрать заголовок ( Caption ) из MDIChild?

Для MDIChild установка свойства BorderStyle := bsNone не убирает заголовок. Это можно сделать так:

procedure TMDIChildForm.CreateParams(var Params: TCreateParams);

begin

inherited CreateParams(Params);

Params.Style := Params.Style and (not WS_CAPTION);

end;

19. Сохранение данных в Clipboard.

Мне нужно использовать clipboard для сохранения данных в собственном формате и я хочу для этого написать набор процедур ввода/вывода с использованием потоков (streams). Возможно ли создать объект TMemoryStream , эаполнить его и поместить в Clipboard?

Не только возможно, именно так поступают функции Clipboard.GetComponent и Clipboard.SetComponent . Сначала вы должны зарегистрировать свой собственный формат данных для Clipboard с помощью функции RegisterClipboardFormat :

CF_MYFORMAT := RegisterClipboardFormat(‘My Format Description’); Далее вы должны выполнить шаги:

1. Создать поток (memory stream) и записать туда данные.

2. Создать глобальный буфер в памяти и скопировать поток туда.

3. Вызвать Clipboard.SetAsHandle(), чтобы поместить буфер в Clipboard.

Пример:

var

begin

try

hBuf := GlobalAlloc(GMEM_MOVEABLE, MStream.Size);

try

try

Move(MStream.Memory^, BufPtr^, MStream.Size);

finally

end;

except

raise;

end;

finally

end;

end;

Внимание: не уничтожайте буфер, созданный с GlobalAlloc . Поскольку вы поместили его в Clipboard, это уже дело clipboard’а его уничтожить. Опять же, получая буфер из Clipboard, не уничтожайте этот буфер — просто сделайте копию содержимого.

Для обратного получения потока и данных, сделайте что-нибудь вроде этого:

var

begin

if hBuf <> 0 then

begin

if BufPtr <> nil then

try

try

finally

end;

finally

end;

end;

end;

20. Что означает Key<>#0 ?

В исходном тексте одного из компонентов третьих фирм я увидел строку:

if Key <> #0 then inherited KeyPress(#0);

В Windows виртуальные коды находятся в диапазоне 1-145 (Dec). Зачем нужна такая проверка?

В соответствии с соглашением Windows код клавиши #0 означает отсутствие реального нажатия. Управление в данную точку программы могло попасть, например вследствие прямого вызова, а не нажатия клавиши или же нажатие уже было обработано предком, вследствие чего код нажатой клавиши был сброшен в 0.

21. Аналог процедуры TP/BP Delay.

procedure TForm1.Delay(MSecs: Longint);

var

begin

repeat

until GetTickCount — FirstTick >= MSecs;

end;

В Win32 API существуют также функции Sleep и SleepEx .

22. Каким образом создать форму, которую можно таскать за поле?

Как сделать форму (окно), которое перетаскивается не за заголовок ( Сaption ), а за все поле ?

Нужно обрабатывать сообщение WM_NCHITTEST :

type

TForm1 = class(TForm)

private

procedure WMNCHitTest(var M: TWMNCHitTest); message WM_NCHITTEST;

end;

procedure TForm1.WMNCHitTest(var M: TWMNCHitTest);

begin

inherited;

if M.Result = htClient then

end;

Примечание: окно можно сделать вообще без Сaption .

23. Как программно спрятать или показать заголовок у формы?

Как программно спрятать или показать заголовок ( Caption ) у формы?

Вы можете попробовать следующее:

procedure TForm1.HideTitlebar;

var

begin

if BorderStyle=bsNone then Exit;

Save := GetWindowLong(Handle, GWL_STYLE);

if (Save and WS_CAPTION) = WS_CAPTION then

begin

case BorderStyle of

SetWindowLong(Handle, GWL_STYLE, Save and (not WS_CAPTION) or WS_BORDER);

SetWindowLong(Handle, GWL_STYLE, Save and (not WS_CAPTION) or DS_MODALFRAME or WS_DLGFRAME);

end;

end;

end;

procedure TForm1.ShowTitlebar;

var

if BorderStyle = bsNone then Exit;

Save := GetWindowLong(Handle, GWL_STYLE);

if (Save and WS_CAPTION) <> WS_CAPTION then

begin

case BorderStyle of

SetWindowLong(Handle, GWL_STYLE, Save or WS_CAPTION or WS_BORDER);

SetWindowLong(Handle, GWL_STYLE, Save or WS_CAPTION or DS_MODALFRAME or WS_DLGFRAME);

end;

Height := Height + GetSystemMetrics(SM_CYCAPTION);

end;

end;

24. Как сделать приложение модальным?

Мне нужно сделать приложение модальным, для того чтобы обезопасить систему и в то же время позволить работать с программой.

Ok, пара предложений на эту тему:

1. Создайте форму, занимающую весь экран (maximized) без системных кнопок (Maximize, Minimize, System)

2. В обработчике FormDeactivate для формы вызовите метод SetFocus — это предотвратит Ctrl+Esc:

3. В обработчике события FormActivate , нужно присвоить метод Deactivate для приложения:

4. Создайте всплывающее меню TPopupMenu с единственным пунктом. В свойствах данного компонента нужно установить Visible=False . Создайте процедуру для этого пункта меню, и в теле поставьте две фигурные скобки <> (для того, чтобы Delphi не удалил эту процедуру)

5. Присвойте созданное Popup-меню форме (св-во PopupMenu )

6. Задайте горячую клавишу (shortcut) для Popup-меню в методе FormActivate как показано ниже:

NullItem1.ShortCut := ShortCut(VK_Tab, [ssAlt]);

( NullItem1 нужно заменить на название созданного вами объекта — пункта меню)

Шаги 4-6 предотвращают переход на приложение по Alt-Tab.

25. Как изменить шрифт у Application.Title (заголовка приложения)?

Никак. Это ограничение Windows — вы не можете изменить шрифт ни у одного заголовка ни у приложения, ни у окна. Для окна можно предложить следующее — создать свое окно без заголовка ( Caption ) и рамки, которое будет само выводить нужную надпись нужным шрифтом и одновременно будет способно изменять свои размеры.

26. Каким образом (желательно не специфичным для Delphi) узнать, открыто меню или нет?

type

TForm1 = class(TForm)

private

public

procedure WMMenuSelect(var M: TWMMenuSelect); message WM_MENUSELECT;

end;

implementation

procedure TForm1.WMMenuSelect(var M: TWMMenuSelect);

begin

inherited;

if M.Menu = MainMenu1.Handle then MessageBeep(MB_ICONASTERISK);

end;

end.

Разное

1. Передача переменной в отчет ReportSmith.

Следующий код показывает, как передать переменную в отчет.

В примере строковой переменной отчета ‘City’ присваивается значение ‘Bombey’ . Подразумевается, что есть готовый отчет с данной переменной. Поместите компонент TReport на форму и установите требуемые свойства для вызова печати отчета. Напишите обработчик OnClick для кнопки Button1 на форме (кнопка — для простоты):

procedure TForm1.Button1Click(Sender: TObject);

begin

Report1.InitialValues.Add(‘@City= ‘);

end;

2. Как получить русские буквы в DBD?

Имя шрифта для отображения русских букв берется из файла PDOXWIN.INI секция [Properties] строка SystemFont. Если очень хочется, то можно исправить имя ‘PDOXWIN.INI’ на ‘DBD.INI’ в файле DBSRV.DLL (он лежит там же где и DBD.EXE) по смещению $E9D8 (не забудьте после ‘DBD.INI’ поставить шестнадцатеричный ноль), и в секции [Properties] файла DBD.INI добавить строку типа

SystemFont = Courier New Cyr

По умолчанию имя фонта для отображения русских букв — Arial.

Действительно, если у Вас Pan Euro или русская версия Windows95, то DBD не будет показывать шрифты Cyr в Preferences/General/Default system font.

Решить эту проблему можно двумя способами:

1. записать в каталог WINDOWS/FONTS шрифты Arial Cyr от русских Windows и сделать ShutDown. После загрузки Arial Cyr будет доступен для выбора.

2. поменять шрифт в Registry вручную например на MS Sans Serif — HKEY_CURRENT_USER/SOFTWARE/Borland/DBD/7.0/Preferences/Properties ключ SystemFont.

3. Как печатать отчеты из приложения Delphi без использования ReportSmith?

1. Лучше всего использовать специализированные генераторы отчетов в виде компонентов, например QuickReport или Ace Reporter.

2. Можно использовать печать формы, например: Form1.Print .

3. Можно использовать свойство Canvas объекта Printer .

4. Как узнать количество точек на дюйм для принтера?

VertPixelsPerInch := GetDeviceCaps(Printer.Handle, LogPixelsX);

HorzPixelsPerInch := GetDeviceCaps(Printer.Handle, LogPixelsY);

5. Как определить, приложение запущено из под Delphi IDE или как отдельный файл?

Для этого следует проверить существование определенных окон:

Delphi 1.0

function DelphiLoaded: Boolean;

function WindowExists(ClassName, WindowName: string): Boolean;

var

PClassName, PWindowName: PChar;

AClassName, AWindowName: array [0..63] of Char;

begin

if then P >

else P >

if WindowName = » then PWindowName := nil

else PWindowName := StrPCopy(@AWindowName[0], WindowName);

Result := FindWindow(PClassName, PWindowName) <> 0;

end;

begin

Result := WindowExists(‘TPropertyInspector’, ‘Object Inspector’)

and WindowExists(‘TMenuBuilder’, ‘Menu Designer’)

and WindowExists(‘TApplication’, ‘Delphi’)

and WindowExists(‘TAlignPalette’, ‘Align’)

and WindowExists(‘TAppBuilder’, »);

end;

Delphi 2.0

function DelphiLoaded: Boolean;

function WindowExists(ClassName, WindowName: string): Boolean;

begin

Result := FindWindow(PChar(ClassName), PChar(WindowName)) <> 0;

end;

begin

Result := WindowExists(‘TPropertyInspector’, ‘Object Inspector’)

and WindowExists(‘TMenuBuilder’, ‘Menu Designer’)

and WindowExists(‘TApplication’, ‘Delphi’)

and WindowExists(‘TAlignPalette’, ‘Align’)

and WindowExists(‘TAppBuilder’, »);

end;

Другой вариант для Delphi 1.0, работает только в EXE файлах (не в DLL).

function InIDE: Boolean;

begin

Result := Bool(PrefixSeg) and Bool(PWordArray(MemL[DSeg:36])^[8]));

;end

6. Что нужно предусмотреть при разработке приложения, которое будет работать при различном разрешении дисплея?

На ранней стадии создания приложения решите для себя хотите ли вы позволить форме масштабироваться. Преимущество немасштабируемой формы в том, что ничего не меняется во время выполнения. В этом же заключается и недостаток (ваша форма может бать слишком маленькой или слишком большой в некоторых случаях).

1. Если вы не собираетесь делать форму масштабируемой, установите свойство Scaled=False и дальше не читайте.

2. В противном случае Scaled=True .

1. Установите AutoScroll=False . AutoScroll = True означает ‘не менять размер окна формы при выполнении’ что не очень хорошо выглядит, когда содержимое формы размер меняет.

2. Установите шрифты в форме на самые распространенные TrueType шрифты, например Arial, Times New Roman, Courier. Если вдруг выбранного шрифта не окажется на пользовательском компьютере, то Windows выберет альтернативный шрифт из того же семейства. Этот шрифт может не совпадать по размерус исходным, что вызовет проблемы.

3. Установите св-во Position в любое значение, отличное от poDesigned . poDesigned оставляет форму там, где она была во время дизайна, и, например, при разрешении 1280Г—1024 форма может оказаться в левом верхнем углу и совершенно за экраном при 640Г—480.

4. Оставляйте по крайней мере 4 точки между компонентами, чтобы при смене положения границы на одну позицию компоненты не «наезжали» друг на друга.

5. Для однострочных меток TLabel с выравниванием alLeft или alRight установите AutoSize=True . Иначе AutoSize=False . Убедитесь, что достаточно пустого места у TLabel для изменения ширины фонта — 25% пустого места многовато, зато безопасно. При AutoSize=False Убедитесь, что ширина метки правильная, при AutoSize=True убедитесь, что есть свободное место для роста метки.

7. Для многострочных меток (word-wrapped labels), оставьте хотя бы одну пустую строку снизу.

8. Будьте осторожны при открытии проекта в среде Delphi при разных разрешениях. Свойство PixelsPerInch меняется при открытии формы. Лучше тестировать приложения при разных разрешениях, запуская готовый скомпилированный проект, а редактировать его при одном разрешении. Иначе это вызовет проблемы с размерами. Не изменяйте свойство PixelsPerInch самостоятельно!

9. В общем, нет необходимости тестировать приложение для каждого разрешения в отдельности, но стоит проверить его на 640×480 с маленькими и большими шрифтами и на более высоком разрешении перед продажей.

10. Уделите пристальное внимание принципиально однострочным компонентам типа TDBLookupCombo . Многострочные компоненты всегда показывают только целые строки, а TEdit покажет урезанную снизу строку. Каждый компонент лучше сделать на несколько точек больше. Даже при выполнении перечисленных инструкций, у вас могут возникнуть проблемы при переходе, например от Large fonts к Small fonts в Windows 95 при одном и том же разрешении. Бороться с этим помогают специально для этого разработанные компоненты. Если же вы решите самостоятельно изменять размеры компонентов, лежащих на форме, то вам могут помочь методы TCanvas.TextWidth и TCanvas.TextHeight .

7. Конвертация ICO в BMP.

Я создают toolbar, у меня есть иконки, но нет картинок в виде bitmap. Помогите!

Для преобразования файлов из одного формата в другой лучше всего иметь что-нибудь вроде HiJaak, который может преобразовывать форматы напрямую. Однако, будем считать, что у вас нет ничего, кроме Windows и Delphi. Следующая процедура может использоваться чтобы преобразовывать иконку в формат Windows Bitmap:

1. Покажите на экране иконку. Не имеет значения, как вы это сделаете.

2. Нажмите Alt-PrintScreen, чтобы скопировать текущее окно в буфер Clipboard.

3. Загрузите Paintbrush и сделайте Edit/Paste.

4. Выберите нужный кусок изображения и сделайте Edit/Copy. Перейдите к пункту Options/Image Attributes и установите размер области 32×32 точки.

5. Снова сделайте Edit/Paste.

6. Сохраните результат как BMP файл.

Лучше всего для редактирования и создания ресурсов (икон, картинок и т.п.) подходит Resource Workshop. Он включен в состав пакетов Borland Pascal 7.0 или Borland C++ 4.5, а также интегрирован в Borland C++ 5.0.

В Delphi 1.0 есть специальный файл (X:\DELPHI\BIN\WORKOPT.DOS) который необходимо поместить в каталог, где находится Workshop — в этом случае последний будет «понимать» ресурсы, создаваемые Delphi 1.0 (например *.DCR).

8. Когда используется свойство Glyph, как узнать, какой цвет прозрачный?

Delphi всегда принимает, что цвет пикселя в левом нижнем углу картинки является фоновым цветом и должен отображаться на экране как прозрачный. Это нигде не документировано, но если у вас есть исходники VCL, вы можете посмотреть код в BUTTONS.PAS .

9. Как отобразить bitmap в 256 цветах?

Как подгрузить 256 цветный bitmap из ресурса и отобразить его в нормальной палитре?


Обычно это делается следующим образом. Код Вадима Пузанова (Красноярск).

Image1.Bitmap.Handle := LoadBitmap(hInstance, ‘BMP_NAME’);

LoadBitmap загружает только картинку, без палитры. Если палитра у картинки отличается от системной, то ее надо устанавливать «вручную». Могут возникнуть проблемы, если на одной форме расположены две картинки с разными палитрами.

procedure XLoadBitmap(Instance: THandle; BitmapName: PChar; var HB: HBitmap; var HP: Palette);

var

OldPalette, Palette: HPalette;

begin

if ResIDHandle <> 0 then

begin

ResDataHandle := LoadResource(Instance, ResIDHandle);

if ResDataHandle <> 0 then

begin

if BI <> nil then

begin

if BI^.bmiHeader.biBitCount = 8 then

begin

GetMem(Pal, SizeOf(TLogPalette) + 256*SizeOf(TPaletteEntry));

for I := 0 to 255 do with Pal^.palPalEntry[I] do

begin

end;

FreeMem(Pal, SizeOf(TLogPalette) + 256 * SizeOf(TPaletteEntry));

DC := CreateDC(‘Display’, nil, nil, nil);

OldPalette := SelectPalette(DC, Palette, False);

BitMap:= CreateDIBitmap(DC, BI^.bmiHeader, CBM_INIT,

@PByteArray(BI)^[SizeOf(TBitMapInfo) + SizeOf(TRGBQuad) * 256 — 4], BI^, DIB_RGB_COLORS);

SelectPalette(DC, OldPalette, False);

end else

begin

BitMap := LoadBitmap(Instance, BitmapName);

end;

end;

end;

end;

end;

procedure TForm1.FormCreate(Sender: TObject);

var

begin

XLoadBitmap(hInstance, ‘PHOTO’, HB, HP);

end;

10. Если я хочу рассылать EXE файл, созданный в Delphi, какие еще файлы нужно посылать с ним?

Hикакие. Все компилируется в .EXE файл. Конечно, если вы разработали другие файлы (HLP, данные и т.д. ), или если вы используете VBX/OCX файлы, тогда вы должны распространять и их заодно. Если вы используете файлы VBX, то в поставку нужно также включать BIVBX11.DLL.

Если приложение использует функции BDE, вы также должны включать Borland DataBase Engine.

Полезные хитрости

1. Может ли редактор текстов в Delphi вырезать и вставлять прямоугольные фрагменты текста?

Конечно, может: Нажмите кроме Shift еще и Alt и режьте на здоровье. Alt можно сразу отпустить. Чтобы вернуться в старый режим, нужно выделить что-либо мышкой.

2. Редактирование файлов SQL в Delphi IDE.

Если вы в Delphi 2.0 IDE редактируете файл с расширением SQL, то, хотя это нигде не документировано, происходит автоматический Syntax Highlighting. Наибольший недостаток — не отслеживается конец комментария ‘*/’.

В Delphi 3.0 комментарии отрабатываются нормально.

3. Встроенный отладчик/дизассемблер.

Если вы создадите в ключе

HKEY_CURRENT_USER\Software\Borland\Delphi\2.0\Debugging

строковое значение EnableCPU = «1» , то после перезапуска среды у вас появится пункт меню View|CPU, которые вызывает появление простейшего отладчика/дизассемблера.

Для Delphi 3.0 справедливо тоже самое (… \Delphi\3.0\Debugging , естественно), причем отладчик там по возможностям сравним с Turbo Debugger.

Вопросы по Delphi 1.0
Вопросы общего характера

1. Какие существуют варианты поставки Delphi 1.0?

Версия Delphi 1.0 имеет два варианта: Delphi Desktop и Delphi Client/Server.

Версия Delphi 1.0 Desktop включает:

• Среду разработки Delphi IDE

• Механизм Borland Database Engine доступа к локальным данным Paradox и dBase, а также через ODBC

• 16-разрядный Local Interbase

Версия Delphi 1.0 Client/Server включает в себя все, что имеется в Delphi Desktop плюс:

• SQL-Links 2.5, которые включают родные драйверы для Oracle, Sybase (MS SQL), Informix, и InterBase, и включают полные неограниченные права распространения к этим драйверам (что стоит $995 если это куплено отдельно);

• Local InterBase Deployment Kit , $495 [2] ;

• Средства поддержки групповой разработки — не доступно отдельно;

• Visual Query Builder, который, как говорят, немного лучше, чем MSQuery, который входит в Microsoft Excel , Access , и т.д.). VQB также недоступен отдельно;

• Исходные тексты библиотеки визуальных компонент, которые доступны отдельно за $100.

• Дополнительно 2 тома документации.

На данный момент версия Delphi 1.0 фирмой Borland отдельно не поставляется и имеется только в составе старших версий продукта.

2. Какие форматы скомпилированных модулей можно получить в Delphi 1.0?

Delphi может создавать EXE- и DLL-файлы для Windows 3.1. Естественно, Вы может также создавать VBX, но для этого нужно знать соглашения по написанию DLL в формате VBX. Имеется информация о написании VBX для Borland Pascal for Windows, которая с небольшими изменениями подходит и для Delphi.

Delphi не создает EXE-файлы для DOS.

3. Есть ли проблемы в Delphi с русским языком?

Что касается визуальных компонент, то все они, включая меню, допускают надписи (Caption) и ввод киррилицей; «горячие клавиши» тоже могут быть русские, например комбинация Alt-Ф для пункта меню &Файл (конечно, должен быть включен драйвер русской клавиатуры). Для работы с таблицами нужно в утилите конфигурации BDE установить:

1. В разделе драйверы для всех типов баз данных установить соответствующий драйвер языка (например Pdox ANSI Cyrillic).

2. Если таблица (в частности, в формате Paradox) уже была создана с использованием другого драйвера языка, то ее можно перенастроить в DataBase Desktop на нужный драйвер.

3. Для того, чтобы Database Desktop нормально ‘видел’ русские буквы, его настройки тоже необходимо немного подкорректировать.

Русские буквы в среде:

Поскольку используются разные версии Windows (Eng, Rus, Win-OS2, Win95, WinNT), способы могут быть как разными, так и общими (Windows есть Windows).

Сначала опишем действия, необходимые для русификации Windows:

1. Если вы собираетесь работать в OS/2, то желательно иметь английскую версию Windows 3.1 или OS/2 с Win-OS2 (в последнем случае вы не сможете запускать Windows без OS/2). Windows for WorkGroups здесь не подойдет, т.к. их сетевые функции под OS/2 работать не будут — для этого есть другие средства.

2. Hесмотря на то, что вы собираетесь работать с англоязычной версией Windows найдите русские Windows и «вытащите» оттуда все шрифты *.FON, *.FOT, *.TTF.

3. Каким-нибудь редактором шрифтов (напр FontoGrapher) скопируйте русские буквы с адреса 100 на адрес С0 — в этом случае один шрифт можно использовать и в английских и в русских Windows.

4. Установите какой-либо русификатор — неплохо ведут себя CyrWin и ParaWin, причем для Win-OS2 предпочтительнее ParaWin. Устанавливать можно только русификатор без шрифтов, т.к. шрифты пойдут от русских Windows. Если вы не выполнили пункт 3, то TTF от русских Windows вам не помогут, и нужно будет ставить шрифты из комплекта русификатора.

5. Замените все шрифты *.FON на шрифты из русских Windows.

6. Подключите русские шрифты (Arial Cyr, Courier New Cyr, Times New Cyr).

7. Добавьте в WIN.INI в секцию [FontSubstitutes] следующую строку: Arial=Arial Cyr или вместо Arial Cyr укажите русский шрифт сходный по начертанию (напр. для CyrWin это NTHelvetica/Cyrillic).

Также на всякий случай можно добавить следующие подстановки:

Helvetica=Arial Cyr (или NTHelvetica/Cyrillic)

Одновременно закомментируйте строки, где упоминается английский шрифт Arial.

В русских Windows можно совершенно безболезненно удалить (при помощи Control Panel/Fonts) шрифты, имеющие в названии окончание CE (напр. Arial CE) — это сербо-хорватские шрифты, которые вам вряд-ли когда понадобятся (русских букв там нет).

Далее, возможные варианты работы с русскими буквами в редакторе Delphi.

Нельзя в Windows выставлять TrueType fonts only — редактор использует только FixedFonts, в результате Delphi просто не будет работать.

1. Комментарии и строки могут быть введены только в кодировке 1251 — причина, естественно в том, что русификатор позволит вводить русские буквы только в этой кодировке. Тексты, написанные в DOS (кодировка 866), будут отображаться как «мусор» на экране — редактор HЕ преобразует символы 866в†’1251. Однако если для редактора установить шрифт Terminal — тексты в 866 будут отображаться нормально, а ввести символы не удастся (опять же по причине ввода символов только в кодировке 1251). Уже готовый текст в 866 кодировке лучше преобразовать в 1251 с помощью одной из программ конвертации.

2. Некоторые программные продукты при установке меняют фиксированные шрифты или даже удаляют их. Будьте внимательны при и после установки других программных продуктов, особенно редакторов текстов (WinWord, AmiPro…). Держите под рукой архив с русскими шрифтами *.FON, чтобы была возможность восстановить эти шрифты.

3. Поэкспериментируйте со шрифтами редактора — разные шрифты имеют разное начертание, и разную скорость перерисовки. Выберите нужное для себя — либо скорость перерисовки, либо удобное начертание. Для локального InterBase нормальной русской кодировкой является Win1251 — имена доступных кодировок можно найти открыв любую DB InterBase (в т.ч. и локальную) и заглянув в системную таблицу RDB$CHARACTER_SETS.

4. Какую модель данных использует Delphi?

Delphi использует смешанную (mixed) модель памяти, но она очень похожа на модель large в C.С++:

• Методы дальние (far)

• Процедуры, описанные в интерфейсной части, дальние

• Процедуры, используемые только в implementation по умолчанию ближние

• Данные в Heap и все указатели вообще (включая экземпляры объектов) дальние

• Глобальные переменные ближние (в сегменте DS)

• Параметры процедур и локальные переменные ближние (в стеке)

• Процедуры, объявленные far или export дальние

• VMT дальние для новой модели классов и ближние для старой

Эта схема используется в Borland Pascal долгое время.

5. Можно ли использовать в приложении ресурсы, созданные в BPW 7.0?

Все ресурсы, созданные в других приложениях, можно подключить и использовать в Delphi с помощью директивы компилятора и процедур Windows API. Кроме того, меню из файла ресурсов и графические файлы *.BMP, *.ICO и *.WMF можно импортировать в приложение Delphi на этапе разработки. В настоящее время компанией Borland поставляется программный продукт RAD Pack for Delphi, где в состав поставки входит эксперт, позволяющий преобразовывать ресурсы из BP7.0 в формы Delphi.

6. Возможно ли написать Screen Saver для Windows в Delphi?

Для создания программы, работающей как Screen Saver:

1. В проектном файле (*.dpr) напишите после uses; данная директива вставляет указанный текст (SCRNSAVE ) в раздел описания модуля — в данном случае программы. Это главное, что необходимо для того, чтобы Windows распознал программу как Screen Saver.

2. Hа главной форме выключите Border ( BorderStyle=bsNone ) и иконки. Установите свойства Left и Top =0 , WindowState=wsMaximize .

3. В обработчике события OnCreate , установите Application.OnMessage на процедуру деактивации Screen Saver. Установите Application.OnIdle на любую процедуру для рисования на экране.

4. В обработчике OnCreate должна проверяться командная строка на наличие ключей /c и /s. Эти параметры определяют, нужно ли запускать сам Screen Saver или его конфигурацию (/c — конфигурация).

5. Скомпилируйте программу и переименуйте из .exe в .scr ; поместите файл в каталог Windows — Screen Saver должен появиться на панели управления (Control Panel).

7. Как Delphi обрабатывает функции обратного вызова Windows (сallback)?

Точно так же как C: вы можете получить указатель ( far pointer ) на вашу callback процедуру (не забыть при этом обьявить ее с директивой компилятора , либо спецификатором far) и передать этот указатель в Windows. Это все.

Delphi и Visual Basic

1. Есть ли в Delphi эквивалент массива элементов управления из Visual Basic?

Hет. Компоненты Delphi не имеют свойства Index, подобное VB. Однако, имеются три основные причины, почему вы хотите использовать их в VB, и для каждой из них есть решение в Delphi.

Причина 1. Вы хотите использовать один обработчик события для разных компонент на форме.

Это просто. Все, что вы должны сделать — это выбрать тот же самый обработчик для каждой визуальной компоненты. Это лучше, чем в случае с массивом компонент, потому что вы можете одну и ту же процедуру-обработчик события присвоить различным типам компонент; например, кнопка на форме и пункт меню могут вызывать ту же самую функцию для обработки события OnClick .

Причина 2. Вы хотите динамически создавать и уничтожать визуальные компоненты во время выполнения программы.

Это также довольно просто в Delphi. Предположим, что на форме есть кнопка, и, каждый раз когда она нажимается, вы хотите создавать другую кнопку. Следующий пример показывается, как это делать:

procedure TForm1.Button1Click(Sender: TObject);

var

begin

end;

Причина 3. Вам действительно требуется доступ к компонентам по номеру.

Предположим, что вы решили написать игру вроде Реверси в Delphi. Вам нужно разместить 100 объектов TShape на форме, в виде квадрата 10Г—10. Конечно, размещать каждый элемент вручную на экране — задача трудоемкая и неинтересная, при этом, в декларации формы появляется 100 строк кода, которые, в общем-то, не нужны. Вместо этого можно завести массив вроде

Board: array [1..10, 1..10] of TShape; Далее в программе нужно создать каждый из этих объекты, вызвав TShape.Create(FormXX) ; указать вручную начальные установки для них. Кроме того, в свойстве Parent каждого объекта из массива нужно указать ту панель ( TPanel ) или форму, на которой они располагаются. Это нужно для правильной перерисовки объектов.

Если же вы не используете такие большие массивы, т.е., например хотите одинаково реагировать на нажатие 3-5 кнопок с незначительным различием для каждой из них, то можно использовать свойство Tag.

2. Как использовать DLL, написанные в Delphi, например в Visual Basic?

Допустим, вы написали на Delphi DLL и в нем объявили функцию

function DataFileType(lpStr: PChar): Integer; export;

begin

end;

в Visual Basic Вы должны подключить ее как:

Declare Function DataFileType Lib «File.dll» (ByVal lpStr As String) As Integer

а в программе на VB использовать следующим образом:

sVendorName = Mid$(lpVar, 1, nSize)

3. Конвертация TBasicString (VBX) в string.

Я использую VBX и испытываю проблемы с конвертацией TBasicString в string. Как это сделать?

Существует две функции —

• BStrPCopy — принимает Basic string и конвертирует в string

SetBStr — принимает string и возвращает Basic string Действительно, ссылок на эти функции нет в документации, но имена этих функций можно «обнаружить» в VBXCTRL.DCU.

Базы данных

1. Ошибка инициализации BDE ($2C09).

Когда я пытаюсь запустить приложение из Delphi, то получаю ошибку EDatabaseError и сообщение ‘An error occurred while attempting to initialize the Borland Database Engine (Error $2C09)’

Добавьте SHARE.EXE в AUTOEXEC.BAT или добавьте DEVICE=VSHARE.386 в раздел [386Enh] файла SYSTEM.INI и перезагрузитесь.

2. Ошибка при загрузке языкового драйвера.

У меня есть Quattro Pro 6.0 и IDAPI в сети. После установки Delphi и нового IDAPI поверх сетевого IDAPI при запуске Quattro Pro с другой машины я получаю ошибку ‘Could not load Language Driver’ .

Добавьте раздел [Borland Language Drivers] в WIN.INI файл для указания каталога языкового драйвера. Пример:

[Borland Language Drivers]

LDPATH=C:\IDAPI\LANGDRV

3. Что значит ошибка IDAPI $2C08?

‘Cannot load IDAPI01.DLL’ . Убедитесь, что в файле WIN.INI правильно прописаны пути:

[IDAPI]

DLLPATH=C:\IDAPI

CONFIGFILE01=C:\IDAPI\IDAPI.CFG

4. Отличается ли локальный InterBase, встроенный в Delphi 1.0, от InterBase для других платформ, в частности, от InterBase для Windows NT?

16-Разрядный Local InterBase не поддерживает:

• функции, определяемые пользователем.

• сигнализатор событий (event alerters)

• запись через журнал (Write Ahead Log (WAL)

• тип данных массив (Array Datatype)

• ‘отключение’ и ‘включение’ базы данных (database shutdown or restart)

• ведение теневой базы данных (database shadowing)

Все остальные функции поддерживаются, но структура хранения базы на диске не совпадает.

Можно ли поставить локальный InterBase на файл-сервере и, таким образом, получить доступ к нему из многих приложений?

Работать не будет. И не пытайтесь. Для этой цели вам нужен нормальный многопользовательский InterBase.

5. Что насчет VBX-компонентов для работы с данными?

Delphi поддерживает только VBX 1.0. Это значит что VBX для работы с данными ‘не работает’ с Delphi. В общем случае, все, что работает с Microsoft Visual C++, должно работать в Delphi. Кроме того, некоторые VBX достаточно хорошо написаны, так что их можно использовать в Delphi и без обращения к возможностям работы с данными.

Object Pascal и Windows API

1. Можно ли использовать OWL в Delphi?

Можно, если уже существуют свои разработки с использованием OWL. Однако следует обратить внимание, не используются ли слова class, try, except и ряда других — в Delphi они являются зарезервированными. Если же опыта использования OWL не было, то вряд ли имеет смысл использование этой библиотеки — в Delphi существуют свои, более удобные средства для работы с Windows.

Компиляция приложений, написанных на BP7 с использованием OWL.

Компилятор Delphi способен компилировать приложения, написанные на OWL Borland Pascal 7.0. Для компиляции таких приложений в среде Delphi необходимо сделать следующее:

1. Откройте главный файл приложения пунктом меню File|Open Project

2. Добавьте в список используемых модулей uses модуль Messages в тех файлах, где использовался модуль WinTypes . Модуль Messages должен быть указан ранее модуля OWindows , ODialogs или любого другого OWL-модуля.

3. При помощи пункта меню Options|Project Dialog добавьте путь x:\DELPHI\SOURCE\RTL70 к пути поиска модулей данного проекта. Этот каталог должен содержать файлы OWL, измененные для компиляции в Delphi.

Если Вы забыли указать использование модуля Messages , то Вы при компиляции получите сообщение ‘Unknown identifier’ . Указание Messages после модуля OWindows вызовет сообщение ‘Header does not match previous definition’ .

Идентификатор Result теперь используется особым образом внутри тела функций, поэтому их внимательно посмотрите, где этот идентификатор может встречаться. Недопустимо использование перекрывающихся диапазонов в операторе case.

Изменилась реализация StrDispose . Если Вы распределяете память для строки при помощи GetMem , то освобождение этой области памяти при помощи StrDispose вызовет ошибку выполнения ‘Runtime error 203’ . Для распределения памяти для строк следует использовать функции StrAlloc или StrNew . Объекты OWL не ориентированы на обработку исключительных ситуаций, т.е. при возникновении таких ситуаций не происходит отката инициализации объектов. Мы не рекомендуем использование исключения в приложениях с OWL.

Компилятор теперь производит поиск модулей, ресурсов и OBJ файлов по пути, указываемому в каталогах OPTIONS|Project. Путь ‘EXE and TPU directory’ больше не поддерживается. EXE-файлы могут создаваться в ‘Output directory’, а файлы DCU всегда создаются в том каталоге, где находятся соответствующие файлы PAS. Новые модули WinTypes и Messages могут быть скомпилированы BP7. Для этого не требуется включения дополнительных директив $IFDEF (зато там есть $IFDEF WIN32;).

2. Как можно зааллокировать блоки памяти больше, чем 64 Кбайт?

Используйте GlobalAlloc и GlobalLock из модуля WinProcs .

3. GPF в ToolHelp.DLL в Win-OS/2 2.1.

Поставьте FixPack, или сделайте Upgrade на OS/2 Warp 3 FullPack.

4. Как получить из Clipboard текст большого размера?

Да, стандартный метод TClipboard.AsText ограничивает текст размером строки — 255 байт. Для получения текста длиной более 255 байт можно использовать, например следующую процедуру:

procedure GetLargeText: PChar

var

begin

try

Result := nil;

if Buffer <> nil then

begin

с ними как с обычной Null-terminated строкой >

end;

finally

end;

end;

5. Проблемы Delphi с WinG.

Я слышал, что у Delphi проблемы с WinG, однако кто-то их решил?

Да, Майк Скотт (Mike Scott, 100140.2420@compuserve.com) даже написал коммерческий вариант VCL-компонентов, использующих WinG для Delphi:

WinG Sprite Kit.

Набор компонентов, осуществляющих доступ к WinG из Delphi. Включает компоненты TWinGCanvas для рисования TWinGDC и TWinGBitmap , TWinGSurface , которые можно поместить на форму и спрайтовый компонент, который можно помещать на них.

$99 EEP

Существует статья по использованию WinG в Borland Pascal — #5 Pascal Magazine. Обзор VCL WinG появится в новом Delphi Magazine. Отошлите письмо с вашим почтовым адресом на 70630.717@compuserve.com для получения бесплатной копии этих журналов (наверняка из России это не сработает.

Компоненты и VCL

1. Каковы ограничения на стандартные компоненты Delphi?

Все компоненты, использующие TList для сохранения информации, имеют верхний предел 16368 единиц. Hапример, TTabControl может содержать до 16368 закладок и Delphi Component Palette может содержать до 16368 страниц.

Многие из стандартных компонент Delphi являются надстройкой над стандартными управляющими элементами Windows. Windows 3.1 налагает свои собственные ограничения на эти компоненты. Hапример: TComboBox или TListbox могут содержать до 5440 единиц, а TMemo или TEdit (и соответствующие компоненты) — до 32k текста.

Ресурсы Windows 3.1 ограничивают компонент TNotebook 570 страницами. (Трудно получить более 500 хендлов /handles/ окон в любом приложении Windows). Превышение этих границ вызывает ошибку или послужит причиной странного поведения Windows.

2. Предел буфера редактирования в 32K для TMemo.

Почему в документации написано, что TMemo может редактировать тексты до 256К, а на деле получается не более 32К?

В документации ошибка. 32К — это ограничение Windows. В Windows все стандартные редакторы используют общий буфер в 32К, компонент TMemo использует другую технику, позволяющую каждому TMemo иметь буфер в 32К. В Windows 95 эта проблема решена.

3. Почему компонент TGauge так медленно работает (медленнее, чем VBX BGauge)?

Компонент TGauge — просто пример, и ничего более. В нем отсутствует даже намек на оптимизацию перерисовок. Если вы посмотрите на код процедуры SetProgress , то увидите

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

1. Не присваивать Progress каждый раз (напр. 3000 раз), т.е. делать обновление менее часто

2. Проверять, действительно ли позиция на экране изменится. Например, в SetProgress сделать следующее:

if Abs(FCurValue-FLastDrawn) >= FDisplayDelta then

begin

end;

где FDisplayDelta что-то вроде (FMaxValue-FMinValue) div Width (идеально было-бы учитывать реальный размер экрана.

3. Обновлять только часть индикатора, которая действительно меняется. Процедура Refresh стирает и перерисовывает весь компонент. Можно сделать вызов InvalidateRect (Windows API) и вызвать Update .

4. Если вы сделали как в пункте 3, вы дополнительно можете оптимизировать процедуру перерисовки, чтобы не перерисовывать неизменяющийся участок.

Разное

1. Распространение приложений Delphi, использующих Local InterBase.

Для распространения таких приложений, в соответствии с лицензионным соглашением вы должны перенести следующие файлы:

Главные модули (X:\IBLOCAL\BIN)

DSQL.DLL

FILEIO.DLL

GDS.DLL

GBAK.DLL

INTL.DLL

IUTLS.DLL

JRD.DLL

REMOTE.DLL

STACK.DLL

Сообщения, лицензионные файлы и т.п. (X:\IBLOCAL)

INTERBASE.MSG

ISC4.GDB

ISC_LIC.DAT

Утилиты (если они необходимы)

WISQL.EXE

WISQL.HLP

SQLREF.HLP

IBMGR.EXE

SVRMGR.HLP

COMDIAG.EXE

COMDIAG.INI

COMDIAG.HLP

BLINT04.HLP

После копирования этих файлов необходимо проделать следующие операции:

1. Добавить в AUTOEXEC.BAT в команду PATH X:\IBLOCAL\BIN

2. Там же сделать SET INTERBASE=X:\IBLOCAL

3. В WIN.INI создать секцию

[Interbase]

RootDirectory=X:\IBLOCAL

Естественно, если путь к локальному InterBase отличается от IBLOCAL, то вы должны изменить его на нужный.

Илон Маск рекомендует:  Что такое код moverel

Для распространения BDE вы должны передать пользователю две инсталляционные дискеты с редистрибутивным BDE (на CD-ROM каталог REDIST\BDE).

Для установки BDE вручную скопируйте содержимое каталога IDAPI (с подкаталогом языковых драйверов), и создайте в WIN.INI следующие секции:

[IDAPI]

DLLPATH=X:\IDAPI

CONFIGFILE01=X:\IDAPI\IDAPI.CFG

[Borland Language Drivers]

LDPath=X:\IDAPI\LANGDRV

После этого ненужные файлы (неиспользуемых языковых драйверов, поддержку ODBC…) можно удалить с диска, или временно перенести, убедиться в работоспособности приложения, и удалить.

Возникает неясность — как добавить драйвер INTRBASE в IDAPI.CFG? Получается, что его необходимо переносить , и затем настраивать псевдонимы на новые каталоги. Иначе драйвер локального InterBase не попадет в IDAPI.CFG.ы

Вопросы по Delphi 2.0
Что нового в Delphi 2.0 по сравнения с Delphi 1.0?

Выпущенная в феврале 1995 года версия Delphi 1.0 стала первым инструментом для Windows, комбинирующим оптимизирующий компилятор, механизмы визуальной разработки Two-Way-Tools и масштабируемую архитектуру обработки баз данных. Сегодня сотни компаний по всему миру заявляют о многократной окупаемости их инвестиций в информационые системы, построенные с применением Delphi в качестве основного инструмента. Borland Delphi 2.0 полностью поддерживает все особенности новых операционных систем Windows 95 и Windows NT. Новый 32-разрядный оптимизирующий компилятор позволяет увеличить производительность разрабатываемых систем на 300-400 процентов при том, что генерируемый в результате код выполняется в 15-50 раз быстрее, чем в системах на базе P-код интерпретаторов. Новые объектно-ориентированные средства, предназначенные для разработки в архитектуре клиент-сервер, включают централизованное хранилище объектов — Object Repository и механизм визуального наследования форм — Visual Form Inheritance. «Всего за один год Delphi был принят на вооружение заказчиками в силу уникальных возможностей этого продукта, сочетающего высокопроизводительную технологию компиляции с единой средой визуального программирования», — говорит вице-президент Borland по маркетингу (Product Marketing and Management) Ричард Горман (Richard Gorman). «С выпуском новых версий мы расширяем рынок Delphi на всем спектре desktop, сетевых и клиент-серверных инструментов».

Как и в любой новой версии продукта, по сравнению с предыдущей, появилось много изменений.

1. Изменения в компиляторе и RTL

1. Новые типы данных:

• строки и символы поддерживающие произвольную длину и

• вариантные структуры для работы с OLE Automation

• тип Currency — 8-байтное число с плавающей точкой

2. Переменные типа Integer и Cardinal теперь 32-битные (4 байта). Для работы с двухбайтовыми целыми числами необходимо использовать типы SmallInt и Word.

3. Генерация 32-битного кода с оптимизацией циклов, передачей параметров через регистры, и т.п.

2. Новые компоненты:

1. набор компонент, свойственных интерфейсу Windows95

2. компоненты OLE Automation

3. новый DBGrid, позволяющий определять атрибуты столбцов.

3. Изменения в работе с БД

1. локальная фильтрация записей для TTable и TQuery

2. поддержка lookup у TField

3. SQL-монитор, отслеживающий выполнение SQL-операций

4. Модуль Данных (DataModule), для централизованного хранения и использования компонент доступа к базам данных

4. Изменения в среде разработчика (IDE)

1. хранилище объектов (Object Repository) — для хранения проектов, форм, модулей данных и др.

2. визуальное наследование форм

3. визуальное связывание форм

4. Database Explorer

5. Редактор полей таблиц в стиле drag-n-drop

5. Изменения в Borland Database Engine

1. полностью 32-разрядная библиотека доступа к данным

2. новое ядро SQL-запросов

3. расширенные возможности SQL Links

4. транзакции и вложенные запросы для локальных форматов данных (dBase и Paradox)

Вопросы общего характера

1. Какие существуют варианты поставки Delphi 2.0?

Выпущенная 4 февраля 1996 года серия продуктов Delphi 2.0 включает три версии, каждая из которых разработана с учетом различного уровня разработчиков и решаемых ими задач:

• Desktop — для создания автономных программ или для начинающих программистов

• Developer — для профессиональных разработчиков, ориентированных на сетевую архитектуру

• Client/Server Suite — для создания систем в архитектуре клиент-сервер Все версии Delphi 2.0 естественно сочетают высокопроизводительный 32-разрядный компилятор, масштабируемые инструменты доступа к базам данных и расширяемую библиотеку «drag-and-drop» компонент в составе объектно-ориентированной среды визуальной разработки.

Состав версий.

Все версии Delphi 2.0 обладают открытой архитектурой, полностью поддерживающей такие технологии, как OLE server, Microsoft OLE Controls (OCX), ODBC, а также Microsoft’s Remote Automation и ожидаемую Network OLE (ActiveX). Все версии Delphi 2.0 также предоставляют разработчикам поддержку новых особенностей и интерфейсов прикладного программирования (API) Windows 95 и Windows NT — многопоточности (threads), Unicode, MAPI и др. Для облегчения перехода разработчиков из 16-разрядного в 32-разрядное операционное окружение каждая версия Delphi 2.0 включает 16-разрядную версию Delphi 1.02 for Windows.

Delphi Desktop 2.0

Delphi Desktop 2.0 наиболее всего соответствует Delphi 1.0 for Windows и предназначен для начинающих Windows-прогрммистов и индивидуальных разработчиков. Некоторые особенности Delphi Desktop 2.0:

• оптимизирующий 32-разрядный компилятор, увеличивающий производительность существующих приложений на 300-400% (относительно Delphi 1.0).

• среда разработки IDE с интерфейсом в стиле Windows95

• расширяемая объектная архитектура компонент

• визуальное наследование форм

• визуальное связывание форм и компонентов, размещенных на различных формах

• 32-разрядный Borland Database Engine для доступа к БД формата dBase и Paradox, обеспечивает ряд расширений языка запросов SQL, транзакции для локальных форматов данных

• Data Modules (модули данных), позволяющие использовать одни и те же таблицы, запросы и др. источники данных и компоненты из многих форм приложения

• Database Explorer — инструмент разработки и модификации структур и содержимого баз данных в стиле Windows Explorer.

• фильтры для таблиц и запросов, развитые Lookup-списки.

• расширенный Grid-компонент с настраиваемыми атрибутами столбцов и «выпадающими» списками

• компонент Quick Report, позволяющий легко создавать встроенные отчеты без использования ReportSmith.

• тип данных currency (деньги), увеличивающий точность финансовых вычислений

• длинные строки и структуры данных (до 2ГБ)

• 16-разрядная версия Delphi 1.02

• полная документация в 5-и томах (более 1100 страниц) включая полное описание языка.

Delphi Developer 2.0

Delphi Developer 2.0 ориентирован на поддержку профессиональных разработчиков многопользовательских (сетевых) приложений. Версия Developer по сравнению с Desktop имеет следующие расширения:

• хранилище объектов (Object Repository), поддерживающее создание и совместное использование форм, модулей данных и других объектов.

• масштабируемый словарь данных (Data Dictionary), содержащий расширенные атрибуты полей (столбцов), квлючая пределы величин, маски редактирования и отображения, параметры шрифтов и т.п.

• низкоуровневая поддержка Borland Database Engine, включая справочные файлы

• Multi-Object Grid для максимально гибкого прдставления информации в приложениях, работающих с базами данных

• расширенный набор примеров компонент и дополнительные OCX

• дополнительные эксперты, среди которых Installation/Deployment Expert для создания рсапространяемых приложений (дистрибутивов)

• расширенный Open Tools API — набор открытых интерфейсов для интеграции с внешними инструментами (CASE’s, Transaction Process Monitor’s и др.), с помощью которых разработчик может создавать и встраивать в среду (IDE) Delphi свои редакторы компонент и их свойств, эксперты и другие инструменты

• интерфейс к средствам групповой разработки (требует Intersolv PVCS 5.2 или выше)

• локальный однопользовательский сервер InterBase для разработки масштабируемых приложений на отдельном компьютере

• 32-разрядный генератор отчетов ReportSmith 3.0 с расширенными возможностями интеграции с Delphi-приложениями

• новая библиотека математических, статистических и бизнес-функций исходные тексты библиотеки компонент VCL32 (32-bit Visual Components Library)

• 8 томов документации и справочных руководств общим объеком свыше 3000 страниц

Delphi Client/Server Suite 2.0

Delphi Client/Server Suite 2.0 ориентирован на организации, разрабатывающие корпоративные системы, предназначенные для работы с данными, хранимыми на серверах БД Oracle, Sybase, InterBase, Informix, MS SQL Server, DB/2; сочетает высокопроизводительный клиентский инструментарий и широкий спектр средств работы с серверами БД. Версия Client/Server Suite по сравнению с Developer имеет следующие расширения:

• SQL Explorer в стиле Windows Explorer, ориентированный на обработку метаданных серверных БД (доменов, триггеров, представлений, хранимых процедур и т.п.)

• SQL Monitor, предназначенный для тестирования, отладки и настройки SQL-запросов для повышения качества и производительности их выполнения

• Cached Updates (буферизированное обновление) обеспечивает более эффективную обработку транзакций в клиент/серверном окружении.

• неограниченное использование высокопроизводительных драйверов SQL Links для доступа к серверным БД Oracle, Sybase, InterBase, Informix и SQL Server (лицензия на распространение SQL Links).

• SQL-сервер Borland InterBase 4.1 для Windows NT с лицензией на 2-х пользователей.

• ReportSmith 3.0 SQL Edition, предназначенный для построения отчетов при работе в клиент/серверном окружении.

• Визуальный конструктор запросов Visual Query Builder

• DataPump Expert — средство переноса/миграции данных для масштабирования приложений. Интегрированная в среду разработчика система контроля версий Intersolv PVCS.

• 12 томов документации и справочных руководств, общим объемом свыше 3500 страниц.

2. Какие форматы скомпилированных модулей можно получить в Delphi 2.0?

Delphi может создавать EXE- и DLL-файлы для Win 32. Естественно, Вы может также создавать OCX, но для этого нужно знать соглашения по написанию DLL в формате OCX.

Delphi может также создавать 32-разрядные консольные приложения для работы под Win 32.

3. Какую модель данных использует Delphi?

Delphi 2.0 использует так называемую плавающую модель памяти (FLOAT), которая принята в Win 32. Отличительной особенностью данной модели памяти является линейная 32-разрядная адресация всего адресного пространства, которое может иметь соответственно размер до 4 Гбайт. При этом все указатели, адреса процедур, указатели на VMT также адресуются через 32-разрядные регистры.

4. Delphi 2.0 может создавать 16-разрядные приложения?

Delphi 2.0 — это полностью 32-разрядный продукт, который создает приложения, функционирующие под Windows 95 и Windows NT. Но в комплект поставки Delphi 2.0 также входит и текущая 16-разрядная версия Delphi (версия 1.0), предназначенная для создания приложения, работающих под Windows 3.1 (а также Windows 3.11 и др.). Те, разработчики, которые не используют новые специфичные характеристики 32-разрядных операционных систем погут перекомпилировать свои приложения с использованием 16-разрядной версии Delphi.

5. Насколько трудно перенести существующее приложение Delphi в Delphi 2.0?

В большинстве случаев разработчику достаточно просто перекомпилировать свое приложение с помощью нового 32-разрядного оптимизирующего компилятора и сразу же использовать преимущества 32-разрядного кода, что вызывает увеличение производительности до 300-400% под Windows 95 и Windows NT. Тем разработчикам, которые использовали низкоуровневый код, использующий 16-разрядную сегментную архитектуру Windows 3.1, больше не поддерживаемую Windows 95 придется внести соответствующие изменения в коде. Если приложение использует дополнительные компоненты и библиотеки третьих фирм, то следует обратиться к фирме-производителю для получения 32-разрядных версий этих компонентов и библиотек.

6. Каким образом разработчик может использовать новые характеристики Windows 95?

Delphi 2.0 включает в себя множество новых компонентов для поддержи новых специфичных характеристик Windows 95, таких как элементы оформления интерфейса пользователя (включая редактирование текстов в формате RTF), многостраничный диалог и прогресс-индикатор в стиле Windows 95, OLE controls (OCX) и др. Разработчику достаточно просто добавить эти компоненты в свои приложения из палитры компонентов, как и любой другой компонент Delphi. В большинстве случаев, Delphi 2.0 будет автоматически поддерживать новые возможности, например такие как длинные имена файлов, новые диалоги и стили и др. В дополнение ко всему, ввиду того, что Delphi 2.0 компилятор непосредственно в исполняемые коды процессора, разработчики сразу же получают доступ ко всему API Windows 95, включая мультитрединг, строки в формате Unicode, MAPI и др.

7. Delphi 2.0 сертифицировано как продукт под Windows 95?

Да. Delphi 2.0 удовлетворил всем требованиям для сертификации как продукт Windows 95. Кроме того, Delphi 2.0 облегчает разработчикам создание приложений, которые могут быть сертифицированы для использования под Windows 95.

8. Delphi 2.0 поддерживает Windows NT?

Да, Вы можете работать с Delphi 2.0 как под Windows 95, так и под Windows NT и, соответственно, создавать приложения, которые будут работать под обеими платформами. При этом имейте ввиду, что не все функции Win 32 API могут работать на обоих платформах, например, в Windows 95 не реализованы сервисы и др. системные функции — но это уже проблема не Borland, а Microsoft.

9. Delphi 2.0 поддерживает OLE controls (OCX) и OLE automation?

Да. Delphi 2.0 полностью поддерживает OCX и OLE automation. Разработчики могут инсталлировать OLE controls на соответствующие страницы палитры компонентов или использовать уже поставляемые с Delphi 2.0. Также, разработчик может использовать OLE automation для того, чтобы создавать приложения, которые управляют другими приложениями, такими как Microsoft Word, Excel, Lotus 1-2-3, Borland C++, Paradox и др. OLE automation в Delphi полностью совместима дальнейшем развитием OLE — Network OLE а также с технологией удаленной автоматизации (remote automation), включенной в VB4, используя все преимущества оптимизирующего компилятора.

10. Delphi 2.0 поддерживает in-process (DLL) или out-of-process (EXE) серверы в OLE automation?

Delphi 2.0 полностью поддерживает эти два типа локальных серверов OLE automation.

11. Delphi 2.0 поддерживает другие виды взаимодействия между приложениями?

Да. Delphi взаимодействует с некоторыми мониторами выпонения транзакций (transaction processing — TP), включая Novell Tuxedo, TransArc Encina, CICS и др. Как правило, эти продукты оформлены в виде DLL и могут вызываться непосредственно из приложения. Кроме того, Borland состоит в Object Management Group (OMG) и планирует в будущем обеспечить поддержку CORBA.

12. Delphi 2.0 поддерживает мультитрединг?

Да. Так как Delphi компилирует непосредственно в коды команд процессора, приложению написанному на Delphi доступны все возможности API Windows 95 и Windows NT. Библиотека Визуальных Комонентов (VCL) также включает объект TThread для создания надежных приложений.

13. Delphi 2.0 совместима с Network OLE?

Да. Так как Delphi 2.0 полностью поддерживает OLE automation как серверы, так и контроллеры, данный вариант OLE полностью совместима в будущем с Network OLE. Также Delphi полностью поддерживает технологию удаленной автоматизации, включенной в VB 4.0 со всеми дополнительными преимуществами оптимизирующего компилятора.

14. Существует ли upgrade Delphi 2.0?

Да. Borland предлагает специальные цены для тех заказчиков, которые являются легальными пользователями Delphi версии 1.0.

15. Насколько успешны продажи Delphi на сегодняшний день?

Продажи Delphi и Delphi Client/Server на данный момент даже превосходят прогнозы, сделанные фирмой Borland. Delphi играет значительную роль как в разработке отдельных, независимых приложений, так и в разработке приложений по технологии клиент-сервер. По результатам опросов и тестов Delphi присуждено множество наград, в т.ч.:

• BYTE Best Technology of Comdex 1994 for best development/system software

• PC Week Labs Analyst Choice Award

• PC Magazine Top Ten Selling Products

• PC Magazine Technical Excellence Award

• PC Magazine Product of the year for 1995

• Computer Daily News (Australia), Top Ten Selling Products

• PC Magazine (UK) Grey Matter Award for the number-one selling software product

• PC World (Spain) Product of the Year for programming languages

• PC/Computing Excellence Award

• DBMS Reader’s choice award

• Best of LAN Times

• Windows Tech Journal Star Tech award

• Ziff-Davis Cannes Software Excellence Award, Overall Technical Excellence

• Ziff-Davis Cannes Software Excellence Award, Languages and Tools

• Visual Basic Programmer’s Journal Editor’s Choice

16. Насколько полно Borland предлагает стратегические решения тем компаниям, которым требуется дополнительная помощь в разработке клиент-серверных приложений?

В первом квартале 1996, Borland представил новую программу Premier Partner VAR, где главный акцент делается на решения в рамках технологии клиент-сервер. Эта программа будет играть важную роль в дополнении комплекта Delphi Client/Server Suite средствами, предназначенными для основных вариантов разработок по технологии клиент-сервер.

17. В чем заключаются преимущества 32-разрядного компилятора в родной код микропроцессора?

Используя новый оптимизирующий компилятор в 32-разрядный код Delphi 2.0 генерирует приложения, превосходящие по своим качествам интерпретаторы p-кода, такие как Visual Basic и PowerBuilder. На данный момент приложения, произведенные с помощью Delphi 1.0 выполняются примерно в 10-20 раз быстрее интерпретаторов p-кода. Предполагается дополнительное увеличение этого показателея в 32-разрядной версии. Новый оптимизирующий 32-разрядный компилятор в Delphi 2.0 использует один и тот же генератор кода, что и Borland C++ и включает множество видов оптимизации, таких как оптимизация использования регистров, оценка общих частей выражений оптимизация использования переменных и генерация кода, оптимированного для выполнения на процессоре Pentium для получения более компактного и быстрого кода. Приложения перекомпилированные во второй версии меньше по размерам и работают быстрее, чем раньше. Ввиду нового кодогенератора появились возможности не только использовать, но и создавать OBJ-файлы для более легкого переноса кода между Delphi и C/C++. Кроме того, сейчас компилятор выдает более информационные сообщения об ошибках, равно как и предупреждения и советы о некорректном коде, неиспользованных или используемых до инициализации переменных и др.

18. Насколько быстрее работают приложения, скомпилированные новым компилятором?

Тестовые испытания показали, что код, полученный при помощи Delphi 2.0 работает в среднем на 300-400% быстрее, чем 16-разрядные приложения. Это означает, что новые приложения будут работать в 15-50 раз быстрее, чем интерпретаторы p-кода. Например, тесты Sieve (что такое — не знаю) показали, что Delphi 2.0 работают в 15 раз быстрее, чем VB 3.0 и в 815 раз быстрее, чем PowerBuilder 4.0.

Ниже приводятся результаты тестирования 16- и 32-разрядных версий Delphi. Все тесты выполнялись на Gateway 2000 V66 (66MHz, процессор 486) с 16Mb памяти. 16-разрядные тесты выполнялись под Windows 3.1. Новые 32-разрядные тесты были выполнены с использованием пре-релиза Delphi 2.0.

Большее число означает большую производительность

Power Builder Visual Basic Delphi 1.0 Delphi 2.0
Sieve 0.22 11.95 52.77 179.37
Whetstone 0.04 1.41 4.70 15.53
File read 0.05 0.42 0.74 2.89
File write 0.05 0.33 1.75 5.28

19. Какой вид коллективной работы над проектом поддерживает Delphi 2.0?

Delphi Client/Server Suite 2.0 использует Open Tools API для тесной интеграции с системой контроля версий Intersolv PVCS (сама система входит в комплект поставки) для работой с файлами. Delphi Developer 2.0 также имеет интерфейс к Intersolv PVCS, но не включает саму систему PVCS. Благодаря Open Tools API, разработчики могут самостоятельно подключать другие системы контроля версий, такие как MKS Source Integrity, Microsoft Source Safe и др.

20. Насколько Delphi Client/Server Suite 2.0 сравним с PowerBuilder?

Delphi Client/Server Suite 2.0 включает в поставку большой диапазон средств, которые имеются в PowerBuilder и предлагают профессиональным разработчикам приложений по технологии клиент-сервер все, что им требуется для построения надежных, мощных приложений по технологии клиент-сервер. Кроме того, предлагаются дополнительные средства, такие как SQL Explorer для просмотра мета-данных на сервере, таких как сохраненные процедуры, триггеры и обработчики событий, SQL Monitor для тестирования и отладки SQL запросов, поддержка командной работы над проектом со встроенным PVCS, расширенный Open Tools API для интеграции с CASE-средствами и версия InterBase под NT с 2-мя пользовательскими лицензиями. Также новый Borland Database Engine поддерживает буферизированное обновление, что существенно облегчает создание высокопроизводительных многозадачных приложений. Delphi остается единственным стредством, совмещающим преимущества оптимизирующего компилятора в родной код, визуального проектирования и технологии масштабируемой работы с базами данных.

Хотя компания PowerSoft и опубликовала планы реализации генератора C кода с возможностью последующей его компиляции в середине 1996 года, он не сможет по производительности, простоте отладки и интеграции в среде превзойти Delphi, который основан на 10-летней технологии производства компиляторов.

21. Насколько Delphi 2.0 сравним с Visual Basic 4.0?

Новый 32-разрядный оптимизирующий компилятор в Delphi 2.0 обеспечивает даже более высокие показатели, чем интерпретатор p-кода в VB 4.0. Кроме того, Delphi 2.0 предлагает более полный доступ к возможностям Windows 95 и NT вместе с поддержкой мульти-трединга и строк Unicode в дополнение к OLE Controls (OCX) и OLE automation. На самом деле, Delphi 2.0 может использовать все преимущества технологии удаленной автоматизации, включенной в VB 4.0 с дополнительным увеличением в скорости.

Delphi 2.0 превосходит VB также в поддержке дополнительных средств технологии клиент-сервер, таких как Database Explorer, Object Repository и Data Dictionary. Также Delphi 2.0 предлаагет много нововведений, таких как визуальное наследование форм и др.

Delphi остается единственным стредством, совмещающим преимущества оптимизирующего компилятора в родной код, визуального проектирования и технологии масштабируемой работы с базами данных. VB 4.0 получил очень среднюю оценку от заказчиков как просто некий 32-разрядный вариант предыдущей версии. VB 4.0 так и не использует основные возможности, такие как компилятор родного кода и настоящее объектно-ориентированное программирование.

Базы данных

1. В чем заключаются преимущества нового 32-разрядного Borland Database Engine?

Новый 32-разрядный Borland Database Engine включает полностью новое ядро запросов, которое было оптимизировано для работы как с удаленными SQL-серверами, так и с локальными данными. 32-разрядный Borland Database Engine использует все преимущества 32-разрядного адресного пространства и асинхронный 32-разрядный ввод/вывод для повышения характеристик. Он также включает новые виды оптимизации, специфичные для конкретных серверов и форматов локальных баз данных. Например, новые 32-разрядные SQL-линки включают многие виды оптимизации для Oracle, Sybase, Informix и InterBase. Новый BDE поддерживает буферизированное обновление для улучшения характеристик выполенний транзакций в приложениях, интенсивно работающих с данными на сервере без требуемого ранее блокировния используемых ресурсов на последнем. Кроме того, дополнительно поодерживаются транзакции на локальных данных и новое ядро запросов более полно реализует стандарт ANSI SQL-92 DML compliance. Новый Borland Database Engine поддерживает Data Dictionary для хранения расширенных аттрибутов данных, таких как минимальное и максимальное значения, маски для редактирования и вывода и др. Delphi также включает новую 32-разрядную версию локального сервера InterBase Server для более полной возможности масштабирования приложений в возможность использования любого другого ANSI SQL 92 сервера.

2. Что такое сервер InterBase?

InterBase это высокопроизводительный SQL сервер фирмы Borland выпускаемый под различные платформы. InterBase доступен для более чем 15 операционных систем, включая: Windows 3.1, Windows 95, Windows NT, NetWare, SCO, Sun OS, Sun Solaris, HP-UX, IBM AIX, SGI IRIX, и множество других Unix платформ.

3. Что такое локальный (Local) InterBase?

Это однопользовательская версия InterBase, включенная в Delphi Developer 2.0 и Delphi Client/Server Suite 2.0. Local InterBase дает возможность разработчикам тестировать свои приложения без привлечения настоящего SQL-сервера, но в то же время используя стандарт ANSI 92 SQL. Локальные InterBase имеет все те же основные возможности, что и многопользовательская версия InterBase доступная под NT и Unix, включая управление транзакциями, сохраненные процедуры, триггеры и обработчики событий.

С помощью локального InterBase разработчики на Delphi получают возможность тестировать свои настоящие клиент-серверные приложения на одном рабочем месте. Это означает возможность работы на laptop-е во время поездок либо использование баз данных, которые очень быстро меняют свою структуру. В отличие от других серверов, InterBase имеет один и тот же API для всех 15, так что приложение, работающее с локальным InterBase будет работать и с любой Unix или NT версией InterBase сервера без каких-либо модификаций.

4. В 32-разрядной версии локального Local InterBase были сделаны какие-либо улучшения?

Да, новая 32-разрядная версия локального InterBase предлагает значительное улучшение характеристик 16-разрядной версии. Также предлагается исключительный интерфйес Windows 95 GUI, включая 32-разрядные средства — Server Manager и Interactive SQL, и полную on-line документацию.

5. Как следует распространять приложения Delphi, использующие InterBase?

Используя Delphi Client/Server Suite 2.0, разработчик может проектировать и тестировать свое приложениe, используя связку Delphi/InterBase на одном рабочем месте. После того, как приложение закончено, просто покупается и инсталлируется требуемая версия InterBase с нужным количеством клиентских лицензий. Данные просто переносятся на сервер, после чего приложение готово к работе. Характеристики InterBase аналогичны для всех платформ — Windows 95, NT и Unix, так что не имеет значения, с какой операционной средой работает сервер. Кроме того, Delphi Developer 2.0 и Delphi Client/Server Suite 2.0 включают InstallShield Express — средство для создания инсталляторов.

6. Насколько InterBase сравним с Watcom SQL?

Характеристики InterBase и Watcom SQL во многом схожи, например в наличии хранимых процедур, триггеров и полного котроля за транзакциями. Однако, InterBase полностью реализует ANSI SQL 92, поддерживает событийную систему на сервере для программирования событийно — управляемых приложений и одновременную модель работы для многопользовательского доступа. Watcom не реализует полностью ANSI 92, не поддерживает события на сервере и имеет полность другое ядро, чем Sybase. Аналогично, InterBase масштабирует с 16-разрядной операционной системы Windows в Unix и имеет один и тот же интерфейс [API] для всех платформ. Watcom не имеет Unix-версий и имеет различные API для всех версий Sybase. Следовательно, если приложение разрабатывается с использованием Watcom API для Windows 3.1, Windows 95, или NT, они должны полностью переписывать свое приложение при изменении целевой платформы. InterBase обеспечивает полностью переноимые, масштабируемые решения для разработчиков клиент-серверных приложений. Наконец, в отличие от блокироки сираниц в Sybase System 11, InterBase предлагает блокировку запись в соответствии с архитектурой множественных поколений записей.

7. Что следует предпочесть разработчику в Delphi: SQL RDBMS, подобный InterBase или базу данных PC LAN, подобно dBase или Paradox?

Для небольших приложений, примерно до 12 одновременно работающих пользователей, использование БД PC LAN таких как dBase или Paradox даст максимально высокую производительность. SQL RDBMS, аналогичные InterBase, проявляют свои преимущества при более чем 10 пользователях и при высоких требованиях к одновременной многопользовательской работе, а также высокой степени сохранности данных. Клиент-серверные приложения позовляют также манипулировать данными больших размеров (20Mb — 20Gb) которые в другом случае вызвали бы слишком медленную работу вследствие взаимного блокирования файлов на файл-сервере и высокого сетевого траффика.

8. Почему я не могу создать в Local InterBase таблицу с кодовой страницей, отличной от страницы по умолчанию?

Этот случай наблюдается, когда полный путь к каталогу, где находится Local InterBase 32 содержит хотя бы один символ пробела (что предлагается по умолчанию). Ошибка официвльно признана Borland и будет устранена в ближайших следующих версиях Delphi 2.0, а тем, кто приобрел текущий вариант Delphi следует перенести IB в другой каталог (например, C:\INTRBASE) и перенастроить пути, либо полностью переставить Delphi с учетом данного требования.

Object Pascal и Windows API

1. Что такое Open Tools API? Насколько он улучшен?

Delphi разработан с учетом Open Tools API, который предоставляет средства интеграции средств третьих фирм, таких как систем контроля версий (Version Control System — VCS), CASE-средств, экспертов и т.д. В версии Delphi 2.0, Open Tools API был расширен с целью увеличить уровень интеграции в отношении работы с файлами, редактором и др. Эта технология идет дальше Microsoft’s Source Code Control (SCC) API для того, чтобы обеспечить более общие возможности интеграции. В данное время Borland ведет работу с большим количеством дополнительных третьих фирм над улучшением взаимодействия с ведущими средствами CASE-проектирования, таких как Popkin System Architect, Sybase S-Designor, CSA SilverRun, LBMS и FMI Select Tools Enterprise и др.

Разное

1. Как ReportSmith 3.0 взаимодействует с Delphi?

Новая 32-разрядная версия ReportSmith 3.0 предлагает более тесную взаимосвязь со средой Delphi и способна работать с любым источником данных, используемом в Delphi, таких как TQuery или TTable . ReportSmith поддерживает создание сложных запросов в среде клиент-сервер и способен функционировать с приложением любой сложности. Delphi 2.0 также включает набор компонетов TQuickReport для встраивания отчетов непосредственно вовнутрь приложения.

2. Каким образом можно разделять Delphi 2 Object Repository между несколькими машинами?

Для этого следует используя Regedit в Registry в секции

HKEY_USERS\.Default\Software\Borland\Delphi\2.0\Repository

завести строковую запись BaseDir и в ней указать путь к вашему репозитарию (в том силе и сетевой).

Вопросы по Delphi 3.0
Вопросы общего характера

1. Какие существуют варианты поставки Delphi 3.0?

Анонсировано три варианта поставки Delphi, каждый из которых предлагает комплект решений для разного уровня разработчиков и решаемых ими задач.

Все версии Delphi 3.0 включают в себя высокопроизводительный 32-разрядный оптимизирующий компилятор, масштабируемые средства доступа к данным, расширяемую библиотеку компонентов, объединенные единой объектно-ориентированной средой разработки.

Состав версий.

Все версии Delphi 3.0 обладают окрытой архитектурой, полностью поддерживают технологии Microsoft OLE Automation, OCX, ODBC, ActiveX. Компонентная модель COM/DCOM поддерживается на уровне компилятора. Компилятор позволяет вам иметь доступ ко всем ресурсам операционных систем, реализующих Win 32 (Windows 95 и Windows NT) и использовать все имеющиеся технологические стандарты — Unicode, MAPI, ISAPI, NSAPI. Как в версии 2.0, в поставку включается 16-разрядная версия Delphi 1.02.

Delphi Standard 3.0

Delphi Standard 3.0 ориентирован на разработчиков в основном отдельных приложений с использованием настольных баз данных. Основные характеристики варианта Standard:

• Профессиональная среда разработки, включающая в себя полностью интегрированный отладчик и редактор

• Интегрированный в среду 32-разрядный оптимизирующий компилятор

• Возможность создания DLL и отдельных исполняемых EXE-файлов

• Возможность создания очень легких EXE с использованием настраиваемой технологии pakeges.

• Полный доступ к Win32 API, поддержка ActiveX, OLE, OLEDB, COM, DCOM, MAPI, ISAPI, NSAPI

• Создание и отладка многопоточных приложений под Windows 95 / Windows NT

• Наличие Delphi 1.0 для создания 16-разрядных приложений под Windows 3.1

• Объектно-ориентированная расширяемая компонентная архитектура

• Наличия репозитария объектов для хранения и повторного использования форм, модулей данных

• Поддержка визуального наследования и визуального связывания форм для уменьшения размера вводимого кода и более простого управления

• Полный набор новейших управляющих элементов Windows 95

• Визуальная библиотека компонентов (VCL) с более чем 100 компонентами, доступными для повторного использования методом ‘drag-and-drop’

• Встроенный генератор отчетов, состоящий из компонентов, позволяющий создавать, просматривать и печатать отчеты без использования дополнительных внешних программ

• Поддержка COM и интерфейсов на уровне языка и компилятора

• Полная поддержка серверов и контроллеров OLE Automation

• Визуальное создание шаблонов для новых компонентов

• Упрощение кодирование и завершение кода с помощью CodeTemplates wizard, CodeCompletion wizard и CodeParameter wizard

• Быстрое вычисление выражений в ToolTip окошке для облегчения процесса отладки Отладка DLL для сокращений времени на разработку и отладку DLL

• Поддержка механизма многих источников данных для быстрого доступа к данным в любой СУБД

• Высокопроизводительные родные драйвера для доступа к данным MS Access, FoxPro, Paradox, dBase

• Компоненты для работы с данными для построения высокопроизводительных приложений, работающих с базами данных

• Увеличение скорости обмена с сервером за счет поддержки Cashed Updates

• Выделение бизнес логики в отдельный модуль данных

• Визуальное упраление базами данных с помощью Database Explorer

Delphi Professional 3.0

Delphi Professional 3.0 предназначается для разработчиков многопользовательских приложений. Данная версия включает в себя все, что имеется в Delphi Standard плюс:

• Исходный код VCL и печатные материалы для более качественного создания собственных компонентов

• Компоненты для построения графиков и диаграмм на основании данных, хранящихся в таблицах баз данных

• Визуальное создание элементов ActiveX для приложений, ориентированных на Web

• Визуальное создание элементов ActiveX для повышения степени повторного использования кода

• Полная поддержка доступа к данным через ODBC

• Обеспечение целостности данных с помощью Data Dictionary

• Возможность создавать и тестировать приложения, работающие с Local InterBase (одна пользовательская лицензия)

• Internet Solutions Pack для создание приложений, использующих ресурсы Web

• Install Shield Express для создания профессиональных инсталляторов

• Open Tools API для интеграции с вашими дополнительными утилитами

Delphi Client/Server Suite 3.0

Delphi Client/Server Suite 3.0 ориентирован на организации, разрабатывающие корпоративные системы, предназначенные для работы с данными, находящимися в базах данных серверов DB/2, Informix, Interbase, MS SQL Server, Oracle, Sybase. Сочетает в себе высокопроизводительный клиентский инструментарий и широкий набор средств работы с серверами БД. По сравнению с версией Client/Server Suite имеет следующие расширения:

• Набор компонентов DecisionCube для облегчения анализа данных, имеющих множество размерностей

• Высокопроизводительные SQL Links с неограниченной лицензией для доступа к данным Oracle, Sybase, Informix, MS SQL Server, InterBase, DB/2

• BDE Driver Development Kit для открытого доступа к любым механизмам баз данных через BDE

• Визуальное управление метаданными SQL сервера, включая хранимые процедуры и триггеры, с помощью SQL Database Explorer

• Тестирование, отладка и настройка производительности приложений, использующих средства SQL с помощью SQL Monitor

• Автоматическое создание правильных SQL выражений с помощью Visual Query Builder

• Возможность создавать и тестировать приложения, работающие с InterBase NT (четыре пользовательских лицензии)

• Легкое деление приложений на отдельные части при помощи Remote DataBroker

• Управление целостностью данных при помощи ConstraintBroker

• Высокоскоростное представление данных через WebServer

• Открытые решения для поддержки Netscape NSAPI и Microsoft ISAPI при помощи WebBridge

• Централизованная обработка информации при помощи WebModule и обработка запросов при помощи WebDispatch

• Распространение тонких клиентов, которым не требуется дополнительно ничего (даже BDE), использу WebDeploy

• Встроенный менеджер версий Intersolve PVCS для групповой разработки

• Эксперт для интеграции с CASE-средствами

• Data Pump эксперт для быстрого масштабирования приложений

2. Какие форматы скомпилированных модулей можно получить в Delphi 3.0?

Delphi может создавать EXE и DLL для Win32. Естественно, вы может также создавать OCX, но для этого нужно знать соглашения по написанию DLL в формате OCX.

Delphi может также создавать 32-разрядные консольные приложения для работы под Win32.

Вы можете создать package — это тоже DLL, но с некоторыми особенностями.

Если вы создаете ActiveX, то у вас появится файл с расширением DLL, который вы можете при желании переименовать в ActiveX. Также у вас автоматически появится файл TLB — это библиотека типов (Type Library), необходимая для поддержки нестандартных типов данных. Кроме того, вы можете создать TLB файл отдельно.

3. Какую модель данных использует Delphi?

Delphi 2.0 использует так называемую плавающую модель памяти (FLOAT), которая принята в Win 32. Отличительной особенностью данной модели памяти является линейная 32-разрядная адресация всего адресного пространства, которое может иметь соответственно размер до 4 Гбайт. При этом все указатели, адреса процедур, указатели на VMT также адресуются через 32-разрядные регистры.

Object Pascal и Windows API

1. Каким образом реализована поддержка COM/DCOM?

В языке Object Pascal появилось понятие интерфейса (interface). Описание интерфейса похоже на описание обычного класса, в нем не может быть указан спецификатор видимости. Список членов ограничен методами и свойствами, для чтения/записи которых используются методы. Поля в интерфейсе недопустимы. Типы параметров и возвращаемых значений ограничены типами, допустимыми в COM/DCOM, их полный перечень можно найти в on-line help.

Интерфейсы могут наследоваться, в соответствии с идеологией COM, допускается только одиночное наследование. Класс может реализовывать несколько интерфейсов, в этом случае он должен объявить методы, которые по типу параметров и возвращаемых значений совпадают с описанием методов соответствующего интерфейса.

Все интерфейсы имеют в качестве базового класса интерфейсный тип IUnknown , объявленный в модуле System следующим образом:

IUnknown = interface

function QueryInterface(const IID: TGUID; out Obj): Integer; stdcall;

function _AddRef: Integer; stdcall;

function _Release: Integer; stdcall;

end;

Для поддержки OLE Automation также в модуле System имеется интерфейс IDispatch :

function GetTypeInfoCount(out Count: Integer): Integer; stdcall;

function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): Integer; stdcall;

function GetIDsOfNames(const IID: TGUID; Names: Pointer;

NameCount, LocaleID: Integer; DispIDs: Pointer): Integer; stdcall;

function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;

Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): Integer; stdcall;

end;

Для облегчения работы с COM имеется класс TInterfacedObject , который реализует методы, объявленные в интерфейсе IUnknown .

2. В Delphi 3.0 допускается множественное наследование классов?

Нет, нет и еще 1024 раза нет. Язык Object Pascal в Delphi 3.0 не позволяет вам наследовать класс от более чем одного класса. Строго говоря, вы всегда наследуете ваш новый класс ровно от одного уже имеющегося. Если вы явно не указываете базовый класс, то им становится TObject , стоящий таким образом в иерархии вообще всех классов.

Слухи о множественном наследовании идут из-за того, что в языке Object Pascal в Delphi 3.0 реализована поддержка интерфейсов для модели COM/DCOM. При этом новый класс может наследоваться от одного класса и реализовывать произвольное количество интефейсов. Соответствующее объявление нового типа:

TNewObject = class(TBaseObject, ISomeInterface, IAnotherInterface, IDummyInterface)

вызывает некоторую путаницу и может быть похожа на множественное наследование. Здесь можно провести анологию с языком Java. Интерфейсы в Delphi 3.0 похожи на интерфейсы в Java с отличием в том, что Java допускает множественное наследование интерфейсов, а Delphi — нет.

Фактически объявление интефейса представляет из себя кусочек таблицы виртуальных методов (VMT), который присоединяется к основной VMT класса.

[1] использовались только версии ODBC 2.0 и Access 2.0.

[2] Local InterBase — однопользовательский SQL сервер базы данных. Версия, включенная в Delphi Desktop, предназначается для использования разработчиками, которые хотят разрабатывать SQL приложения (для последующего переноса их в среду клиент/сервер) без покупки собственной (дорогой) платформы сервера. Однако, Delphi Desktop не включает права распространения на Local InterBase. Если вы хотите распространять однопользовательское приложение, которое его использует, вы должны заплатить дополнительно за deployment kit.

[3] Версия ReportSmith из Delphi Desktop специально обнаруживает и исключает из списка возможных соединений любой ODBC драйвер к удаленному серверу данных. Да, вы не ослышались. Даже если вы купили ODBC драйвер третьей фирмы, и даже если вы можете прекрасно общаться с этим драйвером из Delphi, ReportSmith еще не будет с ним работать. Если вы хотите сделать это без покупки Delphi Client/Server, вы может купить ReportSmith/SQL отдельно за $300 (и тем не менее приобретете ReportSmith версии 2.0, а не 2.5, как в поставке Delphi Client/Server).

Borland delphi 4 0 для начинающих создание элементов управления activex

Все, что необходимо начинающему и опытному программисту

Создание и регистрация управляющих элементов ActiveX

Нет ничего более простого и, одновременно, наиболее поражающего воображение программистов со старой практикой С++, чем создание управляющих элементов ActiveX (так называемых ActiveX Controls) из современных инструментальных средств программирования, таких как Delphi или Visual Basic. Современным разработчикам вовсе нет никакой необходимости досконально понимать сложную структуру встроенных интерфейсов, порой они даже не знают, что такое интерфейс iunknown и зачем нужны функции AddRef, Release и Queryinterface. Зачем им это? Теперь все за них проделывают встроенные в современные RAD-системы «мастера» и шаблоны.

Порой программисты вовсе не задумываются, какую работу проделывают за них TCP/IP и RPC, когда части приложения распределяются сразу на несколько систем при помощи «мастеров развертывания и инсталляции». Впрочем, об этом позже. Что же касается управляющих элементов ActiveX, то они являются первоосновой компонентного проектирования и программирования. Именно поэтому разработчики RAD-систем предельно облегчили работу по созданию таких строительных компонентов, из которых они и сами состоят почти на 80 процентов. Как создать и зарегистрировать на локальной, либо удаленной машине ActiveX-элемент, выполняющий некоторую полезную работу и который только при помощи буксировки с помощью мыши можно перетащить на палитру компонентов в RAD-системах или встроить в любое приложение, не исключая и Web-страницы, да так, чтобы его можно было сразу использовать? Как сделать, чтобы этот OCX-элемент мог загружаться и выполнять свою работу из браузера?

Предположим, вам очень часто приходится писать Интернет-приложения, в которых на Web-странице должно появляться окно со списком всех доступных на этой машине шрифтов. Не будете же вы, в самом деле, постоянно включать функцию на каком-нибудь JavaScript в каждый HTML-файл. Гораздо легче написать управляющий ActiveX-элемент. Попробуем сделать это на Visual Basic 6. Тут даже и программировать-то ничего не нужно. Запустим VB, выберем шаблон для приложения с элементом управления ActiveX и создадим в пустой форме стандартный элемент ListBox, также с помощью специального ActiveX- компонента, находящегося на стандартной палитре компонентов Visual Basic (рис. 1.7).

Рис. 1.7. Окно проекта для создания управляющих элементов ActiveX в VB 6

В свойствах ToolboxBitmap мы можем выбрать желаемую пиктограмму, в качестве которой создаваемый компонент будет присутствовать на палитрах компонентов в любой RAD-системе, в которой вы пожелаете его иметь. Далее нужно связать с этим компонентом какой-либо код. В нашем случае код должен быть самым примитивным — заполнение окошечка ListBox списком присутствующих на машине шрифтов. Программировать ничего не будем, возьмем стандартный код из примеров справочной системы VB 6 и «зальем» его в окно Modulel, который предварительно создадим по команде Project-> Add Module. Ниже приведен этот код.

‘Font enumeration types
Public Const LF_FACESIZE = 32
Public Const LF_FULLFACESIZE = 64
Type LOGFONT
lfHeight As Long
IfWidth As Long
lfEscapement As Long
lfOrientation As Long
lfWeight As Long
IfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
IfPitchAndFamily As Byte
IfFaceName(LF_FACESIZE) As Byte
End Type

Type NEWTEXTMETRIC
tmHeight As Long tmAscent As Long
tmDescent As Long tmlnternalLeading
As Long tmExternalLeading As Long
tmAveCharWidth As Long tmMaxCharWidth As Long
tmWeight As Long tmOverhang As Long
tmDigitizedAspectX As Long tmDigitizedAspectY As Long
tmFirstChar As Byte tmLastChar As Byte
tmDefaultChar As Byte tmBreakChar As Byte
tmltalic As Byte tmUnderlined As Byte
tmStruckOut As Byte tmPitchAndFamily As Byte
tmCharSet As Byte ntmFlags
As Long ntmSizeEM As Long
ntmCellHeight As Long
ntmAveWidth As Long
End Type

‘ ntmFlags field flags Public Const NTM_REGULAR = &H40& Public Const
NTM_BOLD = &H20& Public Const NTM_ITALIC = &H1&
‘ tmPitchAndFamily flags Public Const TMPF_FIXED_PITCH = &H1 Public
Const TMPF__VECTOR = &H2 Public Const TMPF_DEVICE = &H8 Public Const
TMPF_TRUETYPE = &H4
Public Const ELF_VERSION = 0 Public Const ELF_CULTURE_LATIN = 0
‘ EnumFonts Masks
Public Const RASTER_FONTTYPE = &H1
Public Const DEVICE_FONTTYPE = &H2
Public Const TRUETYPE_FONTTYPE = &H4
Declare Function EnumFontFamilies Lib «gdi32» Alias
«EnumFontFamiliesA»
(ByVal hDC As Long, ByVal IpszFamily As String, _ ByVal
IpEnumFontFamProc As Long, LParam As Any) As Long Declare Function
GetDC Lib «user32» (ByVal hWnd As Long) As Long Declare Function
ReleaseDC Lib «user32» (ByVal hWnd As Long, _ ByVal hDC As Long) As Long
Function EnumFontFamProc(lpNLF As LOGFONT, lpNTM As NEWTEXTMETRIC,
ByVal FontType As Long, LParam As ListBox) As Long Dim FaceName
As String Dim FullName As String
FaceName = StrConv(lpNLF.IfFaceName, vbUnicode)
LParam.Addltem Left$(FaceName, InStr(FaceName, vbNullChar) —1)
EnumFontFamProc = 1 End Function
Sub FillListWithFonts(LB As ListBox) Dim hDC As Long LB.Clear
hDC = GetDC(LB.hWnd)
EnumFontFamilies hDC, vbNullString, AddressOf EnumFontFamProc, LB
ReleaseDC LB.hWnd, hDC End Sub

Код интересен тем, что он работает с WinAPI 32 и использует его стандартные функции, что само по себе в VB очень и очень привлекательно, ибо наделяет его необыкновенной мощью при использовании стандартных библиотек Windows, таких как GDI32.DLL, USER32.DLL, но нам сейчас гораздо интереснее другое — как упаковать это в переносимый, пригодный для повторного использования и применения где угодно, даже на Web- страницах Интернета новый ActiveX-элемент? Нет ничего проще.

Продолжим работу в VB 6. После того как мы «залили» код в модуль, можно закрыть окно UserControl, и вы тотчас увидите выбранную вами пиктограмму в палитре инструментов. В окне UserControll в параметре initialize добавим строку Moduiei.FiiiListwithFonts Listi. Стандартная процедура должна выглядеть так, как показано на рис. 1.8.

Рис 1.8. Вызов функции модуля, реализующего функцию Windows API.

Ну вот и все, можно поздравить вас — вы создали первый ActiveX-элемент. Выполнить его непосредственно из Бэйсика еще нельзя, хотя можно сохранить под любым именем (расширение .осх файлу присвоится автоматически), но пока не будем делать этого, потому что такой шаг неизбежно связан с регистрацией нового элемента в системе (о ней мы расскажем позже). Попробуем использовать созданный нами управляющий элемент ActiveX.

Через меню File добавим еще один проект к уже имеющемуся (File->Add Project). Выберем для нового проекта шаблон Standard EXE. Появится пустая форма. Втащим в эту форму из палитры компонентов наш ActiveX- элемент и придадим ему необходимые размеры. Теперь, при желании, можно сохранить группу проектов под любым именем по команде меню FiIe-> Sace Project Group As, чтобы впоследствии продемонстрировать кому-нибудь ваши результаты или скорректировать проект.

Хранить разрабатываемые ActiveX-элементы и формы их использующие в одной группе проектов очень удобно, потому что отпадает необходимость вручную включать их каждый раз в палитру компонентов из гигантского списка компонентов, уже зарегистрированных на вашей машине. Попробуем выполнить группу проектов по команде меню Run из среды Visual Basic. То, что вы увидите на экране, показано на рис. 1.9.

Рис 1.9. Использование разработанного элемента ActiveX.

Как видите, запускается браузер по умолчанию, потому что используется файл с расширением .осх. Он временно регистрируется в системе и исполняется. Разумеется, с данным списком шрифтов пока ничего нельзя сделать (только просмотреть их), но ведь это только пример! Вы можете разрабатывать для себя или с целью перепродажи куда более изощренные управляющие элементы со множеством свойств и методов, способных реагировать на различные события. Главное — это понять принципы создания таких элементов и их последующего использования.

Охарактеризуем вкратце базовые понятия и ключевые объекты, из которых строятся управляющие элементы ActiveX.

Borland delphi 4 0 для начинающих создание элементов управления activex

Технология ActiveX, рассматриваемая в данной статье, базируется на технологии Microsoft COM (Component Object Model — модель компонентных объектов), позволяющей создавать и использовать программные компоненты, предоставляющие различные сервисы другим приложениям, компонентам и операционной системе. COM представляет собой одну из реализаций концепции распределенных вычислений, базирующейся в общем случае на предоставлении возможности приложениям использовать для расширения своей функциональности готовые компоненты и объекты (иногда они называются сервисами). Технология COM позволяет использовать объектно-ориентированный подход не в рамках одного приложения, а в рамках операционной системы, но, в отличие от стандартных классов, определенных в исходном тексте и реализуемых как объекты в адресном пространстве одного процесса, эти компоненты могут в общем случае располагаться в адресных пространствах разных процессов и даже на разных компьютерах.

В настоящее время существуют три типа спецификаций COM, определенных Microsoft и включающих большое количество интерфейсов и функций:

  • OLE-документы — составные документы, содержащие внедренные или связанные объекты. Эта спецификация описывает правила создания контейнеров для таких документов с «активацией по месту». Отметим, что компонент OLEContainer Delphi и C++Builder создан с учетом этой спецификации (этой теме будет посвящена одна из следующих статей данного цикла).
  • OLE Automation. Эта спецификация описывает, как создать сервер и контроллер, управляющий его поведением с помощью скриптов или макросов. Эта спецификация также поддерживается Delphi и C++Builder (об этом также пойдет речь в ближайших статьях данного цикла).
  • Управляющие элементы ActiveX, использующие специальный вариант протокола Automation (о них-то и пойдет речь в данной статье).

Использование COM, и, в частности, технологии ActiveX, позволяет обеспечить создание приложений, собираемых из готовых компонентов — элементов управления ActiveX, отличающееся от привычной пользователям C++Builder или Delphi разработки приложений с помощью VCL-компонентов тем, что такая «сборка» не зависит от того, на каком языке написаны как готовые компоненты, так и использующее их приложение — лишь бы средство разработки поддерживало возможность использования таких компонентов в разрабатываемом приложении (такое приложение обычно называется контейнером).

Элементы управления ActiveX представляют собой библиотеки, содержащие исполняемый код. Как было сказано выше, эти библиотеки могут быть использованы в различных приложениях как встроенные элементы управления, поэтому они обладают свойствами, событиями и методами, доступными посредством автоматизации. Современные средства разработки, как правило, позволяют включать такие элементы в создаваемые с их помощью приложения. Помимо этого, элементы управления ActiveX нередко используются в качестве расширений web-броузеров с целью придания им дополнительной функциональности, например, для отображения документов, отличных от поддерживаемых данным броузером.

Как любой COM-сервер, элемент управления ActiveX обладает уникальным идентификатором GU >Таким образом, создав элемент управления ActiveX, обладающий интересующей Вас функциональностью, Вы можете в дальнейшем позволить его пользователям встраивать этот элемент в свои приложения (например, написанные на Visual Basic, PowerBuilder, Delphi, C++Builder и др.), отображать его в web-броузере в составе выгруженной с Вашего web-сервера HTML-страницы, включать его в состав документов MS Office, при этом Вы не обязаны предоставлять исходный текст этого компонента.

Когда следует создавать управляющие элементы ActiveX? Естественно, в тех случаях, когда функциональность, содержащаяся в таком элементе, уникальна. Нет смысла создавать ActiveX, реализующий функциональность кнопки или текстового редактора — таких элементов управления, в том числе выполненных в виде ActiveX, на рынке готовых компонентов более чем достаточно. Нет смысла также создавать ActiveX, если он будет использоваться только в C++Builder — в этом случае проще создать VCL-компонент, который будет работать в использующем его приложении значительно быстрее, чем аналогичный ActiveX. Но создание элемента управления, реализующего, к примеру, часть автоматизированного рабочего места какой-либо категории сотрудников Вашего предприятия может в ряде случаев оказаться весьма полезным, особенно в следующих двух случаях. Первый случай — использование на предприятии различных средств разработки, например, C++Builder и Visual Basic; в этом случае разработчик, использующий Visual Basic, может встраивать в свои приложения ActiveX, созданный другим разработчиком и реализующий какую-либо функциональность, используемую несколькими различными автоматизированными рабочими местами. Второй случай — широкое использование Internet или intranet при автоматизации предприятия. В этом случае ActiveX, реализующий подобную функциональность, может быть встроен в HTML-страницу и отображен в web-броузере. Такой подход существенно облегчает решение проблемы обновления версий автоматизированных рабочих мест, так как вместо установки новых версий на рабочих станциях достаточно заменить один экземпляр ActiveX, хранящийся на web-сервере. Наиболее ярким примером такого подхода может быть выполненный в виде ActiveX «тонкий» клиент, получающий данные от удаленного сервера приложений, являющегося, в свою очередь, клиентом серверной СУБД.

Такой набор преимуществ сделал эту технологию за последние два года весьма популярной, и именно поэтому многие современные средства разработки, такие, как Delphi или С++Builder, позволяют создавать элементы управления ActiveX. Эти средства обычно имеют встроенные механизмы поддержки спецификации ActiveX с помощью автоматической генерации соответствующего кода (хотя, конечно, не возбраняется писать подобный код вручную).

Спецификация ActiveX представляет собой набор правил (а именно описание стандартных интерфейсов), с помощью которых следует создавать такие элементы управления. Отметим, что текущая версия этой спецификации учитывает возможность использования в качестве контейнера web-броузеров и необходимость загрузки элементов ActiveX с удаленных web-серверов с их автоматической регистрацией.

2 Создание элементов управления ActiveX на основе VCL-компонентов

Как было сказано выше, C++Builder 3 позволяет создавать элементы управления ActiveX на основе VCL-компонентов. Для этой цели используется библиотека Microsoft ATL (Active Template Library), являющаяся на сегодняшний день индустриальным стандартом и позволяющая создавать элементы ActiveX, представляющие собой скомпилированный код и не требующие дополнительных run-time-библиотек для их выполнения. Процесс создания такого элемента управления весьма прост.

Для создания элемента управления ActiveX следует выбрать из репозитария объектов страницу ActiveX и далее — элемент ActiveX Control.

Далее следует заполнить появившуюся диалоговую панель:

Рис.1. Выбор имени ActiveX, имен модулей и базового VCL-класса

Следует выбрать VCL-компонент, на основе которого будет создан элемент ActiveX. В качестве примера выберем TCalendar.

Отметим, что при выборе опции Include Design-Time Licence автоматически будет сгенерирован файл с расширением *.lic, без которого данный ActiveX нельзя будет использовать ни в каких средствах разработки, но можно поставлять с готовыми приложениями. Использование такого файла бывает удобно в случае, когда ActiveX поставляется бесплатно его автором в составе готового продукта, но требует отдельного лицензирования при встраивании его другими пользователями в свои разработки.

В результате работы ActiveX Control Wizard будут созданы несколько модулей, сгенерирован уникальный идентификатор (GUID) будущего ActiveX, а также соответствующая библиотека типов.

Рис.2. Проект библиотеки ActiveX в С++Builder

Библиотека типов содержит сведения о свойствах, событиях и методах компонента ActiveX, унаследованных от исходного VCL-компонента.

Рис.3. Библиотека типов созданного элемента ActiveX

В коде, связанном с реализацией ActiveX, можно найти описание этих свойств и методов.

Далее следует сохранить и скомпилировать проект и зарегистрировать элемент ActiveX в реестре. Это делается с помощью выбора пункта меню Run/Register ActiveX Server.

После этого можно протестировать созданный ActiveX-компонент, открыв его, например, в Visual Basic. Отметим, что последние версии именно этого средства разработки широко используют элементы управления ActiveX в качестве составных частей создаваемых с их помощью приложений; фактически приложения Visual Basic собраны целиком из ActiveX-компонентов. Более того, спецификация ActiveX создана с учетом того, что в первую очередь Visual Basic и Visual C++ (и лишь затем остальные средства разработки) могут быть контейнерами для этих элементов управления. Поэтому тестирование поведения ActiveX в Visual Basic может более или менее гарантировать, что в других средствах разработки этот управляющий элемент будет вести себя точно так же.

В случае отсутствия Visual Basic можно воспользоваться и более широко распространенным Visual Basic for Applications. С этой целью можно запустить Microsoft Word 97, создать новый документ и выбрать на панели инструментов кнопку «Редактор Visual Basic». Далее следует выбрать в окне «Project» имя вновь созданного документа, щелкнуть по нему правой кнопкой мыши и из полученного контекстного меню выбрать опцию «Вставить/UserForm». На экране появится редактор форм Visual Basic и панель элементов. Далее нужно щелкнуть правой клавишей мыши по панели элементов и выбрать из контекстного меню опцию «Дополнительные элементы». Теперь следует из появившегося списка всех зарегистрированных элементов управления ActiveX выбрать нужный, и он автоматически окажется на панели элементов Visual Basic (можно поместить его на единственную имеющуюся страницу управляющих элементов или создать свою, выбрав опцию «Создать страницу» из контекстного меню ярлычков блокнота, расположенного на панели элементов).

После этого можно поместить наш ActiveX на форму и попытаться изменить какие-либо его свойства, используя для этой цели окно «Свойства».

Рис.4. Тестирование ActiveX в Visual Basic

И, наконец, можно вернуться в редактируемый документ, поместить на него кнопку, дважды щелкнуть по ней и в окне редактора кода создать процедуру, показывающую созданную форму, вписав в сгенерированный код строку UserForm1.Show :

Private Sub CommandButton1_Click()
UserForm1.Show
End Sub

Теперь можно нажать на панели инструментов «Visual Basic» кнопку «Выход из режима конструктора». После этого нажатие на созданную в теле документа кнопку приведет к появлению диалоговой панели с созданным нами элементом управления.

Можно было бы, конечно, протестировать поведение созданного ActiveX, установив его в палитру компонентов Delphi или C++Builder,, но это не самый лучший способ тестирования — ведь в основе создания нашего ActiveX лежит та же самая библиотека VCL, что и в основе создаваемого приложения для тестирования ActiveX. Использование для этой цели любого не имеющего отношения к VCL средства разработки, способного использовать элементы управления ActiveX в создаваемых приложениях, более оправдано. При этом следует заметить, что Visual Basic for Applications представляет собой наиболее часто встречающееся средство разработки такого класса, так как входит в состав самого популярного в нашей стране офисного пакета.

3 Создание страниц свойств

Так как элементы управления ActiveX могут быть использованы в средствах разработки, нередко они обладают набором страниц свойств, позволяющим пользователям менять те или иные свойства этого элемента управления.

Для создания страницы свойств выберем из репозитария объектов страницу ActiveX и элемент Property Page. В результате получим форму, на которой можно размещать интерфейсные элементы.

Создадим страницу для редактирования свойств CalendarDate и GridLineWidth. Для этого разместим на вновь созданной форме два компонента TStaticText и два компонента TEdit.

Рис.5. Страница свойств на этапе проектирования

В созданной форме имеются сгенерированные прототипы обработчиков событий UpdatePropertyPage и UpdateObject. Добавим в них соответствующий код:

Далее следует создать ссылку на странице свойств в модуле, описывающем реализацию элемента ActiveX. С этой целью следует модифицировать h-файл .Модификация кода заключается во вставке строки, указывающей на необходимость регистрации страницы свойств:

Следует также включить ссылку на h-файл страницы свойств в h-файл реализации ActiveX.

Далее следует заново скомпилировать библиотеку ActiveX и зарегистрировать ее.

Если теперь в среде разработки Visual Basic поместить на пользовательскую форму наш ActiveX и выбрать страницу свойств «Специальные», получим созданную нами страницу:

Рис.6. Страница свойств на этапе тестирования ActiveX

При изменении значений в компонентах TEdit можно убедиться, что изменяются и соответствующие свойства элемента ActiveX.

Рис.7. Результат использования страницы свойств

4 Создание активных форм

Активная форма — это элемент управления ActiveX, содержащий несколько VCL-компонентов. Возможность создания таких элементов управления позволяет существенно расширить круг доступных для элементов ActiveX функциональных возможностей. Создание такого ActiveX происходит примерно так же, как и создание обычного приложения.

Попробуем создать простейший пример такого элемента управления. Для его создания следует выбрать со страницы ActiveX репозитария объект ActiveForm, ответить на вопросы об имени компонента, после чего в дизайнере форм получим пустую форму — заготовку будущего ActiveX. Добавим на эту форму компоненты TCheckBox, TButton, TImage и TOpenPictureDialog.

Рис.8. Активная форма на этапе проектирования

Создадим обработчики событий, связанных с TCheckBox и TButton:

Теперь можно скомпилировать приложение, зарегистрировать созданный ActiveX и протестировать его указанным выше способом.

Рис.9. Тестирование активной формы в Visual Basic

Можно также протестировать созданный ActiveX c помощью отображения его в Internet Explorer. Для этой цели можно выбрать пункт меню Project/Web Deployment Options и на странице Project в полях Target dir, Target URL, HTML dir этого диалога указать имя какого-нибудь локального каталога.

Затем можно выбрать опцию Project/Web Deploy и по окончании работы Web Deployment Wizard открыть в Internet Explorer автоматически сгенерированную С++Builder html-страницу c именем, совпадающим с именем созданного проекта:

Рис.10. Тестирование активной формы в Internet Explorer

Отметим, что для успешного отображения ActiveX в броузере требуется Microsoft Internet Explorer версии 3.0 и выше, при этом настройки уровня безопасности должны позволять запуск активного содержимого, расположенного в Intranet-зоне. Если в качестве броузера используется Netscape Navigator, он должен быть оснащен модулем расширения (plug-in), позволяющим интерпретировать тег языка HTML как элемент управления ActiveX (естественно, такая возможность существует только для версий Navigator, выполняющихся под управлением 32-разрядных версий Windows). Отметим также, что сгенерированную автоматически страницу можно в дальнейшем отредактировать с помощью любого html-редактора (или даже любого текстового редактора).

При поставке ActiveX через Web процедура аналогична описанной, но вместо локальных каталогов в строке URL следует указать Internet-адрес Web-сервера:

Рис.11. Настройка опций поставки ActiveX через Internet

Помимо этого, следует обратить внимание на дополнительные «пакеты» или другие файлы, которые следует включить в поставку, если опции проекта таковы, что требуют использования каких-либо дополнительных библиотек.. Разделение ActiveX на несколько файлов и выделение отдельных пакетов может быть использовано для того, чтобы уменьшить в целом время загрузки ActiveX через Internet, например, в случае предстоящей необходимости обновления версии ActiveX или при поставке нескольких разных ActiveX — в этом случае часть «пакетов» может быть установлена один раз, а далее производится поставка лишь небольшой содержательной части элемента ActiveX. Впрочем, не возбраняется создавать ActiveX и в виде одного файла. Отметим также, что при выборе опции Include CAB File compression можно собрать используемые файлы в один файл с расширением *.cab, фактически представляющий собой архив, что также уменьшает примерно в два раза время загрузки файлов через Internet.

Следует отметить, что в активных формах можно использовать практически все компоненты C++Builder, кроме TMainMenu. Возможна также динамическая генерация дополнительных форм на этапе выполнения, при этом дополнительные формы уже не будут содержаться в контейнере, а будут представлять собой обычные формы Windows (и, естественно, могут содержать в том числе и TMainMenu).

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

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL