티스토리 뷰

과제내용

1. 실습형 과제1 (35점) 교재 2장 SDI 프로젝트에서 다음 조건을 모두 만족하도록 수정한다. (1) 두 번째 차일드 윈도우를 삭제하고 그 자리에 [이름]버튼을 만들고, 버튼을 클릭하 면 메시지 박스에는 본인의 이름‘ 홍길동’이 나타나도록 수정한다. 과제물은 SDIView.cpp 파일과 결과 윈도우를 캡쳐하여 제출한다(그림1 참조) .

2. 실습형 과제 (35점) 교재 5장 폼뷰 프로젝트에서 고객의 ‘학번’을 입력하는 [학번] 항목을 추가한다. 즉, 왼편 창에서 [개수] 아래에 Edit 컨트롤을 추가하고 컨트롤이름을 [학번]으로 한다. [주 문완료] 버튼을 누르면 오른편 Edit 컨트롤의 맨 마지막에 입력한 ‘학번’ 이 출력되도록 한다. 과제물은 shoppingView.cpp 파일과 결과 윈도우를 캡쳐하여 제출한다(그림2 참 조) .

3. 제출방법: 1) 과제물은 하나의 아래한글 또는 MS워드로 작성한다. 즉, 과제물 파일은 1개이다. (단, 파일 용량은 5MB 이하로 제한함) 2) 문제1번은 SDIView.cpp 파일을 문제2번은 shoppingView.cpp 파일을 복사하여 과제 물 작성 파일에 붙여넣기 한다. 3) 윈도우화면은 캡쳐하여 붙여넣기 하며 그림1과 그림2를 참조한다. 4) 프로젝트는 교수 홈페이지 (http://cs.knou.ac.kr/~khkim/) -> Visual C++프로그래밍 -> 학습정보 게시판 -> 41번에 올려져 있는 프로젝트를 다운로드하여 수정하면 된다


1. SDIView

(1) 캡쳐화면

(2) SDIView.cpp

// SDIView.cpp: CSDIView 클래스의 구현
#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS는 미리 보기, 축소판 그림 및 검색 필터 처리기를 구현하는 ATL 프로젝트에서 정의할 수 있으며

// 해당 프로젝트와 문서 코드를 공유하도록 해 줍니다.
#ifndef SHARED_HANDLERS
#include "SDI.h"
#endif

#include "SDIDoc.h"
#include "SDIView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define  ID_DECREASE_BUTTON            3000
#define  ID_INCREASE_BUTTON             3100
#define ID_NAME_BUTTON 3400
#define  ID_LISTBOX                 3200
#define    ID_PROGBAR           3300

// CSDIView
IMPLEMENT_DYNCREATE(CSDIView, CView)

BEGIN_MESSAGE_MAP(CSDIView, CView)
             // 표준 인쇄 명령입니다.
             ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
             ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
             ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
             ON_WM_CREATE()
             ON_COMMAND(ID_NAME_BUTTON, OnNameButton)
             ON_COMMAND(ID_DECREASE_BUTTON, OnDecreaseButton)
             ON_COMMAND(ID_INCREASE_BUTTON, OnIncreaseButton)
END_MESSAGE_MAP()

// CSDIView 생성/소멸
CSDIView::CSDIView() noexcept

{
             // TODO: 여기에 생성 코드를 추가합니다.
}

CSDIView::~CSDIView()
{}

BOOL CSDIView::PreCreateWindow(CREATESTRUCT& cs)
{
             // TODO: CREATESTRUCT cs를 수정하여 여기에서
             //  Window 클래스 또는 스타일을 수정합니다.
             return CView::PreCreateWindow(cs);
}

// CSDIView 그리기
void CSDIView::OnDraw(CDC* /*pDC*/)
{
             CSDIDoc* pDoc = GetDocument();
             ASSERT_VALID(pDoc);
             if (!pDoc)
                           return;
             // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
}
// CSDIView 인쇄
BOOL CSDIView::OnPreparePrinting(CPrintInfo* pInfo)
{
             // 기본적인 준비
             return DoPreparePrinting(pInfo);
}

void CSDIView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
             // TODO: 인쇄하기 전에 추가 초기화 작업을 추가합니다.
}

void CSDIView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
             // TODO: 인쇄 후 정리 작업을 추가합니다.
}

// CSDIView 진단
#ifdef _DEBUG
void CSDIView::AssertValid() const
{
             CView::AssertValid();
}

void CSDIView::Dump(CDumpContext& dc) const
{
             CView::Dump(dc);
}

CSDIDoc* CSDIView::GetDocument() const // 디버그되지 않은 버전은 인라인으로 지정됩니다.
{
             ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSDIDoc)));
             return (CSDIDoc*)m_pDocument;
}

