윈도우 프로그래밍 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
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
'MFC > 윈도우 프로그래밍' 카테고리의 다른 글
MFC 윈도우 프로그래밍 5장 연습문제(1~8) (0) | 2018.03.29 |
---|---|
MFC 윈도우 프로그래밍 4장 심화문제 (0) | 2018.03.26 |
MFC 윈도우 프로그래밍 4장 연습문제(1~8) (2) | 2018.03.24 |
MFC 윈도우 프로그래밍 3장 심화문제 (4) | 2018.03.21 |
MFC 윈도우 프로그래밍 3장 연습문제(9~16) (0) | 2018.03.18 |