Software/Programming2012. 8. 10. 00:28

Visual C++ 프로그램

    -. 어렵게만 느껴졌던 도큐먼트 뷰구조

    -. 비주얼C++프로그램 쉽게 분석하기

    -. 도큐먼트 뷰 구조 자세히 공부하기

    -. 도대체 애플리케이션 프레임워크가 뭡니까?


  가. 어렵게만 느껴졌던 도큐먼트 뷰구조


    1) 도큐먼트 뷰구조

      ? theApp : 애플리케이션의 수행과 관련된 일

      ② CMainFrame클래스로 동적할당한 객체 : 프레임윈도우와 관련된일

      ③ 도큐먼트 객체 : 파일입출력만 전문적으로 담당

      ④ 뷰 객체 : 화면 출력만 전문적으로 담당


    2) 애플리케이션 유형과 애플리케이션 위저드

      ? 프레임윈도우 객체: 메뉴, 툴바, 상태바

      ② 뷰윈도우 : 프레임윈도우가 둘러싸는 공간. 즉 클라이언트 영역

      ③ 윈도우를 갖지 않는 객체 : theApp(애플리케이션객체)와 도큐먼트 객체

      ④ 도큐먼트와 뷰가 필요없는 경우 =>대화상자(계산기, 전화걸기등)

      ⑤ 도큐먼트가 하나인 경우 =>SDI애플리케이션(워드패트)

      ⑤ 도큐먼트가 여러개인 경우 =>MDI애플리케이션(MS워드)


  나. 비주얼C++프로그램 쉽게 분석하기

     

  // 윈도우 생성

  hwnd = CreateWindow(szAppName)

  "Hello2",

  WS_OVERLAPPENDWINDOW,

  CW_USEDFAULT,

  CW_USEDFAULT,     

  CW_USEDFAULT, 

  CW_USEDFAULT,

  NULL,

  NULL,

  hInstance,

  NULL);

  





      ① WS_OVERLAPPENDWINDOW :두꺼운 프레임과 최소/최대 상자,

                                      그리고 시스템 메뉴가 있는 윈도우 형식

      ② WS_OVERLAPPEND : 윈도우 크기 조절할 수 없다

      ③ ShowWIndow : API프로그램에서 윈도우 표시 최소화/ 최대화


  다. 도큐먼트 뷰구조 자세히 공부하기

    1) 메인프레임 윈도우 객체가 할 수 있는 일들

      ? 윈도우 위치와 크기 지정하기

         - PreCreateWindow함수

            :메인프레임윈도우 객체가 생성된 후 윈도우가 생성되기 바로전에 실행되는 함수      

 // 화면 가운데

        cs.cx=::GetSystemMetrics(SM_CXSCREEN) /2;

        cs.cy=::GetSystemMetrics(SM_CYSCREEN) /2;

        cs.x=((cs.cx*2)-cs.cx)/2;

        cs.y=((cs.cy*2)-cs.cy)/2;

       - ActivateFrame(int nCmdShow)

           : 최대화, 최소화 지정

 cs.style = WS_OVERLAPPED 

          | WS_CAPTION 

          | WS_SYSMENU            // 우위  종료

          | WS_THICKFRAME        // 두께

          | WS_MINIMIZEBOX        // - 박스

          | WS_MAXIMIZEBOX;       // 확대 박스


      ② 오른쪽 마우스 클릭시 종료

void CMainFrame::OnContextMenu(CWnd* pWnd, CPoint point)

{

        // TODO: Add your message handler code here

        PostQuitMessage(0);

}


      ③ 툴바 상태바 제어하기: 툴바 왼쪽에 붙이기

 DockControlBar(&m_wndToolBar, AFX_IDW_DOCKBAR_LEFT);


    2) 애플리케이션객체가 할 수 있는 일들(즉 theApp)

      ① 윈도우 클래스정의, 생성, 표시 그리고 메시지루프

           - InitApplication멤버함수

           - InitInstance멤버함수

           - Run멤버함수

           - ExitInstance멤버함수: 프로그램 종료

           중요: 멤버함수가 가상함수일 경우 상속받은 함수가 아닌 해당클래스에서

                 정의됨 함수가 호출됨.

         

      ② 도큐먼트객체와 메인프레임윈도우객체, 뷰객체 생성

        // Dispatch commands specified on the command line

        if (!ProcessShellCommand(cmdInfo))

                return FALSE;

        OnFileNew();

        pDocTemplate->OpenDocumentFile(NULL);

          - 3가지 모두 동일한 결과

          - OpenDocumentFile를 호출해도 됨(우선 도큐먼트객체 정의)

            

      ③ 도큐먼트 템플리트객체

        CSingleDocTemplate* pDocTemplate;

        pDocTemplate = new CSingleDocTemplate(

                IDR_MAINFRAME,

                RUNTIME_CLASS(CMyDoc),

                RUNTIME_CLASS(CMainFrame),     // SDI frame window

                RUNTIME_CLASS(CMyView));

        AddDocTemplate(pDocTemplate);

          - CMyDoc클래스, CMainFrame클래스, CMyView클래스이용

            세 개의 객체들 동적으로 할당한 후 객체들을 적절히 연결.

      ④ 윈도우 최대화/최소화

        m_pMainWnd->ShowWindow(SW_SHOW);

          - 메인프레임윈도우 객체의 AcrivateFrame에서 구현

          - InitInstance멤버함수에서도 수행함.


    3) 뷰 객체가 할 수 있는 일들

      ① 그리기

          - 메인프레임윈도우의 클라이언트영역 뷰가 덮어 버림

          - 예제로 왼쪽마우스로 문자열 출력시 뷰클래스멤버로 정의해야함.

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)