#endif //_DEBUG
// CSDIView 메시지 처리기
int CSDIView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
             if (CView::OnCreate(lpCreateStruct) == -1)
                           return -1;
             // TODO:  여기에 특수화된 작성 코드를 추가합니다.
    m_ProgressBar.Create(WS_DLGFRAME | WS_VISIBLE, CRect(50, 230, 300, 270), this, ID_PROGBAR);
             m_ProgressBar.SetRange(0, 9);
             m_ProgressBar.SetPos(1);
             m_Wnd01.Create(AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW),
                           _T("첫번째 차일드윈도우"),
                           WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CHILD,
                           CRect(50,50,300,200),
                           this,
                           1010);

             ASSERT(m_Wnd01.m_hWnd != NULL);
             /*m_Wnd02.Create(AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW),
                           _T("두번째 차일드윈도우"),
                           WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CHILD,
                           CRect(350, 50, 600, 250),
                           this,
                           1020);*/

             m_Name_Btn.Create(_T("이름"), WS_VISIBLE, CRect(400, 100, 600, 130),
             m_Increase_Btn.Create(_T("증가"), WS_VISIBLE, CRect(400, 300, 600, 330),
                                     this, ID_INCREASE_BUTTON);
            m_Decrease_Btn.Create(_T("감소"), WS_VISIBLE, CRect(400, 350, 600, 380),
                                      this, ID_DECREASE_BUTTON);
             m_ListBox.Create(WS_DLGFRAME | WS_VISIBLE, CRect(50, 350, 300, 600),
                                                                                             this, ID_LISTBOX);
             m_ListBox.AddString(_T("윈도우 프로그래밍!"));
             return 0;
}

void CSDIView::OnDecreaseButton()
{
             int count = m_ListBox.GetCount();
             if (count > 0)
             {
                           m_ListBox.DeleteString(count - 1);
                           m_ProgressBar.SetPos(count - 1);
             }
             else
             {
                           AfxMessageBox(_T("지울 아이템이 없습니다"));
             }
}

void CSDIView::OnIncreaseButton()
{
             int count = m_ListBox.GetCount();
             if (count < 10)
             {
                           m_ListBox.AddString(_T("윈도우 프로그래밍!"));
                           m_ProgressBar.SetPos(count + 1);
             }
             else
             {
                           AfxMessageBox(_T("더 이상 추가할 수 없습니다"));
             }
}
void CSDIView::OnNameButton()
{
             MessageBox(L"이름", L"SDI");
}

 

 

2. shoppingView

(1) 캡쳐화면

(2) shopingView.cpp

// ShoppingView.cpp : CShoppingView 클래스의 구현
//
#include "stdafx.h"
#include "Shopping.h"
#include "ShoppingDoc.h"
#include "ShoppingView.h"
//setlocale함수를 쓰고자 아래 헤더 파일사용
#include <locale.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CShoppingView
IMPLEMENT_DYNCREATE(CShoppingView, CFormView)

BEGIN_MESSAGE_MAP(CShoppingView, CFormView)
             ON_BN_CLICKED(IDC_BUTTON_DONE, &CShoppingView::OnBnClickedButtonDone)
             ON_COMMAND(ID_FILE_SAVE, &CShoppingView::OnFileSave)
             ON_COMMAND(ID_FILE_OPEN, &CShoppingView::OnFileOpen)
END_MESSAGE_MAP()
// CShoppingView 생성/소멸
CShoppingView::CShoppingView()
             : CFormView(CShoppingView::IDD)
             , m_Product(_T(""))
             , m_ProductCD(_T(""))
             , m_Price(0)
             , m_Cnt(0)
             , m_Class_Num(_T("학번"))
{
             // TODO: 여기에 생성 코드를 추가합니다.
}
CShoppingView::~CShoppingView()
{
}

void CShoppingView::DoDataExchange(CDataExchange* pDX)
{
             CFormView::DoDataExchange(pDX);
             DDX_Control(pDX, IDC_RESULT, m_Result);
             DDX_Text(pDX, IDC_PRODUCT, m_Product);
             DDX_Text(pDX, IDC_PRODUCT_CD, m_ProductCD);
             DDX_Text(pDX, IDC_PRICE, m_Price);
             DDX_Text(pDX, IDC_CNT, m_Cnt);
             DDX_Text(pDX, IDC_CLASS_NUM, m_Class_Num);
             DDX_Control(pDX, IDC_SPIN1, m_Spin1);
}

BOOL CShoppingView::PreCreateWindow(CREATESTRUCT& cs)
{
             // TODO: CREATESTRUCT cs를 수정하여 여기에서
             //  Window 클래스 또는 스타일을 수정합니다.
             return CFormView::PreCreateWindow(cs);
}

void CShoppingView::OnInitialUpdate()
{
             CFormView::OnInitialUpdate();
             GetParentFrame()->RecalcLayout();
             ResizeParentToFit();
             m_Result.SetWindowText(L"데이타 없음");
             m_Spin1.SetRange(1, 100);
}


// CShoppingView 진단
#ifdef _DEBUG
void CShoppingView::AssertValid() const
{
             CFormView::AssertValid();
}

