Главная » C++, C++ Builder » Использование функций Delphi в приложениях CBuilder

0

Если вы можете использовать форму Delphi в приложении, то почему бы не попробовать использовать модуль Delphi без формы, ассоциированной с ним? Как было  бы  здорово использовать все реализованные ранее в Delphi возможности при написании кода на C++! К счастью, это возможно.

Хочу предложить вам хороший пример, подтверждающий мои слова. Когда я приступал к написанию этой книги, я решил, что отличным  примером  возможностей  CBuilder  может послужить код, отображающий на экране текст, повернутый на определенный угол. Изящно смотрится, еще изящнее пишется. Короче говоря, идеальный пример. Пошарив по самым дальним закоулкам своего жесткого диска, я таки нашел код, который делал как раз то, что надо — поворачивал текст при выводе на экран под определенным углом. Я давно уже забыл, где и для чего я его использовал, но главное — он был, и он работал. Это все плоды моей идеи о хранилище кода. Но опустим это сейчас, вернемся к коду. Итак, я раскопал его только для того, чтобы убедиться, что он, конечно же, для Delphi. Чуть ниже в книге, когда мы будем говорить о работе с компонентами, вы увидите, как я перевел его на C++. А сейчас это станет потрясающим примером использования кода Delphi в CBuilder.

Код реализован в виде модуля Delphi. Это «самодостаточный» модуль, то есть в нем содержится и описание (interface) функций, и сами функции. В отличие от языка C++, в котором есть отдельный заголовочный файл для описания и исходный (source) файл для реализации, Object Pascal использует один модуль для того и другого. Это проще в эксплуатации, но плохо вяжется с C++. Или все-таки..? Давайте посмотрим.

Рис. 11.3. Форма примера поворота текста

Создайте форму CBuilder. Добавьте на нее надпись, поле редактирования и кнопку, так, как показано на рис. 11.3. Пространство в центре поля формы будет использовано для отображения повернутого текста. Одно замечание по поводу этой формы: для того чтобы все работало как надо, вам необходимо установить один из шрифтов типа True Type. Если вы выберете свойство font (шрифт) и в его поле в

Object Inspector щелкнете по кнопке , то увидите список шрифтов, отображен ный в левой части Object Inspector. В этом списке представлены все шрифты, которые могут быть выбраны в системе. Нам нужен один из тех шрифтов, перед названием которого в списке стоят две перекрывающиеся буквы T (TT — True Type). Шрифты True Type масштабируемы, и их можно повернуть при отображении на экран. Обычные, символьные шрифты не могут быть повернуты, и с ними этот пример работать не будет.

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

unit Rotate; interface Uses

Graphics, WinTypes, WinProcs;

procedure AngleTextOut(C : TCanvas; Angle,X,Y :Integer; Str :String); implementation

procedure AngleTextOut(C : TCanvas; Angle,X,Y :Integer; Str :String); var

LogRec TLOGFONT;

OldFontHandle, NewFontHandle HFONT; begin

GetObject(C.Font.Handle, SizeOf( LogRec ), Addr( LogRec )); LogRec.lfEscapement := Angle * 10;

NewFontHandle := CreateFontIndirect( LogRec ); OldFontHandle := SelectObject(C.Handle, NewFontHandle); C.TextOut(X, Y, Str);

NewFontHandle  := SelectObject(C.Handle,OldFontHandle); DeleteObject( NewFontHandle );

end;

Сохраните этот модуль под именем rotate.pas. Этот модуль способен осуществить всю работу, необходимую для поворота текста в поле формы. Он отображает текст путем временного создания нового шрифта, выбором этого шрифта в контекст устройства (device context) формы и непосредственно отрисовывания текста, после чего избавляется от старого шрифта. Программа не слишком сложна, но вполне отвечает своему назначению.

Для того чтобы использовать новую форму, вам надо включить новый модуль в модуль формы. Откройте код модуля формы и выберите в главном меню команду File д Include Unit Hdr. Выберите модуль Rotate и нажмите  кнопку OK. При этом автоматически сгенерируется новый заголовочный файл для кода модуля rotate.pas формата C++. Если вы теперь взглянете в каталог проекта, то увидите там файл rotate.hpp, который содержит все описания и функции, находящиеся в файле rotate.pas, переведенные на C++. Вот как этот файл выглядит:

//———————————————————-

// Rotate.hpp – bcbdcc32 generated hdr (DO NOT EDIT) rev: 0

// From: Rotate.pas

//———————————————————-

#ifndef RotateHPP

#define RotateHPP

//———————————————————-

#include <Windows.hpp>

#include <Graphics.hpp>

#include <System.hpp> namespace Rotate

