MFC/윈도우 프로그래밍

MFC 윈도우 프로그래밍 4장 연습문제(9~16)

꾸준함. 2018. 3. 25. 02:02

윈도우 프로그래밍 Visual C++ 2010 MFC Programming(김선우, 신화서 저) 4장 연습문제입니다.

저번에 이어 나머지 연습문제를 풀어봤습니다.


*2018년 3월 29일 부연설명

사실 연습문제를 풀 당시 Invalidate()의 중요성을 파악하지 못한 상태였습니다.

Invalidate()를 이용하면 훨씬 간단하게 풀 수 있는 문제들이 많습니다.


[4-9]

//DrawTexts 예제에서 첫 번째 문장은 밑줄, 두 번째 문장은 이탤릭,

//세 번째 문장은 볼드로 출력되도록 예제를 수정하시오

void CChildView::OnPaint()

{

        CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.

       

        // TODO: 여기에 메시지 처리기 코드를 추가합니다.

        CRect rect;

        GetClientRect(&rect);

 

        CFont font1, font2, font3;

        //문자 폭, 문자 높이, 문자 기울기, 문자 방향, 문자 굵기, 기울기, 밑줄

        //취소선, 문자셋, 출력 정확도, 클리핑 정확도, 출력의 질, 자간과 폰트

        //밑줄

        font1.CreateFontW(40, 0, 0, 0, FW_NORMAL, FALSE, TRUE, 0, NULL, NULL, NULL, NULL, NULL, NULL);

        dc.SelectObject(&font1);

        dc.SetTextColor(RGB(255, 0, 0)); //글자를 빨간색으로 설정

        dc.SetBkColor(RGB(255, 255, 0)); //배경을 노란색으로 설정

        dc.DrawText(CString(_T("DrawText 함수를 연습합니다. [1]")), &rect, 0);

        //이탤릭

        font2.CreateFontW(40, 0, 0, 0, FW_NORMAL, TRUE, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);

        dc.SelectObject(&font2);

        dc.DrawText(CString(_T("DrawText 함수를 연습합니다. [2]")), &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

 

        dc.SetTextAlign(TA_CENTER); //가운데 정렬방식

        dc.SetTextColor(RGB(0, 0, 255)); //글자를 파란색으로 설정

        dc.SetBkColor(RGB(0, 255, 0)); //배경을 초록색으로 설정

        //볼드

        font3.CreateFontW(40, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);

        dc.SelectObject(&font3);

        dc.TextOutW(rect.right / 2, 3 * rect.bottom / 4, CString(_T("TextOut 함수를 연습합니다.")));

        // 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.

}

 


[4-10]

//DrawTexts 예제에서 첫 번째 문장은 크기 10, 두 번째 문장은 크기 12,

//세 번째 문장은 크기 14로 출력되도록 예제를 수정하시오

void CChildView::OnPaint()

{

        CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.

       

        // TODO: 여기에 메시지 처리기 코드를 추가합니다.

        CRect rect;

        GetClientRect(&rect);

       

        CFont font1, font2, font3;

        dc.SetTextColor(RGB(255, 0, 0)); //글자를 빨간색으로 설정

        dc.SetBkColor(RGB(255, 255, 0)); //배경을 노란색으로 설정

        font1.CreateFontW(-::MulDiv(10, GetDeviceCaps(dc.m_hDC, LOGPIXELSY), 72), 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);

        dc.SelectObject(&font1);

        dc.DrawText(CString(_T("DrawText 함수를 연습합니다. [1]")), &rect, 0);

        font2.CreateFontW(-::MulDiv(12, GetDeviceCaps(dc.m_hDC, LOGPIXELSY), 72), 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);

        dc.SelectObject(&font2);

        dc.DrawText(CString(_T("DrawText 함수를 연습합니다. [2]")), &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

 

        dc.SetTextAlign(TA_CENTER); //가운데 정렬

        dc.SetTextColor(RGB(0, 0, 255)); //글자를 파란색 설정

        dc.SetBkColor(RGB(0, 255, 0)); //배경 초록색 설정

        font3.CreateFontW(-::MulDiv(14, GetDeviceCaps(dc.m_hDC, LOGPIXELSY), 72), 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, NULL, NULL, NULL, NULL, NULL, NULL);

        dc.SelectObject(&font3);

        dc.TextOutW(rect.right / 2, 3 * rect.bottom / 4, CString(_T("TextOut 함수를 연습합니다.")));

        // 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.

}


[4-11]

<ChildView.h>

UINT click 추가


<ChildView.cpp>

CChildView::CChildView()

{

        click = 0;

}

//마우스 왼쪽 버튼을 누를 때마다 매핑 모드가 MM_ISOTROPIC MM_ANISOTROPIC으로

//전환되어 출력되도록 MappingMode2 예제를 수정하시오

void CChildView::OnPaint()

{

        CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.

        // TODO: 여기에 메시지 처리기 코드를 추가합니다.

        if (!click)

        {

               CRect rect;

               GetClientRect(&rect);

               dc.SetMapMode(MM_ISOTROPIC);

               dc.SetWindowExt(100, 100);

               dc.SetViewportExt(rect.Width(), rect.Height());

               dc.RoundRect(0, 0, 100, 100, 50, 50);

               dc.DrawEdge(CRect(20, 20, 80, 80), BDR_SUNKENINNER | BDR_RAISEDOUTER, BF_RECT);

        }

        // 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.

}

 

 

 

void CChildView::OnLButtonDown(UINT nFlags, CPoint point)

{

        // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

        CClientDC dc(this);

        CRect rect;

        GetClientRect(&rect);

        ++click;

        if (click % 2 == 0)

               dc.SetMapMode(MM_ISOTROPIC);

        else

               dc.SetMapMode(MM_ANISOTROPIC);

        dc.SetWindowExt(100, 100);

        dc.SetViewportExt(rect.Width(), rect.Height());

        dc.RoundRect(0, 0, 100, 100, 50, 50);

        dc.DrawEdge(CRect(20, 20, 80, 80), BDR_SUNKENINNER | BDR_RAISEDOUTER, BF_RECT);

        //CWnd::OnLButtonDown(nFlags, point);

}

 

[4-12]

// CChildView 메시지 처리기

//클라이언트 영역 배경 전체에 비트맵 이미지를 타일 형태로 반복 출력하도록 Brushes 예제 수정

//, 비트맵 이미지를 이용한 패턴 브러시로 출력하되, 직접 출력하지 않고 윈도우 클래스를

//생성할 때 지정하는 방식 사용

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)

{

        if (!CWnd::PreCreateWindow(cs))

               return FALSE;

 

        CBitmap bitmap;

        bitmap.LoadBitmapW(IDB_BITMAP1);

        HBRUSH h_brush=CreatePatternBrush(bitmap);

        cs.dwExStyle |= WS_EX_CLIENTEDGE;

        cs.style &= ~WS_BORDER;

        cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,

               ::LoadCursor(NULL, IDC_ARROW), h_brush, NULL);

 

        return TRUE;

}


