빌더 버젼이 6이더군요.. ㅠ_ㅠ 전 아직까지 5 버젼을 쓰거든요... -_-a 운좋게도.. 어제 오프에서 임프님이 C++ Builder 6 평가판을 주신게 있어서 읽어올 수 있었네요.. 근데, 평가판에서 저장된게 다른 점이 있다면.. 그건 수정해 주셔야 할꺼예요..
일단, 문제에 관한 몇가지 점을 알려드리겠습니다.
Image 객체는 자동으로 Repaint 가 됩니다. 그렇기 때문에 선이나 캔버스에 다른 작업을 하시게 되면 그때그때마다 계속 그려지게 되는거죠. 이건, Update 를 막아도.. DoubleBuffered 를 설정해도 마찬가지로 깜빡이게 됩니다.
Image 로 처리를 하기 위해서는, WM_ERASEBKND 메세지를 받아서 무시해주고, LockWindowUpdate API로 해당 Repaint를 무시하고 나중에 한꺼번에 그려주는 방법이 있습니다. 하지만 이런 종류의 어플리케이션은 간단히 PaintBox로 바꿔서 처리하는 방법이 가장 무난합니다.
PaintBox는 Repaint가 되지 않고, Bitmap 객체가 없기 때문에 사용하기 전까지 준비해야할 코딩 작업이 많지만, 한번 작성해 놓으시면 Image 와는 Canvas 에 접근성이 똑같으니.. 그리 큰 어려움은 없을것이라고 생각됩니다. (뭐.. 소스코드에서도 잘 분리해서 짜놓으셨던데요.. ^^)
PaintBox가 Repaint가 없기 때문에 화면이 무엇을 그려주었는지 기억을 해 놓으셔야 합니다. 이게 귀찮으시면 따로 비트맵을 동적 생성 하셔서 계속 저장시켜주는 방법도 괜찮지만, 전체를 한꺼번에 그려주어야 하니.. 속도는.. 느리겠죠.. (그래도 깜빡임은 없을껍니다)
지금은.. 간단히 된다는 것만을 보여드리기 위해.. 소스의 최적화는 신경쓰지 않았습니다. 그렇기 때문에 PaintBox에 비트맵 그림을 넣을때.. 이전에 사용하신 Image 그림을 그냥 내부적으로 복사를 시킵니다.. 이건.. 비트맵을 동적생성하여 PaintBox넣고 해제하는 그런 함수를 따로 만드시는게 좋을거라고 생각됩니다.
그리고 OnPaint에서 파일을 항상 다시 불러오는데 이 부분도, 위의 함수를 따로 만드시면 그 함수를 호출하는 부분으로 바꿔주셔야 합니다.
일단, 왼쪽에 작은 이미지 창만을 PaintBox 로 변경하였습니다. 오른쪽 큰 화면은.. 똑같은 방법으로 처리하시면 되겠지요~? ^^
Image의 Flicking 현상에 관해서 참고하시려면 아래를 보시면 됩니다.. ^^
http://www.bcbdev.com/faqs/faq34.htm
http://www.bcbdev.com/faqs/faq35.htm
http://www.bcbdev.com/faqs/faq36.htm
프로젝트는 메일로 다시 발송해 드렸습니다.. 소스에서 추가시키거나 변경된 부분은 "- chris" 라고 주석을 전부 붙여놓았으니.. 찾기로 하셔서 보시면 될꺼예요...
최흥배 님이 쓰신 글 :
: 유영인.Chris 님이 쓰신 글 :
: : 제 실력으로는 아래 소스만 보구서는.. 원인을 찝어내니가.. 힘들것 같네요.
: :
: : Line 을 일일히 줄에 다 그려주는 루틴도 상당히 느릴 것 같고.. Invalidate 도 썩 내키지 않구요.. 만약 급하신 일이라면.. 메일로 프로젝트 압축해서 보내주시면 어떻게든 수정을 해서 보내드릴께요..
: :
: :
: : 최흥배 님이 쓰신 글 :
: : : BitBlt는 제가 Invalidate를 사용하니까 제대로 되는데
: : : 그래도 깜빡이는건 여전하네요...
: : : 제발 좀 아시는분 좀 가르쳐주세요...ㅠ.ㅠ
: : : 이건 게임 제작에 사용할 맵툴이라 깜빡이면 눈이 너무 피곤 할것 같아
: : : 깜빡이는거 꼭 고치고 싶네요
: : :
: : : : ........
: : : : void CImgprocess::WorkViewInit(TImage &workview)
: : : : {
: : : : m_WorkView = &workview;
: : : :
: : : : int width,height;
: : : : //WorkView의 크기.
: : : : width = m_WorkView->Width;
: : : : height = m_WorkView->Height;
: : : : m_iWorkWidth = width;
: : : : m_iWorkHeight = height;
: : : : // target비트맵 초기화.
: : : : m_TargetImg->Width = width;
: : : : m_TargetImg->Height = height;
: : : : //모바일에서 사용하는 투명색을 바탕에 칠한다.
: : : : m_TargetImg->Canvas->Brush->Color = TColor(RGB(32,144,32));
: : : : m_TargetImg->Canvas->FillRect(TRect(0,0,width,height));
: : : : WHLineDraw(*m_TargetImg,width,height,m_iTileW,m_iTileH);
: : : : Swap();
: : : : }
: : : :
: : : : // 이미지 컨트롤 바탕을 위에 지정한 색으로 칠하기 위해 비트맵에 가로,세로로 선을 그립니다.
: : : : void CImgprocess::WHLineDraw(TImage& image,int x, int y, int tilewidth, int tileheight)
: : : : {
: : : : image.Canvas->Pen->Style = psDot;
: : : : for(int i=0;i<=x;i+=tilewidth)
: : : : {
: : : : image.Canvas->MoveTo(i,0);
: : : : image.Canvas->LineTo(i,y);
: : : : }
: : : : for(int i=0;i<=y;i+=tileheight)
: : : : {
: : : : image.Canvas->MoveTo(0,i);
: : : : image.Canvas->LineTo(x,i);
: : : : }
: : : :
: : : : }
: : : :
: : : : // 비트맵에 다른 비트맵에서 원하는부분만큼을 지정한 위치에 그립니다.
: : : : void CImgprocess::DrawWorkViewTile(TileInfo& desttile)
: : : : {
: : : : m_ImgMat[m_WorkTilePos.row][m_WorkTilePos.col] = m_ImgTilePos;
: : : : m_TargetImg->Canvas->CopyRect(desttile.rRange,m_SrcBmp->Canvas,
: : : : TRect(0,0,m_iTileW-1,m_iTileH-1));
: : : : Swap();
: : : : }
: : : :
: : : : // 비트맵을 이미지 컨트롤에 그립니다.
: : : : void CImgprocess::Swap()
: : : : {
: : : : if(m_TargetImg == NULL) return;
: : : : BitBlt(m_WorkView->Canvas->Handle, 0,0,
: : : : m_iWorkWidth,m_iWorkHeight,
: : : : m_TargetImg->Canvas->Handle, 0, 0, SRCCOPY);
: : : m_WorkView->Invalidate();
: : : :
: : : : //CopyRect는 깜박임이 있네요.
: : : : //m_WorkView->Canvas->CopyRect(TRect(0,0,m_iWorkWidth,m_iWorkHeight),
: : : : // m_TargetImg->Canvas,TRect(0,0,m_iWorkWidth,m_iWorkHeight));
: : : : }
: : :
: : :