Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Рисование на TPanel


Автор: EEEEEE 26.1.2009, 23:05
Добрый всем!


Проблемка в том, что форма содержит кнопку.
При нажатии на кнопку на Panel выводится средствами WinAPI различная графика( окружности, линии).
При перерисовке формы всё что было на Panel исчезает. Image не подойдёт.

Что необходимо добавить для сохранения информации, выведенной на Panel?

Автор: Comm 26.1.2009, 23:23
Думаю нужно после  отрисовки на TPanel (линий квадратиков) сохранить контекст в динамической переменной ,отловить сообщение перерисовки компонента TPanel  и в обработчике этого события прорисовывать заново из сохраненного контекста=)

Покажи код отрисовки

Автор: EEEEEE 27.1.2009, 10:44
На чистом WinAPI вся хитрость зашита в сообщениях WM_CREATE & WM_PAINT.
А здесь, явно чего-то нехватает? Вот только чего?

Начальную инициализацию можно "убрать" в коструктор формы или FormCreate. Отрисовка должна происходить по нажатию кнопки и в дальнейшем не затираться.
Код

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//
  HDC pDC = GetDC(Panel1->Handle);


  if(pDC != NULL)
    {
     POINT currpoint;

     currpoint.x = Panel1->Width;
     currpoint.y = Panel1->Height;

     RichEdit1->Lines->Add("Panel1->Width  = " + IntToStr(Panel1->Width));
     RichEdit1->Lines->Add("Panel1->Height = " + IntToStr(Panel1->Height));

     DPtoLP(pDC,&currpoint,1);
     SetWindowOrgEx( pDC, -currpoint.x/2, -currpoint.y/2, NULL);

     for(int i=10; i>= 0; i--)
        {
     Ellipse( pDC,    // handle to device context
              -20*i,    // x-coord. of bounding rectangle's upper-left corner
               20*i,    // y-coord. of bounding rectangle's upper-left corner
               20*i,    // x-coord. of bounding rectangle's lower-right corner
              -20*i    // y-coord. bounding rectangle's f lower-right corner
            );
        }

     ReleaseDC( Panel1->Handle, pDC);
    }
  else
      RichEdit1->Lines->Add("Problems with Graphics!");


  MessageBox(Application->Handle,"Work","Message",MB_OK);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
 Invalidate();
}


Автор: sergey_85 27.1.2009, 13:34
Тебе нужно отловить сообщение панели WM_PAINT, затем нарисовать сначала саму панель, а затем то, что ты хочешь.
Вот примерный код

Отрисовка
Код

//#include "Unit1.h"

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    Panel1->WindowProc = SubClassWndProc;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SubClassWndProc(Messages::TMessage &Message)
{
    if (Message.Msg == WM_PAINT)
    {
       //думаю эта строка немного корявая, но работает  :-D 
       Panel1->Dispatch( (void *)&Message);

       TCanvas *can = new TCanvas();
       can->Handle = ::GetDC(Panel1->Handle);
       can->LineTo(50,50);
    }
    else
    {
        Panel1->Dispatch( (void *)&Message);
    }
}



... и не забудь
Код

//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TPanel *Panel1;
private:    // User declarations
public:        // User declarations
    __fastcall TForm1(TComponent* Owner);
    void __fastcall TForm1::SubClassWndProc(Messages::TMessage &Message);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;

Автор: Comm 27.1.2009, 18:45
Классный пример!  smile 

Автор: Comm 27.1.2009, 19:23
Код

if (Message.Msg == WM_PAINT)
    {
       //думаю эта строка немного корявая, но работает  :-D 
       Panel1->Dispatch( (void *)&Message);

       TCanvas *can = new TCanvas();
       can->Handle = ::GetDC(Panel1->Handle);
       can->LineTo(50,50);
       ReleaseDC(Panel1->Handle,can->Handle);
       delete  can;
       
    }

а красивее помоему так:
Код

if (Message.Msg == WM_PAINT)
    {
       //думаю эта строка немного корявая, но работает  :-D 
       Panel1->Dispatch( (void *)&Message);
       HDC HD=GetDC(Panel1->Handle);
       LineTo(HD, 50, 50);
       ReleaseDC(Panel1->Handle,HD);
       
    }


Автор: Dem_max 27.1.2009, 20:01
а почемубы на TPanel не положить PaintBox и в нем уже рисовать в методе OnPaint ?????????????

Автор: Comm 27.1.2009, 20:07
Тоже вариант  smile 

Автор: EEEEEE 27.1.2009, 22:15
Всем спасибо!!!

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

Автор: sergey_85 27.1.2009, 22:29
Comm,
Цитата

а красивее помоему так:Код

if (Message.Msg == WM_PAINT)
    {
       //думаю эта строка немного корявая, но работает  smile 
       Panel1->Dispatch( (void *)&Message);
       HDC HD=GetDC(Panel1->Handle);
       LineTo(HD, 50, 50);
       ReleaseDC(Panel1->Handle,HD);
       
   }


используя TCanvas, мне кажется будет проще и заморочек с WinAPI меньше - отсюда и задачу сделаешь быстрее, хотя есть много вещей которые через канву не сделаешь.

Автор: Comm 27.1.2009, 22:36
Цитата

используя TCanvas, мне кажется будет проще и заморочек с WinAPI меньше - отсюда и задачу сделаешь быстрее, хотя есть много вещей которые через канву не сделаешь. 

Согласен,но я пытаюсь избегать где только можно оператора new =)) 

Автор: sergey_85 27.1.2009, 22:56
Comm,
Цитата

Согласен,но я пытаюсь избегать где только можно оператора new =)) 

да не надо его бояться! без него, к примеру, vcl компоненты  НИКАК не создать (тот же TButton, к примеру)!!!
Просто например всегда делай так:

Код

TCanvas *myCanvas = 0;
  
try
{
    myCanvas = new TCanvas();
    //делаю что хочу ...
}
__finally
{
   if(myCanvas)
  {
     delete myCanvas;
     myCanvas =0;
  }
}


Автор: Comm 27.1.2009, 23:14
Это я знаю,я к тому что если можно обойтись без new то зачем нагружать программу( на выделение памяти ведь требуются ресурсы и время)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)