Старый 09.09.2011, 12:23   #1   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Движущаяся линия в GDI+

Господа, нужна помощь.
Работаю в Builder XE, использую для рисования графики GDI+.
На TImage нарисована сеточка, а на сеточке толстая линия. Хочу перемещать эту линию нажатием на ее концы. То есть при перемещении линия должная стираться и рисоваться в новом месте.

Как это сделать? Если я буду каждый раз перерисовывать фон, будет мерцание. Может есть какой-то способ рисовать линию создавая ее как объект с параметрами? Наверняка в GDI есть какая-то функция для этого.

Спасибо.
 
Старый 09.09.2011, 12:57   #2   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,872
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
Господа, нужна помощь.
Работаю в Builder XE, использую для рисования графики GDI+.
На TImage нарисована сеточка, а на сеточке толстая линия. Хочу перемещать эту линию нажатием на ее концы. То есть при перемещении линия должная стираться и рисоваться в новом месте.

Как это сделать? Если я буду каждый раз перерисовывать фон, будет мерцание. Может есть какой-то способ рисовать линию создавая ее как объект с параметрами? Наверняка в GDI есть какая-то функция для этого.

Спасибо.
LockWindowUpdate(хэндл окна);//Запретили реальную отрисовку на экране
быренько всё перерисовываем
LockWindowUpdate(NULL);//Разрешили реальную отрисовку на экране
InvalidateRect(хэндл окна, NULL, FALSE);//Пометили всё окно как требующее перерисовки
UpdateWindow(хэндл окна);//Принудительно перерисовали

Это если через чистый GDI работать.
 
Старый 09.09.2011, 12:58   #3   
Registered User
 
Сообщений: 1,114
Регистрация: 23.06.2007
Возраст: 56

Hopkroft вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
Господа, нужна помощь.
Работаю в Builder XE, использую для рисования графики GDI+.
На TImage нарисована сеточка, а на сеточке толстая линия. Хочу перемещать эту линию нажатием на ее концы. То есть при перемещении линия должная стираться и рисоваться в новом месте.

Как это сделать? Если я буду каждый раз перерисовывать фон, будет мерцание. Может есть какой-то способ рисовать линию создавая ее как объект с параметрами? Наверняка в GDI есть какая-то функция для этого.

Спасибо.
1. У формы ставишь DoubleBuffered ->true
2. Координаты того чего хочешь нарисовать хранишь в массиве.
3. Я рисовал всё на PaintBox. Вешаешь в обработчике OnPaint. то что хочешь нарисовать. И когда происходит его вызов делаешь следующее.
3.1. Очищаешь холст.
3.2. Рисуешь координатную сетку (или что там у тебя)
3.3 Рисуешь из массива свои линии. (Скорее всего у тебя, координаты и матрица смежности, в случае если они соединены).

Делал по такому принципу. Мерцаний не заметил. Есть ещё метод когда сначала создают массив TBitMap и рисуют там, потом его копируют на холст. Но я делал по 1-ому способу и было всё ок.
 
Старый 09.09.2011, 13:11   #4   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
хм... что-то не догоняю.
Вот мой код:
Цитата:

void __fastcall TForm1::FormActivate(TObject *Sender)
{
int i,j;

_m_pGraphics = new Gdiplus::Graphics(Form1->Image->Canvas->Handle);
_m_ppen = new Pen(Gdiplus::Color(255,255,180,180));
_m_pbrush= new SolidBrush(Gdiplus::Color(55, 255, 0, 0));
_m_pGraphics->SetSmoothingMode(Gdiplus::SmoothingModeHighQualit y);

_m_ppen->SetLineCap(2, 2, 0);
_m_ppen->SetColor(Gdiplus::Color(255, 190, 190, 190));
_m_ppen->SetWidth(1);

// Рисую сетку
for (i=0; i <= 60; i++) _m_pGraphics->DrawLine(_m_ppen, 0,i*10,700,i*10);
for (j=0; j <= 70; j++) _m_pGraphics->DrawLine(_m_ppen, j*10,0,j*10,600);

/Рисую линию

_m_ppen->SetColor(Gdiplus::Color(255, 50, 50, 50));
_m_ppen->SetWidth(5);

_m_pGraphics->DrawLine(_m_ppen, 0,300,0,0);

//а теперь, допустим, я потянул за верхний конец линии и получил координаты 0,300,200,0
_m_pGraphics->DrawLine(_m_ppen, 0,300,200,0);

// А как перед этим убрать первую линию
}
 
Старый 09.09.2011, 13:14   #5   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Hopkroft,
если не получится то, что написал Spectator, попробую твой метод но с TImage
 