[4-13]

//ANSI_FIXED_FONT 내장 폰트를 설정하여 타원 위에 "타원(Ellipse)",

//ANSI_VAR_FONT 내장 폰트를 사용하여 사각형 위에 "사각형(Tetragon)"이라는

//글자를 출력하도록 StockObjects 예제를 수정하시오

void CChildView::OnPaint()

{

        CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.

       

        // TODO: 여기에 메시지 처리기 코드를 추가합니다.

        dc.Ellipse(100, 50, 200, 200);

        dc.SelectStockObject(ANSI_FIXED_FONT);

        dc.TextOutW(100, 200, _T("타원(Ellipse)"));

 

        dc.Rectangle(300, 350, 400, 400);

        dc.SelectStockObject(ANSI_VAR_FONT);

        dc.TextOutW(300, 400, _T("사각형(Tetragon)"));

        // 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.

}

 


[4-14]

//Bitmaps 예제의 클라이언트 영역에 비트맵을 출력하되, 평소에는 원래 크기로 보여주고

//마우스 왼쪽 버튼이 눌린 상태에서는 클라이언트 영역 전체로 확대되도록 수정하시오.

void CChildView::OnPaint()

{

        CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.

       

        // TODO: 여기에 메시지 처리기 코드를 추가합니다.

        CBitmap bitmap;

        bitmap.LoadBitmapW(IDB_BITMAP1);

        BITMAP bmpinfo;

        bitmap.GetBitmap(&bmpinfo);

 

        //메모리 DC를 만든 후 비트맵 선택

        CDC dcmem;

        dcmem.CreateCompatibleDC(&dc);

        dcmem.SelectObject(&bitmap);

 

        //비트맵 화면에 출력

        dc.BitBlt(10, 10, bmpinfo.bmWidth, bmpinfo.bmHeight, &dcmem, 0, 0, SRCCOPY);

        // 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.

}

 

 

 

