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++ 참조>
'Software > Programming' 카테고리의 다른 글
MFC 사용자 정의 뷰를 가지는 차일드 윈도우 만들기 (0) | 2012.08.10 |
---|---|
MFC의 흐름 (0) | 2012.08.10 |
CFileDialog (0) | 2012.08.10 |
MFC에서 유니코드 관련해서 문제가 생겼다. (1) | 2012.08.09 |
[MFC] OnFileOpen 함수 재정의 해서 사용하기. (0) | 2012.08.09 |