MFC/윈도우 프로그래밍

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

꾸준함. 2018. 4. 7. 02:59

윈도우 프로그래밍 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


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

반응형