void CShoppingView::Dump(CDumpContext& dc) const
{
             CFormView::Dump(dc);
}

CShoppingDoc* CShoppingView::GetDocument() const // 디버그되지 않은 버전은 인라인으로 지정됩니다.
{
             ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CShoppingDoc)));
             return (CShoppingDoc*)m_pDocument;
}
#endif //_DEBUG

// CShoppingView 메시지 처리기
void CShoppingView::OnBnClickedButtonDone()
{
             // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
             UpdateData(TRUE);

             if (m_Product =="")
             {
                           MessageBox(_T("상품명을 입력하세요"), _T("상품명 에러"),  MB_ICONERROR | MB_OK);                        
                           return;
             }else{
             str += L" 상품명 : ";
             str += m_Product;
             }
             str += L" 상품코드 : ";
             str += m_ProductCD;
 
             CString temp = _T("");
             temp.Format(_T(" 단가 %d "), m_Price);
             str += temp;
 
             temp.Format(_T("갯수 %d 합계 %d \r\n"), m_Cnt, m_Price * m_Cnt);
             str += temp;      
 
             str += L" 학번: ";
             str += m_Class_Num;
 
    m_Result.SetWindowText(str);
             UpdateData(FALSE);
}

/*******************************************************************************

Locale 이란?

사용자의 언어, 지역, 특별한 특징(사용자들의 UI에서 선호하고 싶은 사항)을 정의해주는 매개변수의 집합이다.

주로 Locale은 적어도 하나의 언어 식별자와 국가 식별자로 구성되어있다.

이를 잘 지정해 주지 못하면 글자가 깨지거나 출력되지 않는 경우가 발생한다.

이런 경우에는 다음과 같은 코드를 넣어줍니다.

setlocale(LC_ALL, "");

 

첫번째 인자 : 표시형식의 설정입니다. 인자로 주어진 부분에 영향을 미친다.

LC_ALL  //모든 Locale

LC_COLLATE // 유니코드 문자열을 비교, 변형하는 함수

LC_CTYPE // 문자를 처리하는 함수, 멀티바이트/유니코드 함수

LC_MONETARY // 통화

LC_NUMERIC // 숫자 형식

LC_TIME // 시간형식

 

두번째 인자 : Locale 지정자입니다. 어떤 국가의 규칙을 따를지 지정한다.

Ex) "Korean", null

null값을 지정해 주면 현재 시스템의 기본값을 따라간다.

setlocale 함수를 쓰고자 #include <locale.h> 한다

 

CFileDialog::GetPathName

대화 상자에 입력 한 파일의 전체 경로 검색 하려면 이 함수를 호출 한다.

파일 경로가 제목 파일의 전체 디렉터리 경로 포함 된다.

예를 들어, "C:\FILES\TEXT.DAT"이면 파일은 C:\FILES\TEXT.DAT 이다.

GetPathName 를 반환 한다

 

****************************************************************************/

void CShoppingView::OnFileSave()

{

             // TODO: 여기에 명령 처리기 코드를 추가합니다.

    CStdioFile file;

    CString lineStr;

             //유니코드해결에 필요한 코딩

             char* pLocale = setlocale(LC_ALL, "Korean");

 

    lineStr = str;

    CFileDialog fDlg(FALSE, _T("txt"),0, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,

                                                          _T("텍스트 화일(.txt)|.txt"));

 

   if (fDlg.DoModal() ==IDOK)

   {

              //CString nfilename =fDlg.GetFileName();

              CString nfilename = fDlg.GetPathName(); //파일경로   

              file.Open(nfilename , CFile::modeCreate|CFile::modeWrite|CFile::typeText);

              file.WriteString(lineStr);

              file.Close();

   }  

}

 

void CShoppingView::OnFileOpen()

{

             // TODO: 여기에 명령 처리기 코드를 추가합니다.

             CShoppingDoc* pDoc= GetDocument();

             CStdioFile file;

    CFileDialog fDlg(TRUE, _T("txt"),0, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,

                                                                   _T("텍스트 화일(.txt)|.txt|모든 화일(.)|*.*||"));

            

             //유니코드해결에 필요한 코딩

             char* pLocale = setlocale(LC_ALL, "Korean");

 

    if (fDlg.DoModal() ==IDOK)

   {

              str = _T("");

              CString strFileData;

              //file.Open(fDlg.GetFileName(), CFile::modeCreate|CFile::modeNoTruncate|

             //                                                                                                       CFile::modeRead|CFile::typeText);

            

              file.Open(fDlg.GetPathName(), CFile::modeCreate|CFile::modeNoTruncate|

                                                                                                         CFile::modeRead|CFile::typeText);
              //불러온 화일명을 윈도우 타이틀로 보여줌
     pDoc->SetTitle(fDlg.GetFileTitle());
              while(file.ReadString(strFileData))
              {
                           str = str +strFileData + _T("\n");
                           m_Result.SetWindowText(str);
              }
     file.Close();

   }

}
반응형
댓글