Листинг 7.2. Пример работы с методами и свойствами канвы
Canvas->Pen->Color=RGB(255,0,0);
Canvas->Pen->Width=4;
Canvas->Ellipse(100,100,200,200);
Canvas->Font->Height=20;
Canvas->Font->Name="Courier";
Canvas->Font->Style=Canvas->Font->Style<<fsItalic;
Canvas->TextOut(150,150,"Hello");
Отличия вывода с использованием канвы очевидны – в листинге не создаются объекты GDI, такие как перо, шрифт, не надо получать контекст отображения, все команды направлены только на вывод информации в том виде, как это требуется программисту. Однако наличие в канве свойства Handle позволяет программисту использовать и функции GDI в тех случаях, когда нужный метод в компоненте отсутствует. Так, например, вызов метода канвы TextOut можно заменить вызовом GDI-функции TextOut:
TextOut(Canvas->Handle,150,150,"Hello",5);
При формировании изображения на канве формы необходимо учитывать особенности работы Windows. В связи с тем, что операционная система работает в многооконном режиме, на экране происходят перекрытия окон, разворачивание, сворачивание окон, что, очевидно, влияет на изображение в окне. Поэтому, отобразив один раз что-либо в окне, например, в ответ на событие от мыши или таймера, нельзя быть уверенным в том, что это изображение останется в окне до момента его закрытия. При обновлении изображения окна, которое происходит при таких операциях, как разворачивание окна, изменение его размеров, перекрытие одного окна другим, содержимое окна обновляется, при этом требующая пе
рерисовки часть окна по умолчанию закрашивается текущей кистью фона.
Проблему иллюстрирует рис. 7.3. Если сформировать на форме некоторое изображение (рис.7.3а), а потом перекрыть часть окна формы другим окном (рис.7.3б), то при закрытии второго окна Windows определит, что нашей форме нужно восстановить испорченную часть, но по умолчанию эта часть просто закрашивается фоновой кистью, в результате изображение теряет целостность (рис.7.3в). Исправить ситуацию возможно, создав обработчик события OnPaint для формы. Событие OnPaint возникает всякий раз, когда операционная система решает, что форме необходима перерисовка (изменились размеры окна, часть окна появилась из-под другого и т. п.). Программист должен в обработчике события OnPaint формировать полное изображение на форме в том виде, как он хотел бы его видеть в данный момент. К обработчику события OnPaint можно обратиться и программно. Метод Repaint приводит к незамедлительному вызову обработчика события OnPaint и перерисовке изображения на форме. Частый вызов метода Repaint может существенно замедлить работу приложения. Метод Invalidate объявляет всю клиентскую область формы как требующую перерисовки, что заставить операционную систему сгенерировать сообщение WM_PAINT в тот момент, когда нет других событий для обработки. Сообщение WM_PAINT приведет к появлению события OnPaint.
Канвой обладают не только формы. Свойство Canvas присутствует у таких компонентов, как TPrinter, TBitmap, TImage, TToolbar. Это означает, что графическое изображение, хранящееся в этих компонентах или составляющее их внешний вид, можно изменять, используя описанные в таблицах 7.1 и 7.2 свойства и методы.
7.4. Компоненты для работы с изображениями
Операционная система Windows содержит встроенные средства для поддержки растровых изображений в формате BMP. Другие популярные форматы (JPEG, GIF, PNG) требуют предварительного преобразования в обычный растр перед обработкой или отображением. Это требует детального знания данных форматов и достаточно больших усилий программиста. Однако используя специальные компоненты VCL можно значительно упростить процедуры обработки изображений в различных форматах. Для работы с DDB и DIB-растрами можно использовать компонент TBitmap, с JPEG-форматом – TJPEGImage, с изображениями в формате метафайла – TMetaFile, с GIF-форматом – TGIFImage (не входит в стандартную поставку C++Builder 6.0).
Компонент TBitmap инкапсулирует растровое изображение Windows [4] как в формате DDB (аппаратно-зависимый растр), так и в формате DIB (аппаратно-независимый растр). Благодаря наличию свойства Canvas программист имеет полный доступ к любой точке растра (массив Pixels или свойство ScanLine), а также возможность отображать растр или его фрагмент на другой канве (методы Draw, StretchDraw, CopyRect). Для управления палитрой растра используется свойство Palette. Компонент TBitmap поддерживает также методы загрузки/сохранения растра в стандартном буфере обмена, файле, внешнем потоке, ресурсах приложения. Компонент TBitmap используется в визуальных компонентах С++Builder как свойство Bitmap компонента TPicture. TPicture выступает в этом случае как контейнер, хранящий графику одного из поддерживаемых форматов (bitmap, icon, metafile). Свойство Picture имеют такие компоненты, как TImage, TDBImage, TControlBar. Листинг 7.3 представляет пример работы со свойствами и методами компонента TBitmap.
Листинг 7.3. Работа с изображением с помощью TBitmap
Graphics::TBitmap *bm=new Graphics::TBitmap;//Создаем объект TBitmap
if(OpenDialog1->Execute())//Открываем файл в стандартном диалоге
{bm->LoadFromFile(OpenDialog1->FileName); //загружаем картинку из //файла в Bitmap
bm->Canvas->TextOutA(0,bm->Height-20,"Copy");//Изменяем растр в //памяти (выводим текст в левом нижнем углу)
Canvas->Draw(20,20,bm); //копируем битовый образ на форму
}
delete bm;
Метод Draw позволяет отобразить некоторую графику (объект класса-потомка TGraphic) на канве. В данном примере содержание растра bm отображается на канве формы в позиции (20,20). Если вызов метода Draw заменить на
Canvas->StretchDraw(ClientRect, bm);
то содержимое растра будет премасштабировано до размеров указанного в первом параметре прямоугольника (в данном случае – до размеров клиентской области окна).
Используя массив Pixels, можно получить цвет любой точки растра, а также изменить его. Например, первую строку растра можно закрасить белым цветом следующим образом:
for(int i=0;i<bm->Width;i++)
bm->Canvas->Pixels[i][0]=clWhite;
Для работы с изображениями в формате JPEG предназначен компонент TJPEGImage. Его свойства и методы позволяют загружать и сохранять jpeg-изображения, преобразовывать их в обычный Bitmap, управлять качеством сжатия. Методы Assign и DIBNeeded позволяют преобразовать изображение из JPEG в BMP формат. Для работы с файлами, потоками, буфером обмена используются методы LoadFromFile, LoadFromStream, LoadFromClipboardFormat, SaveToFile, SaveToStream, SaveToClipboardFormat. На качество и производительность данных JPEG влияют свойства: CompresionQuality (степень потери качества при сжатии), Performance (скорость распаковки), Scale (относительный размер изображения при распаковке). В листинге 7.4 приведен пример работы с JPEG-изображениями в С++Builder.
Листинг 7.4. Пример работы с изображением в формате JPEG
#include <jpeg. hpp>
if (OpenDialog1->Execute())
{TJPEGImage *ji=new TJPEGImage();
ji->LoadFromFile(OpenDialog1->FileName);
ji->DIBNeeded();
Image1->Height=ji->Height;Image1->Width=ji->Width;
Image1->Picture->Bitmap->Assign(ji);
delete ji;}
Вывод
Графический интерфейс в ОС Windows реализуется подсистемой GDI, работа с функциями которой требует высокой квалификации программиста. C++Builder предлагает программисту набор графических компонент, которые существенно упрощают графический вывод информации, предоставляя свойства и методы для формирования изображений, а также для работы с графическими файлами различных форматов. При этом графические компоненты C++Builder оставляют возможность работы c API-функциями GDI. Все это обеспечивает эффективность и гибкость работы с устройствами графического вывода информации.
8. Разработка компонент в C++Builder
Как уже было отмечено, среда С++Builder содержит большое количество стандартных компонент, позволяющих упростить разработку приложений. Программисты могут расширять функциональность системы благодаря возможности создания собственных пользовательских компонент. Созданные компоненты могут быть помещены в палитру компонент, для них могут быть созданы редактор компонента, редакторы свойств, а также файл помощи. Таким образом, дальнейшая работа с созданным компонентом ничем не отличается от работы со стандартными компонентами. Созданные компоненты могут быть объединены в пакеты для упрощения их установки. Существует большое количество коммерческих и свободно распространяемых дополнительных пакетов компонент. Кроме того, программисты могут сами создавать компоненты для упрощения дальнейшей разработки приложений. Рассмотрим процесс создания компонент более подробно.
8.1. Процедура разработки компонента C++Builder
При разработке нового компонента необходимо наследовать его от какого-либо стандартного класса в соответствии с принципами наследования ООП. Как уже было отмечено, все компоненты должны быть наследованы как минимум от класса TComponent. Процедура создания и установки компонентов в среде С++Builder автоматизирована. Для автоматической генерации заготовки нового компонента можно выбрать пункт главного меню Component | New Component. Далее в появившемся окне список выбора “Ancestor Type” позволяет выбрать имя класса, от которого будет наследован компонент. В поле “Class Name” указывается имя будущего класса. В соответствии с нотацией, принятой в среде С++Builder, имена классов должны начинаться с заглавной буквы “T”. В поле “Palette Page” указывается закладка, на которой будет располагаться компонент. В поле “Unit file name” указывается полный путь и имя файла, который будет содержать новый класс. После нажатия на кнопку “ОК” по указанному пути будет сгенерировано два файла c расширениями *.cpp и *.h и именами, совпадающими с именем класса без начальной буквы “T”. Кроме того, будет отображено окно редактирования этих файлов. В самих файлах уже будет содержаться код для определения класса и инсталляции компонента. Программист должен добавить в этот код все необходимые функциональные возможности нового компонента. Допустим, мы выбрали в поле “Ancestor Type” класс TComponent, в поле “Class Name” – TOurComponent, в поле “Palette Page” – OurSample, тогда будет сгенерирован файл OurComponent. h
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |


