C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[74128] Re:paintbox에 그릴때 그리는 과정없이 결과만 보여주기?
스머팩트 [lego2000] 3472 읽음    2017-01-25 13:19
안녕하세요.

질문 하신 내용을 살펴 보았습니다.

1. 화상 변경에 대한 인지의 문제

프로그램을 수행해 보니, 화면상에 여러부분이 동시에 갱신됩니다.(사각형이 여기저기 그려짐)
때문에 굉장히 느리다는 느낌을 받게 됩니다.

이런 현상을 개선하려면 PaintBox1을 전부 그린 다음, PaintBox2를 그리고.... PaintBox30을 그리면
그려진다는 느낌을 좀 덜받게 할 수 있습니다.

2. 미리 그리기

이 문제에 대한 근본적인 해결 방법은
메모리(일반적으로 OffScreen 또는 BackBuffer라고 부릅니다.)에 모든 내용을 먼저 그린 다음, 화면에 복사하는 방법입니다.

  (1) PaintBox가 30개 이므로 Bitmap(메모리) 30개를 만들고,
  (2) 30개의 Bitmap에 사각형을 그린다.
  (3) 30개의 Bitmap을 PaintBox에 그려주어야 합니다.

  (참고) Bitmap을 하나만 만들고 PaintBox를 하나씩 갱신하는 방법도 있습니다.
            그렇게 하면 메모리도 적게 쓰고, 구현도 비교적 간단합니다.
            그러나 PaintBox와 PaintBox를 그리는 사이에 약간의 지연시간은 발생할 겁니다.
            이 방법의 구현 및 테스트는 질문자님의 몫으로 남겨두겠습니다.

3. 콤포넌트의 배열화

질문하신 프로그램은 각각의 콤포넌트명을 그대로 사용했기 때문에
위에서 설명한 두가지 내용을 적용하기에 매우 어렵습니다.
각각의 PaintBox 포인터를 배열화 해야만 프로그램이 간단해 질것 같군요.

4. (구현1) 콤포넌트를 배열로 만들고 PaintBox를 순서적으로 그리기

  (1) PaintBox는 10개로 테스트 했습니다.
  (2) 버튼을 누를 때 마다 사각형의 색상이 변하도록 했습니다.
  (3) 프로그램이 시작되면 FindComponent() 함수로 화면에 배치된 PaintBox를 찾습니다.
  (4) 각각의 PaintBox에 도형을 그립니다.(pbGroup1, pbGroup2, ....., pbGroupN)

//---------------------------------------------------------------------------
#include "vcl.h"
#pragma hdrstop

#include "UnitMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

#define PB_COUNT 10
TPaintBox *_PaintBox[PB_COUNT];
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	for(int i=0; i < PB_COUNT; i++)
	{
		_PaintBox[i] = (TPaintBox *)FindComponent("pbGroup"+String(i+1));
	}
}

//---------------------------------------------------------------------------
void DrawRect(TCanvas *canvas, TColor color, int row, int col)
{
	canvas->Pen->Color = color;
	for( int i = 0; i < row; i++ )
		for( int j = 0; j < col; j++ )
			canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
}

int mode = 0;
TColor color[] = { clRed, clBlue };
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	int row = 10;
	int col = 10;

	mode = !mode;
	for(int i=0; i < PB_COUNT; i++)
	{
		DrawRect(_PaintBox[i]->Canvas, color[mode], row, col);
	}
}
//---------------------------------------------------------------------------



5. (구현2) 메모리에 그리고 PaintBox에 복사하기

이 방법은 구현하기에 좀 어렵지만, 결과는 매우 좋습니다.

(1) 프로그램이 시작되면 FindComponent() 함수로 화면에 배치된 PaintBox를 찾습니다.
(2) PaintBox에 해당하는 Bitmap을 만듭니다.
(3) 각각의 Bitmap->Canvas에 도형을 그립니다.
       (참고) 그리기 전에 Bitmap을 PaintBox의 배경색으로 칠해줍니다.(이미지 초기화)
(4) 각각의 Bitmap을 PaintBox에 그립니다.

//---------------------------------------------------------------------------
#include "vcl.h"
#pragma hdrstop

#include "UnitMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