Старый 09.09.2011, 13:23   #6   
Registered User
 
Сообщений: 1,114
Регистрация: 23.06.2007
Возраст: 56

Hopkroft вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
Hopkroft,
если не получится то, что написал Spectator, попробую твой метод но с TImage
Не получится, т.к. у TImage нет события OnPaint.
 
Старый 09.09.2011, 13:49   #7   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
А вместо OnPaint разве нельзя что-то вроде onMouseMove?
 
Старый 09.09.2011, 14:22   #8   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Сделал на OnMouseMove - получилось. Тормозило. Но когда отключил сглаживание при прорисовке сетки - тормозить перестало. Линии то в сетке ортогональные.
Но это же временный вариант. А если у меня на фоне картинка будет - каждый раз ее перерисовывать - это жуть.
 
Старый 09.09.2011, 14:24   #9   
Registered User
 
Сообщений: 1,114
Регистрация: 23.06.2007
Возраст: 56

Hopkroft вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
А вместо OnPaint разве нельзя что-то вроде onMouseMove?
Я вопроса не понял.

Что касается PaintBox. Он сам перерисовыватся не может для этого ему нужно обрабатывать метод OnPaint.
Тут идеология следующая.
изменил значение->нарисовал.

1. В OnPaint у тебя рисуется то что находится в массиве.
2. На onMouseMove, onMouseDown, onMouseUp изменяешь координаты нужных линий. После этого вызываешь OnPaint.

Таким образом, у тебя и данные изменяются и программа корректно их отображает.

А TImage насколько я понял, может сам "перерисовываться". Вот от этого и нужно отталкиваться. Тем более TImage в основном для хранения и обработки картинок используют. А тебе активно рисовать нужно, так что сам думай

Upd. Я понял что ты хотел сказать. В принципе ты написал то-же что я тебе предложил. Т.е. у меня тоже в OnMouseMove в конце вызывалась перерисовка.
 
Старый 09.09.2011, 14:28   #10   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,872
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
А вместо OnPaint разве нельзя что-то вроде onMouseMove?
Рисовать в onMouseMove крайне не рекомендуется.
Смотри - отрисовку надо помещать в OnPaint
А в onMouseMove надо писать две строки:

InvalidateRect....
UpdateWindow....
 
Старый 09.09.2011, 14:29   #11   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Хм.. а с картинкой не тормозит.
Шайтан, однако, 150 сглаженных линий рисует в несколько раз дольше, чем грузит картинку из файла..
 
Старый 09.09.2011, 14:33   #12   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Вот что выясняется в ходе экспертиментов:

1. Без Inavalidate не работает. То есть даже TImage нужна принудительная перерисовка.
2. Если на OnMouseMove поставить загрузку картинки в TImage - invalidate не нужен.

Получилось реально работающее вот что:
Цитата:
void __fastcall TForm1::ImageMouseMove(TObject *Sender, TShiftState Shift, int X,
int Y)
{
int i,j;
Form1->Image->Picture->LoadFromFile("tire2.bmp");
_m_pGraphics = new Gdiplus::Graphics(Form1->Image->Canvas->Handle);
// _m_pGraphics_Layer1 = new Gdiplus::Graphics(Form1->Image->Canvas->Handle);
//_m_ppen = new Pen(Gdiplus::Color(255,255,180,180));

// _m_pbrush= new SolidBrush(Gdiplus::Color(55, 255, 0, 0));




_m_pGraphics->SetSmoothingMode(Gdiplus::SmoothingModeNone);

_m_ppen->SetLineCap(2, 2, 0);

_m_ppen->SetColor(Gdiplus::Color(255, 190, 190, 190));
_m_ppen->SetWidth(1);

//рисуем сетку
for (i=0; i <= 60; i++) _m_pGraphics->DrawLine(_m_ppen, 0,i*10,700,i*10);
for (j=0; j <= 70; j++) _m_pGraphics->DrawLine(_m_ppen, j*10,0,j*10,600);

//меняем карандаш для рисования движущейся линии
_m_pGraphics->SetSmoothingMode(Gdiplus::SmoothingModeHighQualit y);
_m_ppen->SetColor(Gdiplus::Color(255, 255, 90, 90));
_m_ppen->SetWidth(5);

_m_pGraphics->DrawLine(_m_ppen, 0,600-50,X,Y); // ее родимую и двигаю


}
 
Старый 09.09.2011, 14:34   #13   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Spectator,

Цитата:
Смотри - отрисовку надо помещать в OnPaint
Так ведь нет в TImage onPaint.

