На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Страницы: (3) 1 [2] 3  все  ( Перейти к последнему сообщению )  
> Проблема с PaintBox , как вывести изображение?
    Цитата Yura93 @
    Стоп! Когда наступает событие OnPaint?

    каждый раз, когда происходит перерисовка твоего PaintBox'а.
      Цитата Yura93 @
      Стоп! Когда наступает событие OnPaint?

      Когда винда или твоя прога просят полностью или частично перерисовать прямоугольник, занятый твоим PaintBox'ом. При этом то, что ты рисовал ранее стирается и нужно все рисовать заново. Если дружишь с аглицким, то глянь справку по TPaintBox::OnPaint и особенно Example2 - пример того как делать нельзя, как раз твой случай ;)

      Добавлено
      PS: Говоря "по научному" PaintBox рисует изображение непосредственно на "канве экрана" (screen buffer). Поэтому когда PaintBox перекрывается другим окном, то это место канвы экрана перерисовывается другим окном и старое изображение от твоего PaintBox'а ес-но затирается = пропадает. Соотв-но, когда это окно закрывается\перемещается, твой PaintBox всплывает наверх и винда просит его перерисовать соответсвующую область экрана заново - шлет ему сообщение WM_PAINT, которое вызывает событие OnPaint. Если ты в обработчике OnPaint ничего не нарисуешь, то соотв-но получишь белый прямоугольник.

      TImage, в отличие от PaintBox'a, рисует изображение не прямо на экране, а в битмапе (по умолчанию) и затем по требованию WM_PAINT просто копирует весь битмап или его часть на экран. Соотв-но, при всяких перекрытиях окон с битмапом ничего не происходит и изображение никуда не пропадает, и никаких OnPaint не нужно, т.к.отрисовка битмапа на экране происходит автоматически
      Сообщение отредактировано: leo -
        Цитата Yura93 @
        Стоп! Когда наступает событие OnPaint?



        Когда винде надо отрисовать твоё окно. Причём там есть фишка, что когда приходит onPaint - не обязательно его отрисовывать во всех случаях, т.к. если например будешь окно таскать по экрану - то увидишь, что оно не перерисовывается постоянно, а просто таскается, но если там будет стоять твой обработчик - то ему событие будет приходить и ты будешь перерисовывать. Если делать на api - то там есть такая фишка как begin_paint кажется, вот с помощью связки begin_paint и end_paint - там формировалась структура и с её помошью можно было определить что нужно рисовать и нужно ли, аналогию в VCL я не знаю, но если заметишь, что твоё приложение медленно рисуется при таскании окна и это будет критично, можешь туда копнуть. К сожалению, я на память всё не помню, надо код свой смотреть, чтобы детали рассказать.
          Цитата brother79 @
          Причём там есть фишка, что когда приходит onPaint - не обязательно его отрисовывать во всех случаях, т.к. если например будешь окно таскать по экрану - то увидишь, что оно не перерисовывается постоянно, а просто таскается, но если там будет стоять твой обработчик - то ему событие будет приходить и ты будешь перерисовывать

          Ничего подобного, WM_PAINT и соотв-но OnPaint приходят только тогда, когда задана конкретная область, которую нужно перерисовать. В begin_paint эта область задается прямоугольником lpPaint->rcPaint, в VCL этот прямоугольник = Canvas->ClipRect

          Но все - это излишние подробности, т.к. TPaintBox, несмотря на свое обманчивое название, совершенно не подходит для "простейшего графического редактора", т.к. он не запоминает нарисованное изображение и для того, чтобы оно не терялось при перерисовках, придется рисовать не сразу на экран, а в битмап и затем копировать этот битмап на экран в OnPaint. Спрашивается - зачем городить огород, если все это уже реализовано в TImage ?
          Сообщение отредактировано: leo -
            Я придумал как сохранять изображения! Если что то было нарисовано на PaintBox то тоже самое рисуется и на невидимом Image... Но это не работает при Resize и я не знаю что нужно написать чтобы в OnPaint картинка из Image рисовалась на PaintBox...
              Цитата Yura93 @
              Я придумал как сохранять изображения!

              :wacko:
              За тебя уже Борланд все давно придумал - юзай TImage вместо TPainBox и не морочь голову, с чего ты взял, что у него нет событий OnMouse.. ? В 6-м билдере точно есть, а у тебя какой ?

              Добавлено
              Цитата Yura93 @
              что нужно написать чтобы в OnPaint картинка из Image рисовалась на PaintBox...

              Ну если ты извращенец, то напиши
              ExpandedWrap disabled
                  PaintBox1->Canvas->Draw(0,0,Image1->Picture->Bitmap);


              Добавлено
              PS: События OnMouse есть у всех наследников TControl, как их может не быть у TImage - загадка :wacko:
              Сообщение отредактировано: leo -
                :wall: Да-да-да... Все кто говорил что я - слепой и у Image есть события OnMouse были правы! Извините! Но!! Я всё переделал в человеческий код. Теперь всё рисуется непосредственно на Image. Должно рисоваться... Я проверял "точкой останова" (если не ошибаюсь) и заметил что при щелчке на Image событие OnMouse не обрабатывается... В чём дело?

                Добавлено
                Ах да! Если надо то вот код:
                ExpandedWrap disabled
                  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);
                          }
                      }
                  }
                  //---------------------------------------------------------------------------

                Может кто-нибудь увидит тут серьёзную ошибку?
                  Отслеживать MouseDown\Up и устанавливать флаг MouseD никчему, т.к. признак зажатия кнопки передается в параметре Shift обработчика MouseMove
                  ExpandedWrap disabled
                      //if(MouseD){
                      if (Shift.Contains(ssLeft)) { //перемещение мыши с нажатой левой кнопкой
                      ...
                  Сообщение отредактировано: leo -
                    leo, спасибо я исправил. Но всё равно программа не реагирует не вождение мышью по Image и не приходит туда сколько бы я не кликал и не водил мышью.
                    Теперь код выглядит так:
                    ExpandedWrap disabled
                      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);
                              }
                          }
                      }
                      Цитата Yura93 @
                      Но всё равно программа не реагирует не вождение мышью по Image и не приходит туда сколько бы я не кликал и не водил мышью

                      Ну, не знаю, у меня нормально реагирует и рисует
                      Может обработчик в инспекторе не присвоил, или неcколько Image создал - присвоил одному, а водишь мышью по другому - казусы разные бывают ;)
                        Цитата leo @
                        Может обработчик в инспекторе не присвоил

                        Что это значит?
                          Так... Ну ошибку я исправил... Почему то глюк был из-за того что Image лежал на Panel а она видимо автоматически кладётся поверх... Но теперь почему то не работает функция формы OnResize... Вот код:
                          ExpandedWrap disabled
                            {
                            void __fastcall TForm1::FormResize(TObject *Sender){
                             
                            Image1->Width=Form1->ClientHeight-16;
                            Image1->Height=Form1->ClientWidth-133;
                            Image1->Top=8;
                            Image1->Left=8;
                             
                            }
                            //---------------------------------------------------------------------------

                          Но тут важно то что Image в принципе не меняет своих размеров...
                          Сообщение отредактировано: Yura93 -
                            Цитата Yura93 @
                            а она видимо автоматически кладётся поверх...

                            :no:
                            Если все нормально сделано, то без разницы где лежит Image, на форме или на панели

                            Цитата Yura93 @
                            Но тут важно то что Image в принципе не меняет своих размеров...

                            :no:
                            Просто размер 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 при резайзе не изменяются, поэтому незачем их переустанавливать
                            Сообщение отредактировано: leo -
                              Поменял AutoSize на false и всё равно ничего не работает....
                                Цитата Yura93 @
                                Поменял AutoSize на false и всё равно ничего не работает....

                                Значит, не судьба :D
                                Насчет AutoSize и соотношение размеров Image и Bimap я уже тебе все "разжевал", осталось еще проверить св-ва Align и Constraints.
                                Плюс бросить дурную превычку тыкать мышой и менять значение св-в, не понимая как они работают и на что влияют. Сначала следует почитать справочку или умные книжки, а затем уже тыкать со знанием дела ;)
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) 1 [2] 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0679 ]   [ 16 queries used ]   [ Generated: 13.06.25, 17:44 GMT ]