Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Canvas - начальные знания!  (Прочитано 11773 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Dr.CODE
Участник

ru
Offline Offline
Пол: Мужской

« : 03-02-2010 12:37 » 

Ребят, прошу помощи в первом знакомстве с канвой!
Код:
__fastcall TMyForm5::TMyForm5(TComponent* Owner)
: TForm(Owner)
{

MyForm5 -> Canvas -> Pen -> Color = clRed;
MyForm5 -> Canvas -> Pen -> Width = 5;

}

void __fastcall TMyForm5::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
 int X, int Y)
{

   if (Button == mbLeft) {

     MyForm5 -> Canvas -> MoveTo(X,Y);

   }

}
По идее мне нужно, чтобы за четыре клика мышки по форме можно было бы нарисовать треугольник. Т.е. первый шекчок ничего не рисует, а уже второй шелчок рисует линию от координат точки запомненных от первого клика. Помогите пожалуйста советом!

Upd:
Я предполагаю, что нужен второй обработчик OnMouseDown(FormMouseDown2) и как-то их оба связать между собой. Никто не знает как это осуществить?
« Последнее редактирование: 03-02-2010 12:45 от Dr.CODE » Записан

Краткость - сестра таланта, некраткость - сам талант!
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 03-02-2010 13:43 » 

Опиши точнее, как именно хочешь рисовать треугольник за 4 клика - пока непонятно, почему 4 Улыбаюсь

Самое простое решение - запоминать текущее состояние и отмеченные точки. То есть, например, заводим флаг "есть точка" и по очередному onMouseDown смотрим, стоит ли флаг. Если стоит - рисуем линию из сохранённой точки в текущую. И вне зависимости от флага, новую точку ставим в качестве текущей и устанавливаем значение флага.

Тогда хватит и одного обработчика (разве что, придётся ещё очистку флага предусмотреть при потере фокуса канвой).
Записан
Kivals
Команда клуба

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 03-02-2010 13:43 » 

Во-первых рисовать нужно по событию OnPaint формы, т.к. форма может быть перекрыта и возникнет необходимость ее перерисовывать.
Я бы завел массив и счетчик, счетчик бы инкрементировал на 1 при каждом клике и брал остаток от деления на длину массива, таким образом счетчик бы при каждом клике менялся по кругу: 0->1->2->...N->0->1 (в твоем случае N=2). В соответствующий элемент массива (типа TPoint) писал бы координаты нажатия.
В событии OnPaint анализировал бы счетчик и в случае заполнения массива (Сч=N) рисовал бы линии по всему массиву:
Код:
Canvas->MoveTo(Pt[N].X,Pt[N].Y); // В последнюю точку чтобы замкнуть фигуру
for (i=0;i<=N;i++) Canvas->LineTo(Pt[i].X,Pt[i].Y);

P.S. Я работал с Delphi и то давно, так что названия типов и событий "могут отличаться от реальных" Улыбаюсь
Записан
Dr.CODE
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 03-02-2010 15:50 » new

Опиши точнее, как именно хочешь рисовать треугольник за 4 клика - пока непонятно, почему 4 Улыбаюсь
Сейчас попробую объяснить. Т.е., к примеру, если проецировать на бумагу - ставлю 3 точки (A,B,C) - они вершины. Координаты вершины A запоминаются при первом клике мышкой, а дальше соединяем остальные вершины. Итого четыре клика.

Самое простое решение - запоминать текущее состояние и отмеченные точки. То есть, например, заводим флаг "есть точка" и по очередному onMouseDown смотрим, стоит ли флаг. Если стоит - рисуем линию из сохранённой точки в текущую. И вне зависимости от флага, новую точку ставим в качестве текущей и устанавливаем значение флага.

Тогда хватит и одного обработчика (разве что, придётся ещё очистку флага предусмотреть при потере фокуса канвой).
Пробую...
Записан

Краткость - сестра таланта, некраткость - сам талант!
Dr.CODE
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 03-02-2010 16:40 » 

Реализовал:
Код:
bool tochka = false; // глобально объявленная переменная;
....
__fastcall TMyForm5::TMyForm5(TComponent* Owner) : TForm(Owner)
{
MyForm5 -> Canvas -> Pen -> Color = clRed;
MyForm5 -> Canvas -> Pen -> Width = 5;
}
void __fastcall TMyForm5::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
  int X, int Y)
{
   if (!tochka) {
MyForm5 -> Canvas -> MoveTo(X,Y);
tochka = true;
   }
   else {
MyForm5 -> Canvas -> LineTo(X,Y);
   }
}
Вад, спасибо большое за совет!
Записан

Краткость - сестра таланта, некраткость - сам талант!
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 03-02-2010 18:10 » 

Угу, только переменную, наверное, стоит сделать членом класса TMyForm5. И предусмотреть сброс флага, если фокус уходит из канвы: а то ерунда получится - ты клацнулся куда-то в другой контрол, потом клацнул опять по канве, а он тебе продолжает линию из того места, где закончил. Или так и задумано?

Да и треугольник довольно сложно будет точно нарисовать - это же нужно в исходную точку суметь попасть Улыбаюсь
Записан
Dr.CODE
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 09-02-2010 18:17 » 

Угу, только переменную, наверное, стоит сделать членом класса TMyForm5.
Вад, а как переменную можно сделать членом класса? Только можно более подробней?

И предусмотреть сброс флага, если фокус уходит из канвы: а то ерунда получится - ты клацнулся куда-то в другой контрол, потом клацнул опять по канве, а он тебе продолжает линию из того места, где закончил. Или так и задумано?

Да и треугольник довольно сложно будет точно нарисовать - это же нужно в исходную точку суметь попасть Улыбаюсь
Действительно, проблемы увидел! Сейчас взялся за доработку!
Записан

Краткость - сестра таланта, некраткость - сам талант!
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 09-02-2010 19:21 » 

Угу, только переменную, наверное, стоит сделать членом класса TMyForm5.
Вад, а как переменную можно сделать членом класса? Только можно более подробней?

Думаю, поподробнее - это будет слишком длинно Улыбаюсь Нужно объявить эту переменную не локально, а в определении класса. Если это описание ничего не говорит, очень советую почитать про объектно-ориентированное программирование (ООП) в целом, и про его применение в C++ в частности.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines