윈도우 프로그래밍 Visual C++ 2010 MFC Programming(김선우, 신화서 저) 6장 연습문제입니다.
저번에 이어 나머지 연습문제를 풀어봤습니다.
[6-9]
//ColorSelect 예제에서 툴바를 왼쪽 테두리에 세로로 배치하고,
//항상 윈도우 왼쪽에 위치하도록 예제를 수정하시오
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// 프레임의 클라이언트 영역을 차지하는 뷰를 만듭니다.
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("뷰 창을 만들지 못했습니다.\n");
return -1;
}
//여기 수정!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//CBRS_TOP->CBRS_LEFT
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_LEFT | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("도구 모음을 만들지 못했습니다.\n");
return -1; // 만들지 못했습니다.
}
if (!m_wndStatusBar.Create(this))
{
TRACE0("상태 표시줄을 만들지 못했습니다.\n");
return -1; // 만들지 못했습니다.
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
// TODO: 도구 모음을 도킹할 수 없게 하려면 이 세 줄을 삭제하십시오.
//여기도 수정!!!!!!!!!!!!!!!!!!!!!!!!!!!
//CBRS_ALIGN_ANY->CBRS_ALIGN_LEFT
m_wndToolBar.EnableDocking(CBRS_ALIGN_LEFT);
EnableDocking(CBRS_ALIGN_LEFT);
DockControlBar(&m_wndToolBar);
return 0;
}
[6-10]
//SystemMenu 예제에서 시스템 메뉴의 [닫기] 메뉴를 활성화하고
//시스템 메뉴에 [닫기] 메뉴만 나타나도록 에제를 수정하시오
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// 프레임의 클라이언트 영역을 차지하는 뷰를 만듭니다.
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("뷰 창을 만들지 못했습니다.\n");
return -1;
}
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("도구 모음을 만들지 못했습니다.\n");
return -1; // 만들지 못했습니다.
}
if (!m_wndStatusBar.Create(this))
{
TRACE0("상태 표시줄을 만들지 못했습니다.\n");
return -1; // 만들지 못했습니다.
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
// TODO: 도구 모음을 도킹할 수 없게 하려면 이 세 줄을 삭제하십시오.
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
CMenu *pSysMenu = GetSystemMenu(FALSE);
//닫기 메뉴 항목 비활성화
pSysMenu->EnableMenuItem(SC_CLOSE, MF_GRAYED);
//분리자 항목 추가
pSysMenu->AppendMenuW(MF_SEPARATOR);
//ID가 16인 메뉴 항목 추가
pSysMenu->AppendMenuW(MF_STRING, 16, _T("이 프로그램은..."));
//삭제
pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_MOVE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
pSysMenu->DeleteMenu(MF_SEPARATOR, MF_BYCOMMAND);
return 0;
}
[6-11]
//Alt+Enter 키를 누르면 윈도우가 최대화되도록 Simple2 예제를 수정하시오
void CMainFrame::OnMaximize()
{
// TODO: 여기에 명령 처리기 코드를 추가합니다.
ShowWindow(SW_MAXIMIZE);
}
[6-12]
//Simple2 예제에 윈도우가 최소호하되는 툴바 버튼을 추가하시오
void CMainFrame::OnMinimize()
{
// TODO: 여기에 명령 처리기 코드를 추가합니다.
ShowWindow(SW_MINIMIZE);
}
[6-13]
//Simple2 예제에서 상태바의 ID_SEPARATOR 부분에 마우스 좌표를 출력하도록 한다
void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CString str;
str.Format(_T("마우스 좌표 (%d,%d)"), point.x, point.y);
CMainFrame *pMainFrame = (CMainFrame*)AfxGetMainWnd();
pMainFrame->m_wndStatusBar.SetPaneText(0, str);
CWnd::OnMouseMove(nFlags, point);
}
[6-14]
//순서를 바꿔준다
static UINT indicators[] =
{
ID_INDICATOR_POS,
ID_SEPARATOR, // 상태 줄 표시기
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
//ShowCursorPos 예제에서 상태바의 ID_SEPARATOR 부분이 상태바에서 두 번째에 나타나도록
//순서를 변경하고 마우스 좌표는 그대로 ID_INDICATOR_POS 부분에 출력되도록 수정하시오
void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CString str;
str.Format(_T("(%4d,%4d)"), point.x, point.y);
CMainFrame *pMainFrame = (CMainFrame*)AfxGetMainWnd();
pMainFrame->m_wndStatusBar.SetPaneText(0, str);
CWnd::OnMouseMove(nFlags, point);
}
[6-15]
static UINT indicators[] =
{
ID_SEPARATOR, // 상태 줄 표시기
ID_INDICATOR_POS,
ID_INDICATOR_POS2,
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
//상태바의 ID_INDICATOR_POS 뒤에 ID_INDICATOR_POS2 추갛한다
//ID_INDICATOR_POS에는 클라이언트 영역 기준의 마우스 좌표를 출력하고
//ID_INDICATOR_POS2에는 스크린 영역 기준의 마우스 좌표를 출력한다
void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CString str;
str.Format(_T("%4d,%4d"), point.x, point.y);
CMainFrame *pMainFrame = (CMainFrame*)AfxGetMainWnd();
pMainFrame->m_wndStatusBar.SetPaneText(1, str);
ClientToScreen(&point);
str.Format(_T("(%4d,%4d)"), point.x, point.y);
pMainFrame->m_wndStatusBar.SetPaneText(2, str);
CWnd::OnMouseMove(nFlags, point);
}
[6-16]
// ChildView.h: CChildView 클래스의 인터페이스
//
#pragma once
// CChildView 창
class CChildView : public CWnd
{
// 생성입니다.
public:
CChildView();
// 특성입니다.
public:
BOOL m_bDrawMode; //그리기 모드
int m_x1, m_y1, m_x2, m_y2;
// 작업입니다.
public:
// 재정의입니다.
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
// 구현입니다.
public:
virtual ~CChildView();
// 생성된 메시지 맵 함수
protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
};
// ChildView.cpp: CChildView 클래스의 구현
//
#include "stdafx.h"
#include "연습문제 6-16.h"
#include "ChildView.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CChildView
CChildView::CChildView()
{
m_bDrawMode = FALSE;
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
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;
}
void CChildView::OnPaint()
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
// 그리기 메시지에 대해서는 CWnd::OnPaint()를 호출하지 마십시오.
}
void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CString str;
CMainFrame *pMainFrame = (CMainFrame*)AfxGetMainWnd();
if (m_bDrawMode)
{
//전에 작성한 예제에 있는 코드이므로 따로 주석 X
CClientDC dc(this);
dc.SelectStockObject(LTGRAY_BRUSH);
dc.SetROP2(R2_NOTXORPEN);
dc.Rectangle(m_x1, m_y1, m_x2, m_y2);
m_x2 = point.x;
m_y2 = point.y;
dc.SetROP2(R2_NOTXORPEN);
dc.Rectangle(m_x1, m_y1, m_x2, m_y2);
CRect rect(m_x1, m_y1, m_x2, m_y2);
str.Format(_T("(%4d,%4d)"), rect.Width(), rect.Height());
pMainFrame->m_wndStatusBar.SetPaneText(1, str);
}
else
{
str.Format(_T("(%4d,%4d)"), point.x, point.y);
pMainFrame->m_wndStatusBar.SetPaneText(1, str);
}
CWnd::OnMouseMove(nFlags, point);
}
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
SetCapture();
m_bDrawMode = TRUE;
m_x1 = m_x2 = point.x;
m_y1 = m_y2 = point.y;
CWnd::OnLButtonDown(nFlags, point);
}
void CChildView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
CClientDC dc(this);
m_x2 = point.x;
m_y2 = point.y;
dc.SelectStockObject(LTGRAY_BRUSH);
dc.Rectangle(m_x1, m_y1, m_x2, m_y2);
m_bDrawMode = FALSE;
::ReleaseCapture();
CWnd::OnLButtonUp(nFlags, point);
}
개발환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
'MFC > 윈도우 프로그래밍' 카테고리의 다른 글
MFC 윈도우 프로그래밍 7장 연습문제(9~16) (0) | 2018.04.30 |
---|---|
MFC 윈도우 프로그래밍 7장 연습문제(1~8) (0) | 2018.04.29 |
MFC 윈도우 프로그래밍 6장 연습문제(1~8) (0) | 2018.04.06 |
MFC 윈도우 프로그래밍 5장 심화문제 (0) | 2018.04.01 |
MFC 윈도우 프로그래밍 5장 연습문제(9~16) (0) | 2018.03.30 |