void CChildView::OnLButtonDown(UINT nFlags, CPoint point)

{

        // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

        CClientDC dc(this);

        CRect rect;

        GetClientRect(&rect);

 

        CBitmap bitmap;

        bitmap.LoadBitmapW(IDB_BITMAP1);

        BITMAP bmpinfo;

        bitmap.GetBitmap(&bmpinfo);

 

        //메모리 DC를 만든 후 비트맵 선택

        CDC dcmem;

        dcmem.CreateCompatibleDC(&dc);

        dcmem.SelectObject(&bitmap);

       

        //확대

        dc.StretchBlt(10, 10, bmpinfo.bmWidth * 4, bmpinfo.bmHeight * 4, &dcmem, 0, 0, bmpinfo.bmWidth, bmpinfo.bmHeight, SRCCOPY);

        //CWnd::OnLButtonDown(nFlags, point);

}

 

[4-15]

<ChildView.h>

UINT click; 추가


<ChildView.cpp>

CChildView::CChildView()

{

        click = 0;

}

 

//마우스 왼쪽 버튼을 누를 때마다 비트맵이 180도 회전되어

//위아래가 뒤바뀌어 출력되도록 Bitmaps 예제를 수정하시오

void CChildView::OnPaint()

{

        CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.

       

        // TODO: 여기에 메시지 처리기 코드를 추가합니다.

        //비트맵 리소스를 로드한 후 크기 정보를 얻는다

        if (!click)

        {

               CBitmap bitmap;

               bitmap.LoadBitmapW(IDB_BITMAP1);

               BITMAP bmpinfo;

               bitmap.GetBitmap(&bmpinfo);

 

               //메모리 DC를 만든 후 비트맵을 선택해 넣는다

               CDC dcmem;

               dcmem.CreateCompatibleDC(&dc);

               dcmem.SelectObject(&bitmap);

 

               //비트맵 화면에 출력

               dc.BitBlt(10, 10, bmpinfo.bmWidth, bmpinfo.bmHeight, &dcmem, 0, 0, SRCCOPY);

        }

        // 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.

}

 

 

 

void CChildView::OnLButtonDown(UINT nFlags, CPoint point)

{

        // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.

        CClientDC dc(this);

        CBitmap bitmap;

        bitmap.LoadBitmapW(IDB_BITMAP1);

        BITMAP bmpinfo;

        bitmap.GetBitmap(&bmpinfo);

 

        //메모리 DC를 만든 후 비트맵을 선택해 넣는다

        CDC dcmem;

        dcmem.CreateCompatibleDC(&dc);

        dcmem.SelectObject(&bitmap);

 

        ++click;

        if (click % 2 == 0)

               dc.BitBlt(10, 10, bmpinfo.bmWidth, bmpinfo.bmHeight, &dcmem, 0, 0, SRCCOPY);

        else

               //180도 회전

               dc.StretchBlt(10 + bmpinfo.bmWidth - 1, 10 + bmpinfo.bmHeight - 1, -bmpinfo.bmWidth, -bmpinfo.bmHeight, &dcmem, 0, 0, bmpinfo.bmWidth, bmpinfo.bmHeight, SRCCOPY);

        //CWnd::OnLButtonDown(nFlags, point);

}

 

[4-16]

 

//208쪽의 Regions 예제 실행 결과에서 겹친 부분이

//빨간색으로 채워지도록 수정하시오

void CChildView::OnPaint()

{

        CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.

       

        // TODO: 여기에 메시지 처리기 코드를 추가합니다.

        CRgn rgn1, rgn2, rgn3;

        rgn1.CreateRectRgn(0, 0, 1, 1); //임의로 만든 리전

        rgn2.CreateRectRgn(10, 10, 100, 100);

        rgn3.CreateEllipticRgn(50, 50, 200, 200);

        rgn1.CombineRgn(&rgn2, &rgn3, RGN_XOR); //겹치지 않는 부분

        CBrush brush(RGB(0, 0, 255)); //파란색

        dc.FillRgn(&rgn1, &brush);

        rgn1.CombineRgn(&rgn2, &rgn3, RGN_AND); //겹치는 부분

        CBrush brush2(RGB(255, 0, 0)); //빨간색

        dc.FillRgn(&rgn1, &brush2);

        // 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.

}

 


개발환경:Visual Studio 2017


지적, 조언, 질문 환영입니다! 댓글 남겨주세요~

반응형