{

//–type  declarations—————————————-

//–var, const, procedure————————————  extern void __fastcall AngleTextOut(Graphics::Tcanvas* C, int Angle, int X, int Y, System::AnsiString Str);

namespace Rotate

{

//–type  declarations————————————————

//–var,  const,  procedure——————————————–

extern void __fastcall AngleTextOut(Graphics::Tcanvas* C, int Angle, int X, int Y, System::AnsiString Str);

namespace Rotate

{

//–type  declarations————————————————

//–var,  const,  procedure——————————————–

extern void __fastcall AngleTextOut(Graphics::Tcanvas* C, int Angle, int X, int Y, System::AnsiString Str);

} /* namespace Rotate */

#if  !defined(NO_IMPLICIT_NAMESPACE_USE) using Namespace Rotate;

#endif

//– end unit ——————————————————-

#endif // Rotate

Не стоит пытаться изменить этот файл, о чем предупреждает и комментарий в начале файла. Если вы все же попробуете его изменить, то CBuilder автоматически перепишет его, когда файл rotate.pas будет компилироваться в следующий раз,  и ваши изменения, скорее всего, вступят в противоречие  с  содержимым  самого  модуля  Rotate.  Итак,  если  вы  измените  этот  файл,  то  в

лучшем случае программа не скомпилируется, а в худшем — повиснет во время работы.

Обратите внимание, что CBuilder автоматически генерирует именованную область видимости (namespace), внутрь которой заключает все функции и определения модулей, а также добавляет предложение using в заголовочный файл. Как мы уже говорили ранее на страницах этой книги, это не лучший способ работы с именованными областями видимости, но он позволяет нам вызывать в нашем коде функции напрямую, не волнуясь о том, в которой области она находится. И, что даже более важно, это дает возможность подключать несколько модулей, не заботясь о том, к которому из них принадлежит та или иная функция или объект.

Замечание

Если в подключенном модуле оказался объект Pascal, то, как нетрудно убедиться, в сгенерированном заголовочном файле будет полный перевод этого объекта как класса C++. CBuilder практически полностью совместим со всеми типами, используемыми в Object Pascal.

Последнее, на что стоит обратить  внимание в преобразовании, — это на последний параметр функции. В модуле Pascal параметр Str имеет тип String. Этот тип — реализованный в Pascal генеральный тип String. Однако в CBuilder нет класса String, который бы напрямую был связан с этим типом. Вместо этого параметр воспринимается как  тип  AnsiString,  который  эквивалентен типу String в Delphi.

Кроме прочего, для вызова функции нам нужны строка текста и значение угла поворота. Строку мы будем использовать, заранее заданную в коде программы, а угол поворота позволим пользователю вводить в поле редактирования на форме. Для завершения примера нам осталось добавить обработчик для кнопки Отобразить текст. Добавьте обработчик для нее, а в него добавьте следующие строки:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Canvas->Brush->Color = Color;

AngleTextOut(Canvas,  atoi(Edit1->Text.c_str()), Width/2, Height/2, "Повернутый текст");

}

Цвет фона текста мы сделали таким же, как цвет формы, чтобы текст не выглядел крикливой, криво налепленной этикеткой. После этого мы устанавливаем начальную точку текста в центр формы, поделив пополам параметры Height (высота) и Width (ширина). От пользователя мы получаем значение угла поворота, заданное им в поле редактирования формы. Угол представляет собой число (градусы) от 0 (соответствующего нормальному, горизонтальному расположению текста) до 360. Теперь, после того как весь код набран, давайте пойдем дальше и скомпилируем и соберем наше приложение в CBuilder. При этом автоматически скомпилируются модуль Pascal и модуль формы C++, после чего они будут собраны воедино.

Отметьте, что компилятор Pascal автоматически запускается для модулей с расширением .pas.

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

Рис. 11.4. Программа поворота текста в действии

Несмотря на то что этот пример был не чересчур сложным, в нем показано все, что вам надо знать об использовании модулей Pascal в CBuilder. Если модуль компилируется в  Delphi,  он,  скорее всего, будет компилироваться  и  в  CBuilder.  Ограничения  существуют  только  для  версии CBuilder 1.0. В приложениях, написанных на Delphi 3.0, нельзя использовать никаких новых компонентов VCL для форм, которые будут экспортироваться в CBuilder 1.0. Точно так же нельзя использовать и функции Delphi 3.0, которых  нет в версии Delphi 2.0. CBuilder 1.0 совместим  с Delphi 2.0 и почти совместим с Delphi 3.0, хотя, конечно, между ними и существуют различия. В отношении CBuilder 3.0 подобных ограничений не обнаружено.

Когда я работал над созданием форм в Delphi 3.0 для последующего использования в CBuilder, то выяснил, что обычно практически все переводится правильно. Использование любого из новых компонентов (например, таких как TCoolBar) в Delphi 3.0 влечет за собой невозможность использования этой формы в CBuilder 1.0. Версия CBuilder 3.0 полностью совместима с Delphi 3.0. К середине 1998 года фирма Borland привела в соответствие друг другу два своих главных программных продукта, так чтобы все последующие их версии были полностью совместимы.

Замечание

Вы можете поинтересоваться, а нет ли возможности (при том, что CBuilder может использовать формы Delphi 3.0) использовать формы CBuilder в Delphi 3.0? Как ни странно, нет. Delphi 3.0 поставляется без компилятора C++, в то время как CBuilder включает в себя полный компилятор Pascal. Так что формы CBuilder использовать в Delphi 3.0 нельзя.

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

  • Комментарии