
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.75] |
![]() |
|
Страницы: (3) 1 [2] 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
каждый раз, когда происходит перерисовка твоего PaintBox'а. |
Сообщ.
#17
,
|
|
|
Когда винда или твоя прога просят полностью или частично перерисовать прямоугольник, занятый твоим PaintBox'ом. При этом то, что ты рисовал ранее стирается и нужно все рисовать заново. Если дружишь с аглицким, то глянь справку по TPaintBox::OnPaint и особенно Example2 - пример того как делать нельзя, как раз твой случай ![]() Добавлено PS: Говоря "по научному" PaintBox рисует изображение непосредственно на "канве экрана" (screen buffer). Поэтому когда PaintBox перекрывается другим окном, то это место канвы экрана перерисовывается другим окном и старое изображение от твоего PaintBox'а ес-но затирается = пропадает. Соотв-но, когда это окно закрывается\перемещается, твой PaintBox всплывает наверх и винда просит его перерисовать соответсвующую область экрана заново - шлет ему сообщение WM_PAINT, которое вызывает событие OnPaint. Если ты в обработчике OnPaint ничего не нарисуешь, то соотв-но получишь белый прямоугольник. TImage, в отличие от PaintBox'a, рисует изображение не прямо на экране, а в битмапе (по умолчанию) и затем по требованию WM_PAINT просто копирует весь битмап или его часть на экран. Соотв-но, при всяких перекрытиях окон с битмапом ничего не происходит и изображение никуда не пропадает, и никаких OnPaint не нужно, т.к.отрисовка битмапа на экране происходит автоматически |
Сообщ.
#18
,
|
|
|
Когда винде надо отрисовать твоё окно. Причём там есть фишка, что когда приходит onPaint - не обязательно его отрисовывать во всех случаях, т.к. если например будешь окно таскать по экрану - то увидишь, что оно не перерисовывается постоянно, а просто таскается, но если там будет стоять твой обработчик - то ему событие будет приходить и ты будешь перерисовывать. Если делать на api - то там есть такая фишка как begin_paint кажется, вот с помощью связки begin_paint и end_paint - там формировалась структура и с её помошью можно было определить что нужно рисовать и нужно ли, аналогию в VCL я не знаю, но если заметишь, что твоё приложение медленно рисуется при таскании окна и это будет критично, можешь туда копнуть. К сожалению, я на память всё не помню, надо код свой смотреть, чтобы детали рассказать. |
Сообщ.
#19
,
|
|
|
Цитата brother79 @ Причём там есть фишка, что когда приходит onPaint - не обязательно его отрисовывать во всех случаях, т.к. если например будешь окно таскать по экрану - то увидишь, что оно не перерисовывается постоянно, а просто таскается, но если там будет стоять твой обработчик - то ему событие будет приходить и ты будешь перерисовывать Ничего подобного, WM_PAINT и соотв-но OnPaint приходят только тогда, когда задана конкретная область, которую нужно перерисовать. В begin_paint эта область задается прямоугольником lpPaint->rcPaint, в VCL этот прямоугольник = Canvas->ClipRect Но все - это излишние подробности, т.к. TPaintBox, несмотря на свое обманчивое название, совершенно не подходит для "простейшего графического редактора", т.к. он не запоминает нарисованное изображение и для того, чтобы оно не терялось при перерисовках, придется рисовать не сразу на экран, а в битмап и затем копировать этот битмап на экран в OnPaint. Спрашивается - зачем городить огород, если все это уже реализовано в TImage ? |
Сообщ.
#20
,
|
|
|
Я придумал как сохранять изображения! Если что то было нарисовано на PaintBox то тоже самое рисуется и на невидимом Image... Но это не работает при Resize и я не знаю что нужно написать чтобы в OnPaint картинка из Image рисовалась на PaintBox...
|
Сообщ.
#21
,
|
|
|
Цитата Yura93 @ Я придумал как сохранять изображения! ![]() За тебя уже Борланд все давно придумал - юзай TImage вместо TPainBox и не морочь голову, с чего ты взял, что у него нет событий OnMouse.. ? В 6-м билдере точно есть, а у тебя какой ? Добавлено Цитата Yura93 @ что нужно написать чтобы в OnPaint картинка из Image рисовалась на PaintBox... Ну если ты извращенец, то напиши ![]() ![]() PaintBox1->Canvas->Draw(0,0,Image1->Picture->Bitmap); Добавлено PS: События OnMouse есть у всех наследников TControl, как их может не быть у TImage - загадка ![]() |
Сообщ.
#22
,
|
|
|
![]() Добавлено Ах да! Если надо то вот код: ![]() ![]() void __fastcall TForm1::Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { MouseD=true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Image1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { MouseD=false; } //--------------------------------------------------------------------------- void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { Size=StrToInt(Edit1->Text); if(MouseD){ Image1->Canvas->Brush->Color=Panel2->Color; if(CheckBox3->Checked){ Image1->Canvas->Pen->Color=Panel6->Color; Image1->Canvas->Pen->Width=StrToInt(Edit2->Text); } else{ Image1->Canvas->Pen->Color=Panel2->Color; Image1->Canvas->Pen->Width=0; } if(RadioGroup1->ItemIndex==1){ Image1->Canvas->Ellipse(X-Size,Y-Size,X+Size,Y+Size); } else{ Image1->Canvas->Rectangle(X-Size,Y-Size,X+Size,Y+Size); } } } //--------------------------------------------------------------------------- Может кто-нибудь увидит тут серьёзную ошибку? |
Сообщ.
#23
,
|
|
|
Отслеживать MouseDown\Up и устанавливать флаг MouseD никчему, т.к. признак зажатия кнопки передается в параметре Shift обработчика MouseMove
![]() ![]() //if(MouseD){ if (Shift.Contains(ssLeft)) { //перемещение мыши с нажатой левой кнопкой ... |
Сообщ.
#24
,
|
|
|
leo, спасибо я исправил. Но всё равно программа не реагирует не вождение мышью по Image и не приходит туда сколько бы я не кликал и не водил мышью.
Теперь код выглядит так: ![]() ![]() void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { Size=StrToInt(Edit1->Text); if(Shift.Contains(ssLeft)){ Image1->Canvas->Brush->Color=Panel2->Color; if(CheckBox3->Checked){ Image1->Canvas->Pen->Color=Panel6->Color; Image1->Canvas->Pen->Width=StrToInt(Edit2->Text); } else{ Image1->Canvas->Pen->Color=Panel2->Color; Image1->Canvas->Pen->Width=0; } if(RadioGroup1->ItemIndex==1){ Image1->Canvas->Ellipse(X-Size,Y-Size,X+Size,Y+Size); } else{ Image1->Canvas->Rectangle(X-Size,Y-Size,X+Size,Y+Size); } } } |
Сообщ.
#25
,
|
|
|
Цитата Yura93 @ Но всё равно программа не реагирует не вождение мышью по Image и не приходит туда сколько бы я не кликал и не водил мышью Ну, не знаю, у меня нормально реагирует и рисует Может обработчик в инспекторе не присвоил, или неcколько Image создал - присвоил одному, а водишь мышью по другому - казусы разные бывают ![]() |
Сообщ.
#26
,
|
|
|
Цитата leo @ Может обработчик в инспекторе не присвоил Что это значит? |
Сообщ.
#27
,
|
|
|
Так... Ну ошибку я исправил... Почему то глюк был из-за того что Image лежал на Panel а она видимо автоматически кладётся поверх... Но теперь почему то не работает функция формы OnResize... Вот код:
![]() ![]() { void __fastcall TForm1::FormResize(TObject *Sender){ Image1->Width=Form1->ClientHeight-16; Image1->Height=Form1->ClientWidth-133; Image1->Top=8; Image1->Left=8; } //--------------------------------------------------------------------------- Но тут важно то что Image в принципе не меняет своих размеров... |
Сообщ.
#28
,
|
|
|
Цитата Yura93 @ а она видимо автоматически кладётся поверх... ![]() Если все нормально сделано, то без разницы где лежит Image, на форме или на панели Цитата Yura93 @ Но тут важно то что Image в принципе не меняет своих размеров... ![]() Просто размер TImage и размер битмапа это не одно и то же. Размер хранимого изображения определяется размером битмапа Image->Picture->Bitmap. Если битмап создается автоматически при первом рисовании, то его размер устанавливается = размеру Image. В свою очередь размер Image определяет размер видимого изображения на экране. Если Image.AutoSize = false, то после создания битмапа размеры Image и Bitmap не привязаны друг к другу. Поэтому при уменьшении размера Image видимое изображение будет уменьшаться (просто выводится не весь хранимый битмап, а только его часть). А вот при увеличении размера Image видимое изображение ес-но не может быть больше размера самого битмапа (размер рамки Image увеличивается, а размер битмапа остается тем же). Ну а если Image.AutoSize = true, то изменение размеров самого Image вообще не работает (размер = битмапу) и для ресайзинга изображения нужно изменять размер Image->Picture->Bitmap. Поэтому сам думай, как должна вести себя картинка при изменении размеров. Если она должна всегда соответсвовать размеру окна и обрезаться при его уменьшении, то самое просто установить Image.AutoSize = true и в FormResize изменять не размеры Image, а размеры Image->Picture->Bitmap PS: Top и Left при резайзе не изменяются, поэтому незачем их переустанавливать |
Сообщ.
#29
,
|
|
|
Поменял AutoSize на false и всё равно ничего не работает....
|
Сообщ.
#30
,
|
|
|
Цитата Yura93 @ Поменял AutoSize на false и всё равно ничего не работает.... Значит, не судьба ![]() Насчет AutoSize и соотношение размеров Image и Bimap я уже тебе все "разжевал", осталось еще проверить св-ва Align и Constraints. Плюс бросить дурную превычку тыкать мышой и менять значение св-в, не понимая как они работают и на что влияют. Сначала следует почитать справочку или умные книжки, а затем уже тыкать со знанием дела ![]() |