В общем-то спасибо за советы. А то я уж грешным делом думал для каждой линии свой прозрачный TImage рисовать. Линий всего 4, но в планах еще одна программа другого назначения, но похожей структуры,там линий будет до 200...

Цитата:
InvalidateRect....
UpdateWindow....
А нельзя ли применительно к моему коду, поподробнее?
Учитывая, что нет onPaint, непонятно, где надо рисовать.
 
Старый 09.09.2011, 14:40   #14   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,872
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
Вот что выясняется в ходе экспертиментов:

1. Без Inavalidate не работает. То есть даже TImage нужна принудительная перерисовка.
2. Если на OnMouseMove поставить загрузку картинки в TImage - invalidate не нужен.
в OnMouseMove загрузку картинки вставлять не стоит.

Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
Spectator,
Так ведь нет в TImage onPaint.
Выкинь его нахрен, он не для рисования предназначен, а для загрузки картинок, что вполне понятно из названия. Рисуй прямо на канве формы.
 
Старый 09.09.2011, 15:04   #15   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Spectator,
Цитата:
Рисуй прямо на канве формы.
На форме не получится. У меня на ней панелька, в которой нет OnPaint. Так что тогда сделать? PaintBOx налепить? Он загрузку картинок поддерживает?
 
Старый 09.09.2011, 15:05   #16   
Форумец
 
Аватар для Shtirliz
 
Сообщений: 248
Регистрация: 17.01.2005

Shtirliz вне форума Не в сети
-=Женек=-, у тебя же был уже несколько постов назад рабочий вариант, чем он не устроил?
 
Старый 09.09.2011, 15:13   #17   
///
 
Аватар для -=Женек=-
 
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43

-=Женек=- вне форума Не в сети
Shtirliz,
ну так мне пишут, что нерациональный у меня вариант.
 
Старый 09.09.2011, 15:15   #18   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,872
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
Spectator,

На форме не получится. У меня на ней панелька, в которой нет OnPaint. Так что тогда сделать? PaintBOx налепить? Он загрузку картинок поддерживает?
Значит и панельку выкидывай, отрисуещь ее сам. Иначе тебе надо будет создать вручную (через CreateWindow) окно, предварительно создав класс окна, в котором прописать обработчик WM_PAINT, и это окно создать как дочернее к панели.
Изврат еще тот.
 
Старый 09.09.2011, 15:19   #19   
Форумец
 
Аватар для Shtirliz
 
Сообщений: 248
Регистрация: 17.01.2005

Shtirliz вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
ну так мне пишут, что нерациональный у меня вариант.
На заборе тоже пишут, а там дрова. Если качество работы тебя устраивает, то оставляй, как есть. Там проблемы могут быть в основном только с масштабированием, насколько я помню. Я бы использовал TPaintBox или как он там.
 
Старый 09.09.2011, 15:30   #20   
Форумец
 
Аватар для Shtirliz
 
Сообщений: 248
Регистрация: 17.01.2005

Shtirliz вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
Он загрузку картинок поддерживает?
PaintBox - это обычный Cancas
Картинку грузить как обычно, через TBitMap загрузить используя LoadFromFile картинку, потом установить размеры для PaintBox, а потом PaintBox.Canvas.Draw для экземпляра TBitMap.
Извини, точнее по методам не скажу, потому что Borland жлобит выкладывать справку по компонентам своим в свободный доступ.
 
Старый 10.09.2011, 01:23   #21   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,872
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
Цитата:
Сообщение от -=Женек=- Посмотреть сообщение
Хм.. а с картинкой не тормозит.
Шайтан, однако, 150 сглаженных линий рисует в несколько раз дольше, чем грузит картинку из файла..
ты куски кода приводи. с параметрами и всяким таким. не стесняйся.
разберемся с твоими 150-ю сглаженными линиями как-нибудь.
 
Старый 10.09.2011, 03:20   #22   
Registered User
 
Сообщений: 1,114
Регистрация: 23.06.2007
Возраст: 56

Hopkroft вне форума Не в сети
Цитата:
Сообщение от Spectator Посмотреть сообщение
ты куски кода приводи. с параметрами и всяким таким. не стесняйся.
разберемся с твоими 150-ю сглаженными линиями как-нибудь.
только давай без ассемблера!
I try to be polite
 
Старый 13.09.2011, 01:53   #23   
Форумец
 
Аватар для Spectator
 
Сообщений: 39,872
Регистрация: 27.05.2003
Возраст: 46

Spectator вне форума Не в сети
закрыто, в дальнейшем с такими вопросами - в болталку.
 
Поиск в теме: 



Быстрый переход:

  Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Support by DrIQ & Netwind