Форум: "Начинающим";
Текущий архив: 2008.12.21;
Скачать: [xml.tar.bz2];
ВнизПодлый PaintBox Найти похожие ветки
← →
Fresh © (2008-11-09 17:25) [0]Я вывожу на PaintBox нужную мне инфу (графики, точки и т.д.) Пока окно активное - графика есть. Только появляется другое окно поверх этого - вся графика пропадает. Та же фишка если затягивать окно за границы экрана или сворачивать. Мне нужно, чтоб при любом "насилии" моего окна рисунок на PaintBox оставался тем же, а не появлялись белые "пробелы" на нем. Кто-то знает, как это сделать?
← →
AndreyV © (2008-11-09 17:38) [1]Выводи в OnPaint
← →
Сергей М. © (2008-11-09 17:38) [2]рисуй в обработчике WM_PAINT
← →
{RASkov} © (2008-11-09 18:11) [3]Можно заменить на TImage... как вариант. немножко расточительнее, но вариант :)
← →
Юрий Зотов © (2008-11-09 18:49) [4]> Fresh © (09.11.08 17:25)
Вы уверены, что "подлый" именно PaintBox? Может быть, причина все же в чем-то другом?
Я тут справочку по PaintBox"у открыл - и в полминуты нашел в ней вполне работающий пример. Да еще и с пояснениями. И без всякой "подлости".
In order for the drawing to be persistent, you need to also include an OnPaint event handler that tells the PaintBox how to redraw itself when it needs to. In the code below, an ellipse will be drawn everytime the PaintBox renders itself, but the PaintBox will only paint the client area of the control red after the Button is clicked. This client area will only stay red until it is invalidated, but the ellipse will persist. This behavior is different from the TImage component, because the TImage component maintains an internal bitmap that stores this drawing information for you.
procedure Form1.PaintBox1Paint(Sender: TObject);
begin
PaintBox1.Canvas.Ellipse(0,0,100,100);
end;
← →
antonn © (2008-11-09 19:27) [5]если рисование изображение задача ресурсоемкая, то лучше рисовать на буферном битмапе, а уже буфер выводить (как при рисовании, так и в Onpaint).
либо воспользоваться советом в [3] :)
← →
Palladin © (2008-11-09 21:28) [6]подлый Fresh, свалил все на PainBox... )
← →
Fresh © (2008-11-09 22:47) [7]Спасибо, я уже сам разобрался, поместил все что нужно в OnPaint. Правда пришлось с этим чуть поиграться... У меня изображение может менятся в зависимости от входных параметров, приходится каждый раз его перезапоминать. Я создал масив точек (по размеру PaintBox) при изменении изображения вношу изменения в этот масив, а в OnPaint рисую картинку из этого масива по точкам :)
← →
Юрий Зотов © (2008-11-09 23:07) [8]> Fresh © (09.11.08 22:47) [7]
> при изменении изображения вношу изменения в этот масив, а в OnPaint
> рисую картинку из этого масива по точкам
Совершенно правильная схема. Но если Вы хотите, чтобы при изменении массива картинка обновлялась немедленно (но не мешая работе системы), то сразу после изменения массива напишите одну простую штуку - PaintBox.Invalidate.
А что эта штука означает -см. в справке
:o)
← →
Loginov Dmitry © (2008-11-09 23:26) [9]> Я создал масив точек (по размеру PaintBox) при изменении
> изображения вношу изменения в этот масив, а в OnPaint рисую
> картинку из этого масива по точкам :)
Вместо массива точек можно создать дополнительный объект TBitmap, и вносить изменения в него. При этом на OnPaint для отрисовки достаточно делать Paintbox.Canvas.Draw(0,0,Bitmap). Это должно работать быстрее, чем поточечный вывод на экран.
← →
antonn © (2008-11-09 23:36) [10]
> Совершенно правильная схема.
Не совершенно правильная схема.
Если рисование затрагивает некие "тормознутые" расчеты, то явно будет лишние подвисания программы при банальной перерисовке формы. Поэтому и вводят буферный битмап.
К тому же, как уже сказали, на tbitmap вывод графики будет быстрее, чем на paintbox, хотя сам вывод и bltbtn по затратам довольно мизерные.
← →
Юрий Зотов © (2008-11-09 23:37) [11]> Loginov Dmitry © (09.11.08 23:26) [9]
Смотря что требуется. Если нужно, например, масштабирование, то этот способ будет вносить сильные искажения, а векторная графика - не будет.
← →
antonn © (2008-11-09 23:38) [12]я к тому, что массив явно менее расширяем, чем буферный битмап:)
← →
antonn © (2008-11-09 23:39) [13]
> Юрий Зотов © (09.11.08 23:37) [11]
рисуем векторы на буфере - выводм буфер, в onpaint выводим тот же буфер
← →
Юрий Зотов © (2008-11-09 23:53) [14]> antonn © (09.11.08 23:36) [10]
> Если рисование затрагивает некие "тормознутые" расчеты
Это как? Может быть, наоборот - расчеты затрагивают рисование? Обычно все же так. Потому что при наличии в программе и расчетов, и рисования рисуются обычно как раз результаты расчетов, а не наоборот.
> то явно будет лишние подвисания программы при банальной перерисовке
Это как? При перерисовке будет перерисовка, только и всего. Естественно, в однопоточной схеме расчетов в этот момент производиться не будет - но никаких подвисаний не будет тоже.
> Поэтому и вводят буферный битмап.
Да, спасибо, про CreateCompatible* я где-то когда-то слышал. Да и вообще в курсе, зачем вводят буфера (и не только битмапы).
:о)
Правда, есть ощущение, что это не та конфа, где вообще стоит упоминать о подобных вещах. Человек не понимал (сейчас уже понимает) самой элементарной вещи - необходимости перерисовки. А Вы ему про буфера...
← →
antonn © (2008-11-10 00:15) [15]
> Это как? Может быть, наоборот - расчеты затрагивают рисование?
> Обычно все же так.
если не касаться массива с готовым результатом - то например процедура рисования рисует сплайны, который считаются неоптимизировано, потом все это заливается цветом (попиксельно, тоже неоптимизировано :) ). Или жесче - рисование состояние порта (ком/лпт), программа узнает "информацию о ножках" и рисует результат, явно видно, что при обычно перерисовке формы будет лишний ненужный опрос порта. Да и вообще, мало ли как люди рисуют (а перед этим тут же обсчитывают), насмотрелся всякого... :)
← →
Loginov Dmitry © (2008-11-10 00:20) [16]> Вы ему про буфера...
Судя по всему, не про те мы ему буфера)
← →
Юрий Зотов © (2008-11-10 00:32) [17]> antonn © (10.11.08 00:15) [15]
> рисование состояние порта (ком/лпт), программа узнает "информацию о
> ножках" и рисует результат, явно видно, что при обычно перерисовке
> формы будет лишний ненужный опрос порта.
Нет, здесь явно видно другое:
1. Опрос порта (по таймеру, по событию, еще как-то).
2. Обновление "информации о ножках" (в массиве, в переменной, еще где-то).
3. Перерисовка.
Что автор и сделал, судя по [7]. Я просто подсказал ему, как лучше обновить рисунок при изменении "информации о ножках". Но никаких "ненужных опросов порта при перерисовке" здесь не наблюдается.
← →
antonn © (2008-11-10 00:57) [18]
> 1. Опрос порта (по таймеру, по событию, еще как-то).
да в той же процедуре, где и рисование. Жестокий пример, про сплайны лучше :)
Кстати, я в полу-играх часто делаю буфер текста, его получается вывести быстрее через битмап (да и с эффектами вроде прозрачности), чем каждый раз вызывать textout.
← →
Германн © (2008-11-10 02:07) [19]
> antonn © (10.11.08 00:15) [15]
>
> Или жесче - рисование состояние порта (ком/лпт), программа
> узнает "информацию о ножках" и рисует результат, явно видно,
> что при обычно перерисовке формы будет лишний ненужный
> опрос порта.
Антон, а ты с "портами" сам работал?
← →
antonn © (2008-11-10 12:08) [20]нет, только ковырял компоненты давно для Д5, было бесплатно зато :)
и потом использовал готовые классы с либами, где все разложено по св-вам компонент и не надо мудрить :)
← →
Fresh © (2008-11-10 14:03) [21]Значит так, с масивом точек у меня получилось. Но при малом количестве точек изображение перерисовывается нормально, а когда много точек, то при сворачивании-разворачивании окна видно, как картинка попиксельно прорисовывается снизу-вверх. По-этому, я решил попробовать совет с битмапом, но у меня что-то не получилось. Вот маленький кусочек текст программы... Я сделал так, как мне сказали: вывожу графику на битмап, а в OnPaint PaintBoxa рисую этот битмап. Но что-то видно я не дописал, бо не пашет. Укажите плиз что именно, если заработает эта малая программка, то и вся моя прога тоже заработает :)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Buttons, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
PaintBox1: TPaintBox;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1 : TForm1;
Bitmap : TBitmap;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Bitmap := TBitmap.Create;
with Bitmap do
begin
Width := PaintBox1.Width;
Height := PaintBox1.Height;
end;
end;
procedure TForm1.FormDestroy( Sender : TObject );
begin
Bitmap.Free;
end;
procedure TForm1.PaintBox1Paint( Sender : TObject );
begin
PaintBox1.Canvas.Draw( 0 ,0, Bitmap ) ;
end;
procedure TForm1.Button1Click( Sender : TObject );
begin
Bitmap.Canvas.Pen.Color := clRed;
Bitmap.Canvas.Brush.Color := clGreen;
Bitmap.Canvas.Ellipse( 10, 10, 60, 60 );
end;
end.
← →
antonn © (2008-11-10 15:44) [22]
> procedure TForm1.PaintBox1Paint( Sender : TObject );
> begin
> PaintBox1.Canvas.Draw( 0 ,0, Bitmap ) ;
> end;
>
> procedure TForm1.Button1Click( Sender : TObject );
> begin
> Bitmap.Canvas.Pen.Color := clRed;
> Bitmap.Canvas.Brush.Color := clGreen;
> Bitmap.Canvas.Ellipse( 10, 10, 60, 60 );
> end;procedure TForm1.PaintBox1Paint( Sender : TObject );
begin
BitBlt(PaintBox1.Canvas.Handle,0,0,PaintBox1.Width,PaintBox1.Height,Bitmap.Canva s.Handle,0,0,SRCCOPY);
end;
procedure TForm1.Button1Click( Sender : TObject );
begin
//ну и не забывай очищать предыдущее нарисованое :)
Bitmap.Canvas.Pen.Color := clRed;
Bitmap.Canvas.Brush.Color := clGreen;
Bitmap.Canvas.Ellipse( 10, 10, 60, 60 );
PaintBox1.invalidate;
end;
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.12.21;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.053 c