#define PB_COUNT 10
TPaintBox *_PaintBox[PB_COUNT];
TBitmap *_Bitmap[PB_COUNT];
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	for(int i=0; i < PB_COUNT; i++)
	{
		_PaintBox[i] = (TPaintBox *)FindComponent("pbGroup"+String(i+1));
	}

	for(int i=0; i < PB_COUNT; i++)
	{
		_Bitmap[i] = new TBitmap();
		_Bitmap[i]->SetSize(_PaintBox[i]->Width, _PaintBox[i]->Height);
		_Bitmap[i]->PixelFormat = pf32bit;
	}
}

//---------------------------------------------------------------------------
void DrawRect(TCanvas *canvas, TColor color, int row, int col)
{
	canvas->Pen->Color = color;
	for( int i = 0; i < row; i++ )
		for( int j = 0; j < col; j++ )
			canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
}

int mode = 0;
TColor color[] = { clRed, clBlue };
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	int row = 10;
	int col = 10;

	mode = !mode;
	for(int i=0; i < PB_COUNT; i++)
	{
		_Bitmap[i]->Canvas->Brush->Color = _PaintBox[i]->Canvas->Brush->Color;
		_Bitmap[i]->Canvas->FillRect(TRect(0,0,_Bitmap[i]->Width, _Bitmap[i]->Height));
		DrawRect(_Bitmap[i]->Canvas, color[mode], row, col);
	}

	for(int i=0; i < PB_COUNT; i++)
	{
		TRect rect(0,0,_Bitmap[i]->Width, _Bitmap[i]->Height);
		_PaintBox[i]->Canvas->CopyRect(rect, _Bitmap[i]->Canvas, rect);
	}
}


6. 참고사항

  (1) 질문내용에는 TPaintBox를 사용하셨는데요, TImage를 사용 하시는 것이 보다 유용하지 않을 까 하는 생각을 해봅니다.
  (2) PaintBox 30개를 손으로 그리기 싫어서 저는 아래와 같은 코드로 생성했습니다.

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	for(int i=0; I < PB_COUNT; i++)
	{
		_PaintBox[i] = new TPaintBox(NULL);
		_PaintBox[i]->Parent = this;
		_PaintBox[i]->SetBounds((i %5)*110, (i /5)*110, 100, 100);
	}

/*
	for(int i=0; i < PB_COUNT; i++)
	{
		_PaintBox[i] = (TPaintBox *)FindComponent("pbGroup"+String(i+1));
	}
*/

	for(int i=0; I < PB_COUNT; i++)
	{
		_Bitmap[i] = new TBitmap();
		_Bitmap[i]->SetSize(_PaintBox[i]->Width, _PaintBox[i]->Height);
		_Bitmap[i]->PixelFormat = pf32bit;
	}
}


도움이 되셨길 바랍니다.
그럼 안녕히~


Euijung 님이 쓰신 글 :
: 안녕하세요. 윈도우 프로그램은 초보라서 문의드립니다.
:
: 아래와 같이 총 30개의 paintbox를 루프를 돌면서 사각형을 그리고 있습니다.
: 아무래도 paintbox가 많다보니 그리는게 보입니다.
:
: canvas에 그릴때, 그리는 동안은 갱신이 안되고 최종루프가 다 돌고 한번에 보이게 하는 방법도 있는지 궁금합니다.
: 초보다 보니 기초적인 질문일수도있습니다.
: 조언부탁드립니다.
:
: for( int i = 0; i < row; i++ ) {
:         for( int j = 0; j < col; j++ ) {
:             pbGroup1->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup2->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup3->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup4->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup5->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup6->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup7->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup8->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup9->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup10->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup11->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup12->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup13->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup14->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup15->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup16->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup17->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup18->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup19->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup20->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup21->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup22->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup23->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup24->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup25->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup26->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup27->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup28->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup29->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:             pbGroup30->Canvas->Rectangle(0 + (j * 10), 0 + (i * 10), 10 + (j * 10), 10 + (i* 10));
:         }
:     }

+ -

관련 글 리스트
74127 paintbox에 그릴때 그리는 과정없이 결과만 보여주기? Euijung 3525 2017/01/24
74128     Re:paintbox에 그릴때 그리는 과정없이 결과만 보여주기? 스머팩트 3472 2017/01/25
74129         Re:Re:paintbox에 그릴때 그리는 과정없이 결과만 보여주기? Euijung 3390 2017/01/25
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.