다음으로 소개할 클래스는 CPaintDC 입니다.
CPaintDC는 WM_PAINT라는 Flag성 메세지가 발생 했을 때 사용해야 하는 클래스입니다.
Window는 Message가 들어오는 곳이 Message Queue와 Message Table 2개가 있는데,
그 중 우선순위로 처리 되는 영역은 Message Queue부분이며, 이 영역의 메세지가 모두 처리되면 Message Table을 처리하게 됩니다.
WM_PAINT는 Invaild Area가 Vaild Area로 됐을 시 들어오는 메세지이며, 이 메세지에는 자신이 다시 그려야 할 영역의 값을 포함해서 들어옵니다.
WM_PAINT 메세지는 Message Table에 존재하며, 연속해서 발생된다고 그 때 마다 계속 처리되는 메세지가 아니고 메세지가 발생 했을 시 값을 1로 바꾸는 역할을 합니다.
CPaintDC는 Message Table의 WM_PAINT값을 확인하고 1로 설정되어 있으면 0으로 바꿔주는 함수입니다.
즉, WM_PAINT 메세지가 있을 경우 자신의 Window 화면을 다시 갱신하는 함수입니다.
코드에서 사용하는 방법을 알려드리겠습니다.
<TestDCDlg.h>
//마우스 좌표를 저장할 공간을 100으로 define한다.
#define MAX_COUNT 100
//마우스 좌표를 저장할 공간을 100으로 define한다.
#define MAX_COUNT 100
class CTestDCDlg : public CDialog
{
private :
//마우스 x, y 좌표를 저장할 POINT 구조체를 생성한다.
POINT mClickPos[MAX_COUNT];
//마우스 좌표가 몇개가 저장되었는지 확인하기 위해 Count변수를 생성
int mClickCount;
}
<TestDCDlg.cpp>
BOOL CTestDCDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//전역변수인 mClickCount를 0으로 초기화 시켜준다.
mClickCount = 0;
}//OnInitDialog
void CTestDCDlg::OnPaint()
{
//예전 윈도우는 작업표시줄이 없어 최소화 창을 누르면 아이콘 형식으로 배치됬었다.
//지금은 작업표시줄이 있어 아이콘 형식으로 배치 되지않는다.
//아이콘 형식이면 if문 실행
if ( IsIconic())
{
...
}
//아이콘 형식이 아니면 else문 실행
else
{
//CPaintDC 권한을 얻어온다.
CPaintDC dc(this);
//저장된 마우스 좌표의 갯수만큼 반복한다.
for ( int i=0; i<mClickCount; i++ )
{
//DrawMyShape() 함수를 호출한다.
DrawMyShape(&dc, mClickPos[i];
}
}
}//OnPaint
void CTestDCDlg::OnLButtonUP(UINT nFlags, CPoint point)
{
//CClientDC의 권한을 획득한다.
CClientDC dc(this);
//DrawMyShape() 함수를 호출한다.
DrawMyShape(&dc, point);
//전역변수인 mClickPos의 해당하는 index배열에 마우스 x, y좌표를 저장하고,
//Count수를 증가시킨다.
mClickPos[mClickCount].x = point.x;
mClickPos[mClickCount].y = point.y;
mClickCount++;
CDialog::OnLButtonUP(nFlags, point);
}//OnLButtonUP
//DrawMyShape() 함수는 CDC의 포인터를 첫번째 인자로 넘겨받고
//두번째 인자로 마우스의 x, y좌표를 가진 CPoint함수를 넘겨받는다.
//OnPaint() 영역에서 두번째 인자로 POINT 구조체를 넘겨받았는데,
//CPoint() 함수는 원래 POINT 구조체이기 때문에 인자로 받는것이 가능하다.
void CTestDCDlg::DrawMyShape(CDC *paramDC, CPoint point)
{
//CDC클래스의 포인터로 접근하여 사각형을 그려낸다.
paramDC->Rectangle(point.x, point.y, point.x + 20, point.y + 20);
}//DrawMyShape
OnPaint() 영역에서 도형을 그릴 시 CPaintDC 권한을 얻어 작업을 할 수도 있지만, invalidate() 함수를 사용하여 그려낼 수도 있습니다.
하지만 invalidate() 함수는 도형을 그릴 시 해당하는 index 좌표의 도형을 하나씩 하나씩 그려나가는 방식이 아닌, 처음 index부터 다시 그려내는 방식이기 때문에 반복문이 길어질 경우 안좋은 결과를 낼 수도 있습니다.
출처 - 탑스소프트