Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.06.2010, 22:10   #1
MindFreak
 
Регистрация: 02.06.2010
Сообщений: 5
По умолчанию Перерисовка Canvas

Недавно занялся Дельфями, ради интереса и получения опыта соорудил совершенно бессмысленную программку, которая при запуске рисует прямо на Canvas'e формы "пейзаж". Собсно, дальше хочу добавить кнопку по которой "солнце" будет перемещаться...
Но возникли два вопроса от которых уже весь мозг распух:

1. Насущный - перерыл кучу веток форумов, но так и не нашёл решения:
При выполнении программы, когда окно формы перекрывается другим окном, выходит за границы экрана, сворачивается-разворачивается в панель задач и разворачивается кнопкой во весь экран, изображение не отрисовывается и остаются чистые области. Пробовал присобачить эту же процедуру к событию OnPaint формы, но тогда Canvas формы безостановочно рисуется и съедает всё время процессора! А как эту перерисовку сделать грамотно??

2. Забавный - эта проблема меня ваще сконфузила:
При выполнении программы, изменяя горизонтальные размеры формы все размеры фигур пересчитываются и пропорционально перерисовываются, но при изменении вертикальных размеров - все фигуры отрабатывают правильно, кроме "солнца" - его размеры почему-то не меняются!

Вот, собсно, содержимое Unit1.pas:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormResize(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormResize(Sender: TObject); //Событие Form1 onResize

  var w, h, wm, hm: integer;

begin
  Form1.Refresh;
  wm := Form1.ClientWidth;
  w := wm div 8;
  hm := Form1.ClientHeight;
  h := hm div 10;
  with Form1.Canvas do begin
    //Небо
    Brush.Color := clBlue;
    Brush.Style := bsDiagCross;
    Pen.Color := clBlue;
    Rectangle(0, 0, wm, h);
    //Трава
    Brush.Color := clGreen;
    Brush.Style := bsHorizontal;
    Pen.Color := clGreen;
    Rectangle(0, hm-h, wm, hm);
    //Солнце
    Brush.Color := clYellow;
    Brush.Style := bsSolid;
    Pen.Color := clYellow;
    Ellipse(w, 2*h, 2*w, 2*h+w);
    //Домик
    Brush.Color := clGray;
    Brush.Style := bsSolid;
    Pen.Color := clMaroon;
    Rectangle(2*w, hm-5*h, 6*w, hm-h);
    Polygon([Point(2*w, hm-5*h), Point(4*w, hm-7*h),
             Point(6*w, hm-5*h), Point(2*w, hm-5*h)]);
    Brush.Color := clWhite;
    Brush.Style := bsSolid;
    Pen.Color := clMaroon;
    Rectangle(3*w, hm-4*h, 5*w, hm-2*h);
  end;
end;

end.
MindFreak вне форума Ответить с цитированием
Старый 07.06.2010, 23:10   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

по первому.
DoubleBuffered(или одна f) в OnCreate формы поставьте, и используйте OnPaint.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 08.06.2010, 00:38   #3
MindFreak
 
Регистрация: 02.06.2010
Сообщений: 5
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
по первому.
DoubleBuffered(или одна f) в OnCreate формы поставьте, и используйте OnPaint.
Мерцание стало в два раза быстрее, даже пейзаж не разглядеть... И нагрузка на проц не уменьшилась - вся система от этого OnPaint притормаживает...
MindFreak вне форума Ответить с цитированием
Старый 08.06.2010, 01:43   #4
MindFreak
 
Регистрация: 02.06.2010
Сообщений: 5
По умолчанию

По поводу второго вопроса до меня допёрло!
Там, при вертикальном изменении размеров, ширина формы не изменяется, а вторая координата эллипса "солнца" жёстко привязана к этой самой ширине формы! То есть, оно сдвигается, а размер его не изменяется! Вот глупость-то!

Проблемку решил как-то сам ещё не понял как:
Добавил некий коэффициент, почему-то пришедший в мои мысли:
we := (wm+hm) div 13;
И в расчёте эллипса написал такое:
Ellipse(we, we, 2*we, 2*we);

Последний раз редактировалось MindFreak; 08.06.2010 в 03:22.
MindFreak вне форума Ответить с цитированием
Старый 08.06.2010, 11:27   #5
x128
Форумчанин
 
Регистрация: 03.02.2010
Сообщений: 178
По умолчанию

в OnResize вызывай Repaint, а процесс рисования перенеси в OnPaint и как уже сказали в OnCreate вставь DoubleBuffered:=true
x128 вне форума Ответить с цитированием
Старый 08.06.2010, 17:36   #6
MindFreak
 
Регистрация: 02.06.2010
Сообщений: 5
По умолчанию

Цитата:
Сообщение от x128 Посмотреть сообщение
в OnResize вызывай Repaint, а процесс рисования перенеси в OnPaint и как уже сказали в OnCreate вставь DoubleBuffered:=true
Всё тоже самое, тока теперь при зацикливании перерисовки соответственно не отрисовываются кнопки закрытия и т.п. окна...
MindFreak вне форума Ответить с цитированием
Старый 08.06.2010, 17:59   #7
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Убери
Код:
Form1.Refresh;
Добавлено --------------------------------
И вот еще. Зачастую при отрисовке на канве необходимо сохранять постоянство пропорций (решение см. во вложении). А иногда возникает проблема точности отрисовки. Для этого можно хрить координаты в Real, а округлять только при вызове процедуры отрисовки. Это не очень хорошее решение (увеличивает нагрузку), но для простых чертежей (думаю до 1000-2000 элементов) более чем достаточное.
Вложения
Тип файла: zip Перерисовка Canvas.zip (1.4 Кб, 64 просмотров)

Последний раз редактировалось Sibedir; 08.06.2010 в 18:24.
Sibedir вне форума Ответить с цитированием
Старый 08.06.2010, 22:50   #8
MindFreak
 
Регистрация: 02.06.2010
Сообщений: 5
По умолчанию

Цитата:
Сообщение от Sibedir Посмотреть сообщение
Убери
Код:
Form1.Refresh;
Спасибо огромное!
Вот, как раз уже само допёрло, что проблема в рефреше и вместо Form1.Refresh я написал:
Код:
    Canvas.Brush.Color:=clBtnFace;
    Canvas.FillRect(Canvas.ClipRect);
И отдельное спасибо за добавленное разъяснение с вложением - очень ценно!

Последний раз редактировалось MindFreak; 08.06.2010 в 23:03.
MindFreak вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перерисовка окна _Dmitry_ Win Api 3 30.03.2010 19:55
Перерисовка TlistBox DarkEN_ANGEL Компоненты Delphi 4 26.01.2010 23:04
Перерисовка канвы Bayazet Мультимедиа в Delphi 4 09.04.2009 22:14
перерисовка канвы Bayazet Общие вопросы Delphi 14 27.01.2009 16:02
Перерисовка на Image SERG1980 Мультимедиа в Delphi 9 09.04.2008 10:24