Russian Belarusian English German Japanese Ukrainian

Rashka.studio - игры и приложения для Android! Заходи, ждём тебя =)

Основы работы с событием OnPaint

CuBook1.675

Все, что можно рисовать на канве с помощью компонента TImage, можно рисовать и на форме. Кроме того, имеется специальный компонент PaintBox, имеющий канву и позволяющий рисовать на ней. Рисование на PaintBox вместо формы не имеет никаких преимуществ, кроме может быть некоторого облегчения в расположении одного или нескольких рисунков в площади окна. При рисовании на канве формы или PaintBox надо учитывать некоторые особенности.
 
Откройте новое приложение, перенесите на него диалог OpenPictureDialog, кнопку и в обработчик щелчка на ней вставьте операторы:
if(OpenPictureDialog1->Execute()}
{
Graphics::TBitmap *Bitmap = new Graphics::TBitmap;
try
{
Bitmap->LoadFromFile(OpenPictureDialog1->FileName);
Canvas->Draw(0,0,Bitmap);
}
__finally
{
Bitmap->Free();
}
}
Эти операторы обеспечивают загрузку выбранного пользователем графического файла и отображение изображения непосредственно на канве формы (поскольку оператор Canvas->Draw относится к канве формы, можно было бы это уточнить, написав Form1->Canvas->Draw). Запустите приложение, выберите файл. А теперь, не закрывая своего приложения, вернитесь в C++Builder и, ничего там не делая, опять перейдите в свое выполняющееся приложение. Если окно Редактора Кода, выступившее на первый план при вашем переходе в C++Builder, целиком перекрыло окно вашего приложения, то вернувшись в него вы увидите, что картинка в окне исчезла. Если же вы опять загрузите в него картинку и сдвинете окно приложения так, чтобы окно Редактора Кода не могло целиком его закрыть, то, повторив эксперимент с переходом в C++Builder и обратно вы, возможно, увидите уже иной результат.
 
Вы видите, что если окно какого-то другого приложения перекрывает на время окно вашего приложения, то изображение, нарисованное на канве формы, портится. В компоненте Image этого не происходило, поскольку в классе TImage уже предусмотрены все необходимые действия, осуществляющие перерисовку испорченного изображения. А при рисовании на канве формы или других оконных компонентов эти меры должен принимать сам разработчик приложения.
 
Если окно было перекрыто и изображение испортилось, операционная система сообщает приложению, что в окружении что-то изменилось и что приложение должно предпринять соответствующие действия. Как только требуется обновление окна, для него генерируется событие OnPaint. В обработчике этого события (в нашем случае события формы) нужно перерисовать изображение.
 
Перерисовка может производиться разными способами в зависимости от приложения. В нашем примере можно было бы вынести объявление указателя Bitmap за пределы приведенной выше процедуры, т.е. сделать эту переменную глобальной:
Graphics::TBitmap*Bitmap;
Тогда приведенная выше процедура загрузки файла сокращается на следующий код:
if(OpenPictureDialog1->Execute())
{
Bitmap = new Graphics::TBitmap;
Bitmap->LoadFromFile(OpenPictureDialog1->FileName);
Canvas->Draw(0,0,Bitmap);
}
Оператор Bitmap->Free(), содержавшийся ранее в этой процедуре, переносится в обработчик события формы OnDestroy. Тогда в течение всего времени выполнения вашего приложения вы будете иметь копию картинки в компоненте Bitmap и вам достаточно ввести в обработчик события OnPaint формы всего один оператор:
if(Bitmap != NULL)
Canvas->Draw(0,0,Bitmap);
Оператор if используется, чтобы избежать ошибочного обращения к Bitmap, пока графический файл еще не загружался и объект Bitmap не создан. Сделайте это, и увидите, что изображение на форме не портится при любых перекрытиях окон.
 
Сделанный вами обработчик перерисовывает все изображение, хотя, может быть, испорчена только часть его. При больших изображениях это может существенно замедлять перерисовку и вызывать неприятные зрительные эффекты. Перерисовку можно существенно ускорить, если перерисовывать только испорченную область канвы. У канвы есть свойство ClipRect типа TRect, которое в момент обработки события OnPaint указывает область, которая подлежит перерисовке. Поэтому более экономным будет обработчик:
if(Bitmap !- NULL)
Canvas->CopyRect(Canvas->ClipRect,Bitmap->Canvas,Canvas->ClipRect);
Он перерисовывает только область ClipRect, которая испорчена.
Если заметили ошибку, выделите фрагмент текста и нажмите Ctrl+Enter

Добавить комментарий