윈도우 프로그래밍 Visual C++ 2010 MFC Programming(김선우, 신화서 저) 4장 연습문제입니다.
우선 1~8번 문제까지 풀어봤습니다.
[4-1]
//직사각형과 타원 모두 CRect 객체를 사용하도록 PaintDC 예제를 수정하시오
void CChildView::OnPaint()
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
CRect rect1(0, 0, 200, 100), rect2(200, 100, 500, 200);
dc.Rectangle(&rect1);
dc.Ellipse(&rect2);
// 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.
}
[4-2]
<ChildView.h>
#pragma once
#include <afxtempl.h>
// CChildView 창
class CChildView : public CWnd
{
// 생성입니다.
public:
CChildView();
// 특성입니다.
public:
CArray<CPoint, POINT> m_rect, m_elli; //직사각형과 타원
UINT rIdx, eIdx;
// 작업입니다.
public:
// 재정의입니다.
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
// 구현입니다.
public:
virtual ~CChildView();
// 생성된 메시지 맵 함수
protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
};
<ChildView.cpp>
//ClientDC 예제가 다른 윈도우에 가려지거나 최소화 상태에서 복원되어 윈도우가 다시
//그려져도 그렸던 원이 모두 나타나도록 예제를 수정하시오
void CChildView::OnPaint()
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
for (int i = 0; i < rIdx; i++)
{
CRect rect(m_rect[i].x - 20, m_rect[i].y - 20, m_rect[i].x + 20, m_rect[i].y + 20);
dc.Rectangle(&rect);
}
for (int i = 0; i < eIdx; i++)
{
CRect rect(m_elli[i].x - 20, m_elli[i].y - 20, m_elli[i].x + 20, m_elli[i].y + 20);
dc.Ellipse(&rect);
}
// 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.
}
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CClientDC dc(this);
dc.Rectangle(point.x - 20, point.y - 20, point.x + 20, point.y + 20);
m_rect[rIdx++] = point;
//CWnd::OnLButtonDown(nFlags, point);
}
void CChildView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CClientDC dc(this);
dc.Ellipse(point.x - 20, point.y - 20, point.x + 20, point.y + 20);
m_elli[eIdx++] = point;
//CWnd::OnRButtonDown(nFlags, point);
}
[4-3]
<ChildView.h>
// ChildView.h: CChildView 클래스의 인터페이스
//
#pragma once
#include <afxtempl.h>
// CChildView 창
class CChildView : public CWnd
{
// 생성입니다.
public:
CChildView();
// 특성입니다.
public:
CList<CPoint, POINT> m_rect, m_elli;
// 작업입니다.
public:
// 재정의입니다.
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
// 구현입니다.
public:
virtual ~CChildView();
// 생성된 메시지 맵 함수
protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
};
<ChildView.cpp>
//ClientDC 예제가 다른 윈도우에 가려지거나 최소화 상태에서 복원되어 윈도우가 다시
//그려져도 그렸던 원이 모두 나타나도록 예제를 수정하시오
void CChildView::OnPaint()
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
POSITION pos1 = m_rect.GetHeadPosition();
POSITION pos2 = m_elli.GetHeadPosition();
while (pos1 != NULL)
{
CPoint coord = m_rect.GetNext(pos1);
dc.Rectangle(coord.x - 20, coord.y - 20, coord.x + 20, coord.y + 20);
}
while (pos2 != NULL)
{
CPoint coord = m_rect.GetNext(pos2);
dc.Ellipse(coord.x - 20, coord.y - 20, coord.x + 20, coord.y + 20);
}
// 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.
}
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CClientDC dc(this);
dc.Rectangle(point.x - 20, point.y - 20, point.x + 20, point.y + 20);
m_rect.AddTail(point);
//CWnd::OnLButtonDown(nFlags, point);
}
void CChildView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CClientDC dc(this);
dc.Ellipse(point.x - 20, point.y - 20, point.x + 20, point.y + 20);
m_elli.AddTail(point);
//CWnd::OnRButtonDown(nFlags, point);
}
[4-4]
//배경이 초록색인 직사각형을 그리고 그 위에 투명모드로 글자를 출력하도록
//WindowDC 예제를 수정하시오
void CMainFrame::OnNcPaint()
{
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
// 그리기 메시지에 대해서는 CFrameWnd::OnNcPaint()을(를) 호출하지 마십시오.
//운영체제가 자동으로 비클라이언트 영역을 그리게 한다
CFrameWnd::OnNcPaint();
//타이틀바에 직사각형을 그린다
CWindowDC dc(this);
int height = GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYSIZEFRAME);
dc.Rectangle(150, 0, 350, height + 1);
dc.FillSolidRect(CRect(150, 0, 350, height + 1), RGB(0, 255, 0)); //초록색
dc.SetBkMode(TRANSPARENT); //투명
//메인(프레임) 윈도우의 크기를 얻는다
CRect rect;
GetWindowRect(&rect);
//타이틀바에 크기 출력
CString str;
str.Format(_T("Width=%4d, Height=%4d"), rect.Width(), rect.Height());
dc.TextOutW(160, 7, str);
}
[4-5]
// ChildView.cpp: CChildView 클래스의 구현
//
#include "stdafx.h"
#include "연습문제 4-5.h"
#include "ChildView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CChildView
CChildView::CChildView()
{
//확장 메타파일 객체를 생성하고 초기화
CMetaFileDC dc;
dc.CreateEnhanced(NULL, NULL, NULL, NULL);
//멤버 함수를 호출하여 출력
dc.Rectangle(0, 0, 10, 10);
dc.Ellipse(1, 1, 9, 9);
//확장 메타파일 핸들을 얻는다
m_hmf = dc.CloseEnhanced();
}
CChildView::~CChildView()
{
//확장 메타파일을 삭제한다
::DeleteEnhMetaFile(m_hmf);
m_rect.RemoveAll();
m_elli.RemoveAll();
}
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()
// CChildView 메시지 처리기
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);
return TRUE;
}
//윈도우가 다른 윈도우에 가려지거나 최소화 상태에서 복원되어 다시 그려져도 그렸던 원이
//모두 나타나도록 MetaFileDC 예제를 수정하시오. 단, 정보는 CList 클래스를 이용하여 보관한다
void CChildView::OnPaint()
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
POSITION pos1 = m_rect.GetHeadPosition(), pos2 = m_elli.GetHeadPosition();
while (pos1 != NULL)
{
CPoint coord = m_rect.GetNext(pos1);
CRect rect(coord.x - 20, coord.y - 20, coord.x + 20, coord.y + 20);
dc.PlayMetaFile(m_hmf, &rect);
}
while (pos2 != NULL)
{
CPoint coord = m_elli.GetNext(pos2);
CRect rect(coord.x - 50, coord.y - 20, coord.x + 50, coord.y + 20);
dc.PlayMetaFile(m_hmf, &rect);
}
// 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.
}
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CClientDC dc(this);
CRect rect(point.x - 20, point.y - 20, point.x + 20, point.y + 20);
dc.PlayMetaFile(m_hmf, &rect);
m_rect.AddTail(point);
//CWnd::OnLButtonDown(nFlags, point);
}
void CChildView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CClientDC dc(this);
CRect rect(point.x - 50, point.y - 20, point.x + 50, point.y + 20);
dc.PlayMetaFile(m_hmf, &rect);
m_elli.AddTail(point);
//CWnd::OnRButtonDown(nFlags, point);
}
[4-6]
//마우스 왼쪽 버튼을 클릭하면 해당 좌표에 해당하는 색상값을 다음과 같이
//메시지 상자에 출력하도록 DrawPoints 예제를 수정하시오
void CChildView::OnPaint()
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
for (int x = 0; x < 256; x++)
for (int y = 0; y < 256; y++)
dc.SetPixelV(x, y, RGB(x, y, 0));
// 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.
}
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CClientDC dc(this);
COLORREF color = dc.GetPixel(point);
CString str;
str.Format(_T("R:%d, G:%d, B:%d"), GetRValue(color), GetGValue(color), GetBValue(color));
MessageBox(str, _T("DrawPoints"), NULL);
//CWnd::OnLButtonDown(nFlags, point);
}
[4-7]
void CChildView::OnPaint()
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
//클라이언트 영역의 좌표를 얻는다
CRect rect;
GetClientRect(&rect);
//수평선과 수직선을 그린다
dc.MoveTo(0, rect.bottom / 2);
dc.LineTo(rect.right, rect.bottom / 2);
dc.MoveTo(rect.right / 2, 0);
dc.LineTo(rect.right / 2, rect.bottom);
int centerX = rect.Width() / 2, centerY = rect.Height() / 2; //원점 재설정
CArray<POINT, POINT&> arr;
double PI = 3.14159265358979323846;
//마름모꼴을 그린다
for (int i = -centerX; i <= centerX; i++)
{
POINT coord;
coord.x = i + centerX; //x축의 원점이 centerX이므로
coord.y = centerY - (int)(sin(i*PI / 180.0)*centerY); //y좌표계 또한 반대
arr.Add(coord);
}
dc.Polyline(arr.GetData(), arr.GetSize());
// 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.
}
[4-8]
//DrawTexts 예제에서 서체가 각각 첫번째 문장은 굴림, 두번째 문장은 궁서
//세번째 문장은 바탕으로 출력되도록 예제를 수정하시오
void CChildView::OnPaint()
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
CRect rect;
GetClientRect(&rect);
dc.SetTextColor(RGB(255, 0, 0)); //글자를 빨간색으로 설정
dc.SetBkColor(RGB(255, 255, 0)); //배경을 노란색으로 설정
CFont font1, font2, font3;
font1.CreatePointFont(400, _T("굴림"));
dc.SelectObject(&font1);
dc.DrawText(CString(_T("DrawText 함수를 연습합니다. [1]")), &rect, 0);
font2.CreatePointFont(400, _T("궁서"));
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.CreatePointFont(400, _T("바탕"));
dc.SelectObject(&font3);
dc.TextOutW(rect.right / 2, 3 * rect.bottom / 4, CString(_T("TextOut 함수를 연습합니다.")));
// 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.
}
개발환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
'MFC > 윈도우 프로그래밍' 카테고리의 다른 글
MFC 윈도우 프로그래밍 4장 심화문제 (0) | 2018.03.26 |
---|---|
MFC 윈도우 프로그래밍 4장 연습문제(9~16) (3) | 2018.03.25 |
MFC 윈도우 프로그래밍 3장 심화문제 (4) | 2018.03.21 |
MFC 윈도우 프로그래밍 3장 연습문제(9~16) (0) | 2018.03.18 |
MFC 윈도우 프로그래밍 3장 연습문제(1~8) (0) | 2018.03.18 |