{

        CClientDC dc(this);

        dc.TextOut(0,0, "왼쪽 마우스 버튼 누름");

        CView::OnLButtonDown(nFlags, point);

}

         (문제) 화면크기를 변경하면 사라짐

void CMyView::OnPaint()

{

        CPaintDC dc(this); // device context for painting

        dc.TextOut(0,0,"안녕 페이트");

}

         (문제) 인쇄미리보기 안나타남


void CMyView::OnDraw(CDC* pDC)

{

        CMyDoc* pDoc = GetDocument();

        ASSERT_VALID(pDoc);

        pDC->TextOut(0,0,"안녕 페이트");

}

         (문제) 미리보기에는 나타나는 데 화면과 불일치

               => 클래스위저드로 OnPaint멤버함수 삭제


      ② 도큐먼트주소 알아내기

         - 뷰가 도큐먼트에 있는 데이터를 출력 하기위해서 도큐먼트 주소를 알아야 함.

           (즉, GetDocument()멤버함수 호출

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)

{

        CString szStr;

        szStr.Format("도큐먼트객체번지: %p.", GetDocument());

        MessageBox(szStr);

        

        CView::OnLButtonDown(nFlags, point);

}


    3) 도큐먼트 객체가 할 수 있는 일들

      ① 직렬화

         - 도큐먼트존재: 동적으로 할당되어 메모리 어딘가에존재함

         - 도큐먼트위치: 프레임윈도우클라이언트영역, 뷰윈도우 바로 아래

         - 도큐먼트객체: 파일로 저장하고 읽어오기

         - 직렬화(serialization) : 도큐먼트객체 멤버변수에 저장되어 있는 자료를

                                 일렬로 저장하거나 읽어오기(즉 파일입출력을 말함)

// 도큐먼트 멤버변수 정의

   CString m_szData;

// 도큐먼트초기화

BOOL CMyDoc::OnNewDocument()

{

   ...

   m_szData = "";

   return true;

}

// 직렬화 수행

void CMyDoc::Serialize(CArchive& ar)

{

        if (ar.IsStoring())

        {

                // 파일 저장하기

                ar << m_szData;

        }

        else

        {

                // 파일 불러오기

                ar >> m_szData;

        }

}

// 뷰화면에 표현

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)

{       

     CString szCoord;

     szCoord.Format("마우스를 좌표:(%d, %d)", point.x, point.y);

        GetDocument()->m_szData=szCoord;

        Invalidate();   // 강제로 WM_PAINT메시지 발생  

        CView::OnLButtonDown(nFlags, point);

}

// 저장자료로 표시

void CMyView::OnDraw(CDC* pDC)

{

        CMyDoc* pDoc = GetDocument();

        ASSERT_VALID(pDoc);

        pDC->TextOut(0,0,GetDocument()->m_szData);

}


  라. 도대체 애플리케이션 프레임워크가 뭡니까?

    1) 도큐먼트 뷰 구조 및 애플리케이션 프레임워크

      ① 정의

         - 애플리케이션 객체(theApp)와 메인프레임윈도우 객체, 도큐먼트객체와

           뷰객체로 이루어진 애플리케이션을 말함

      ② 도큐먼트 뷰구조 목적

         - 역할 분담을 위함, 자료를 유지관리 역할을 하는 도큐먼트객체와

            자료를 표시하는 뷰객체를 둠

      ③ 각각의 객체가 특정 작업만을 수행=>모듈성 강화


    2) 애플리케이션프레임워크 안

      ① 디버깅 : Debug-Step Into , F11키누름

                  F10: 한줄씩 통째로

                  F11: 함수가 있을 경우 안으로 들어감

         - 애플리케이션 프레임워크 코드

             :tWinMain함수를 시작으로 일정한 순서대로 실행

         - 애플리케이셔 프레임워크 추적

             :F10키와 F11키를 번갈아 눌러서 처음부터 추적

      ② CTRL+F5: 운영체제는 tWinMain 함수를 가장 먼저 실행

      ③ AfxWinMain함수

         - 이함수 직접작성한 WinMain함수에 해당

         - theApp객체의 InitApplication멤버함수호출(정의,등록,생성,실행)


      ④ CAfxApp theApp

         - 반드시 하나만 존재 변경도 안됩니다

         - 두 개 입력시 에러(Debug Assertion Failed)


      ④ InitAppication 멤버함수

         - CAfxApp의 멤버로 정의하며 CWinApp로부터 상속

         - theApp의 객체는 두 개의 InitAppication멤버함수를 가지는데

           CAfxApp::InitAppication가 실행 됩니다.

           (이유 가상함수이기때문, 가상함수가 아니면 상속받은 멤버함수가 실행)

<변영철 비주얼C++ 참조>

Posted by 십자성군