새우의 세상사

원문 링크 : [펌] MDI 폼에서 Client 영역에 배경 그리기 2

MDI 폼에서 Client 영역에 배경 그리기 2 - 더욱 쉽게

작성자 : 장성호  (nasilso)  읽음 : 415    2007-05-25 오전 1:57:59

================================================

MDI 폼의 메인 화면에 배경 이미지 그리기 - 여기는 직접 작성한 것임.

1, 메인 화면의 클래스에 다음과 같이 정의한다.

    TCanvas *MDICanvas;
   Graphics::TBitmap *imgBG;

2. 폼의 FormCreate 함수에 다음을 넣어 초기화한다.

void __fastcall TCMain::FormCreate(TObject *Sender)
{
    MDICanvas=new TCanvas;
    MDICanvas->Handle=GetDC(ClientHandle);
    imgBG = new Graphics::TBitmap;
    if (FileExists ("bgfile.bmp"))
        imgBG->LoadFromFile("bgfile.bmp");
}

3. 폼의 FormResize 함수에 다음과 같이 넣어준다.

void __fastcall TCMain::FormResize(TObject *Sender)
{
    MDICanvas->Draw(0, 0, imgBG);
}

4. 폼의 FormPaint 함수에 다음과 같이 넣어준다.

void __fastcall TCMain::FormPaint(TObject *Sender)
{
    MDICanvas->Draw(0, 0, imgBG);
} // 여기까지

================================================

여기 tip 게시판에 이미 같은 내용의 tip을 민병권님께서 올려놓은 것이 있습니다.

http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=357

위에 tip은 한가지가 문제가 있던데.. Form을 Resize할 때는 WM_ERASEBKGND 메세지가 발생하지 않아 잔상이 있거나 이상하게 되더군요

위 팁에 문제점을 보완하려면 그냥 Form의 Resize 이벤트에서 다시 한번 똑같이 그려주면 문제가 해결되더군요

----------------------------------------------------------------------------------

[쉬운방법]

그런데 위 팁에서 또하나 불편한것은 sub-classing을 해야한다는 것입니다.
뭐 서브클래싱이 그렇게 어렵고 복잡한것은 아니지만....

sub-classing 하지않고 하는 쉬운방법은 그냥 Form의 Repaint 이벤트와 Resize 이벤트에 배경을 그려주면 됩니다.

여기서 중요한 것은 Form의 Handle과 MDI Client의 Handle이 다르다는데 있습니다.
그러므로 그려져야할 HDC도 Form의 DC인 Canvas에 그려주는 것이 아니라 MDI Client의 HDC에 그려줘야 하는것입니다.


즉 아래와 같이 간단히 하면 됩니다.

문론 bmp에 배경 이미지가 들어있어야 하구요

//---------------------------------------------------------------------------

void __fastcall TDLG_MAIN::FormPaint(TObject *Sender)
{
        HDC DC=GetDC(ClientHandle);
       BitBlt(DC,0,0,bmp->Width,bmp->Height,bmp->Canvas->Handle ,0,0,SRCCOPY    );
       //StretchBlt(DC, 0, 0, Width, Height, bmp->Canvas->Handle, 0, 0, bmp->Width, bmp->Height, SRCCOPY);
}

//---------------------------------------------------------------------------

void __fastcall TDLG_MAIN::FormResize(TObject *Sender)
{
        HDC DC=GetDC(ClientHandle);
       BitBlt(DC,0,0,bmp->Width,bmp->Height,bmp->Canvas->Handle ,0,0,SRCCOPY    );
       //StretchBlt(DC, 0, 0, Width, Height, bmp->Canvas->Handle, 0, 0, bmp->Width, bmp->Height, SRCCOPY);

}

//---------------------------------------------------------------------------

[응용 방법]

이를 좀더 응용하여서 하는 쉬운 방법이 있는데요

VCL의 Canvas를 이용하는 방법입니다.

여기 tip에 보면 김태선님의 "바탕화면을 TCanvas로 만들어 주는 클래스"라는 것을 응용한 것으로 http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=551 TCanvas를 하나 new 하시고 그 canvas의 HDC를 MDI Clinet 영역의 HDC로 설정해주면 됩니다
그러면 아래와 같이 Paint 나 Resize 이벤트때 코딩이 더 짧아질 수 있습니다.

TCanvas *MDICanvas;

void __fastcall TDLG_MAIN::FormCreate(TObject *Sender)
{
       MDICanvas=new TCanvas;
       MDICanvas->Handle=GetDC(ClientHandle);
}

//---------------------------------------------------------------------------

void __fastcall TDLG_MAIN::FormPaint(TObject *Sender)
{
        MDICanvas->Draw(0,0,bm_bg);
}

//---------------------------------------------------------------------------

void __fastcall TDLG_MAIN::FormResize(TObject *Sender)
{
      MDICanvas->Draw(0,0,bm_bg);
}

//---------------------------------------------------------------------------

그리고 또 이렇게 Client영역에 Canvas로 접근할 수 있으므로 아래와 같이 쉽게 원하는 내용을 client 영역에 그릴수 있습니다.

void __fastcall TDLG_MAIN::FormPaint(TObject *Sender)
{
        MDICanvas->Draw(0,0,bm_bg);
        MDICanvas->Brush->Color=clRed;
        MDICanvas->Pen->Color=clWhite;
        MDICanvas->Rectangle(Rect(100,100,200,300));

}

//---------------------------------------------------------------------------

요즘에 MDI로 프로그램하는경우가  많이 없는것 같기는 한데 혹 누군가 필요하실 수도 있을것 같아서 올려봅니다.

신고
Posted by 새우날다 Trackback 2 Comment 0


티스토리 툴바