Microsoft PowerPoint - MFC-교재.ppt

Similar documents
untitled

5장 MFC기반 다지기

Microsoft PowerPoint - hci2-lecture10.ppt

<4D F736F F F696E74202D203031C0E520C0A9B5B5BFEC20C7C1B7CEB1D7B7A1B9D620B1E2C3CA5FBFB5B3B2C0CCB0F8B4EB205BC8A3C8AF20B8F0B5E55D>

4S 1차년도 평가 발표자료

Visual C++의 개요

Chapter 1. MFC 시작하기

윈도우시스템프로그래밍

MFC 프로그래밍

Microsoft PowerPoint - hci2-lecture5-messagemap.ppt

<4D F736F F F696E74202D203036C0E520BBE7BFEBC0DA20C0CEC5CDC6E4C0CCBDBA205BC8A3C8AF20B8F0B5E55D>

Microsoft PowerPoint - hci2-lecture3.ppt

Microsoft PowerPoint - hci2-lecture3.ppt

Microsoft PowerPoint - hci2-lecture7.ppt

MFC 프로그래밍

윈도우시스템프로그래밍

08장 윈도우에서의 그리기

Microsoft PowerPoint - 04windows.ppt

Microsoft PowerPoint - CPP_chap3

슬라이드 1

그래픽 프로그래밍

강의10

歯Lecture2.PDF

Programming hwp

<33372DC0A9B5B5BFECC7C1B7CEB1D7B7A1B9D62E687770>

1장 윈도우 프로그래밍 들어가기

Microsoft PowerPoint - hci2-lecture6.ppt

Microsoft PowerPoint - hci2-lecture6.ppt

윈도우시스템프로그래밍

Microsoft PowerPoint - hci2-lecture1.ppt

Microsoft Word - hci07-final-answer.doc

C# Programming Guide - Types

Microsoft PowerPoint - hci2-lecture1.ppt

<4D F736F F F696E74202D203032C0E520C0AFC6BFB8AEC6BC20C5ACB7A1BDBABFCD20C1FDC7D520C5ACB7A1BDBA5FBFB5B3B2C0CCB0F8B4EB205BC8A3C8AF20B8F0B5E55D>

WISHBONE System-on-Chip Interconnection Architecture for Portable IP Cores

윈도우 프로그래밍의 개념

[제1강] 텍스트를 입력하세요

Dialog Box 실행파일을 Web에 포함시키는 방법

iii. Design Tab 을 Click 하여 WindowBuilder 가자동으로생성한 GUI 프로그래밍환경을확인한다.

Microsoft Word - hci08-final-answer.doc

설계란 무엇인가?

<B9CCB5F0BEEE20C1A4BAB8C3B3B8AE2E687770>

윈도우시스템프로그래밍

PowerPoint 프레젠테이션

<4D F736F F F696E74202D20C1A C0E520B5B5C5A5B8D5C6AE20C6C4C0CF20C0D4C3E2B7C220B9D720B4D9BEE7C7D120BAE420C5ACB7A1BDBA2E BC8A3C8AF20B8F0B5E55D>

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

Week3

Microsoft Word - FunctionCall

chap 5: Trees

API - Notification 메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어

PowerPoint Template

쉽게 풀어쓴 C 프로그래밍

쉽게 풀어쓴 C 프로그래밍

Something that can be seen, touched or otherwise sensed

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

Microsoft PowerPoint _파일입출력.ppt

04장 메시지 처리 유형

Lab 3. 실습문제 (Single linked list)_해답.hwp

PowerPoint Template

PowerPoint 프레젠테이션

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할

Microsoft PowerPoint - chap01-C언어개요.pptx

GDI 와 DC GDI (Graphics Device Iterface) 응용프로그램이하드웨어를제어할수있도록윈도우 OS 가제공하는모든기능 윈도우가출력장치에대한정보를스스로판단하고분석하여, 실제로사용할드라이버를불러옴 이를이용할경우, 하드웨어독립적인프로그래밍을할수있음 Widw

Programming hwp

1. 객체의생성과대입 int 형변수 : 선언과동시에초기화하는방법 (C++) int a = 3; int a(3); // 기본타입역시클래스와같이처리가능 객체의생성 ( 복습 ) class CPoint private : int x, y; public : CPoint(int a

4 장클래스와객체 클래스와객체 public과 private 구조체와클래스객체의생성과생성자객체의소멸과소멸자생성자와소멸자의호출순서디폴트생성자와디폴트소멸자멤버초기화멤버함수의외부정의멤버함수의인라인함수선언 C++ 프로그래밍입문

Microsoft PowerPoint - 09-CE-7-선과 도형

윈도우시스템프로그래밍

JAVA PROGRAMMING 실습 08.다형성

Design Issues

Microsoft PowerPoint - C++ 5 .pptx

PowerPoint Presentation

Chapter #01 Subject

Lab 4. 실습문제 (Circular singly linked list)_해답.hwp

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

Programming hwp

Microsoft PowerPoint - Chapter 6.ppt

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

gnu-lee-oop-kor-lec06-3-chap7

<4D F736F F F696E74202D20C1A63034B0AD202D20C7C1B7B9C0D3B8AEBDBAB3CABFCD20B9ABB9F6C6DBC0D4B7C2>

Analytics > Log & Crash Search > Unity ios SDK [Deprecated] Log & Crash Unity ios SDK. TOAST SDK. Log & Crash Unity SDK Log & Crash Search. Log & Cras

Microsoft PowerPoint - 09-CE-5-윈도우 핸들

슬라이드 1

thesis

DE1-SoC Board

UI TASK & KEY EVENT

No Slide Title

ISP and CodeVisionAVR C Compiler.hwp

Microsoft PowerPoint - 11주차.pptx

JVM 메모리구조

1

chapter4

슬라이드 1

MPLAB C18 C

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

C++ Programming

Microsoft PowerPoint - CPP_chap7_dialogbox(2)

Microsoft PowerPoint - CPP_chap6_interface(2)

The_IDA_Pro_Book

UI TASK & KEY EVENT

Transcription:

MFC MFC 기초와구조 1

차례 MFC 란무엇인가 Application Framework MFC 계층구조 MFC 구조 The Application Framework CWinApp Class CFrameWnd Class Documents and Views 객체간의통신 MFC 프로그래밍 Messages and Commands [2] MFC(Microsoft Foundation Class) 란무엇인가? 윈도우 API 이외에도 OLE,ODBC, 윈속 (Winsock) 관련클래스를포함하여 230 여개의클래스를제공 MFC Collections, Miscellaneous Classes Base MFC Classes OLE Classes ODBC Classes Win32 API (SDK) OLE ODBC Windows Base OS Services Windows OS Service Extensions [3] 2

Application Framework AppWizard,ClassWizard,Workspace등과 MFC를유기적으로연결하여응용프로그램을쉽고편리하게만들어주는도구모든어플리케이션에공통적으로필요한골격을자동생성 프로그래머는고유기능만추가어플리케이션프레임워크의사용잇점 프레임워크의어플리케이션은표준화된구조를사용한다. 프레임워크의어플리케이션은작고빠르다 MFC코드와의동적연결방법 (Shared DLL) 으로작은크기 MFC관련 DLL이시스템에있어야한다. 프레임워크를이용하면코딩작업이줄어개발기간단축 AppWizard, ClassWizard, 리소스편집기, Component Gallery [4] MFC 의계층구조 CObject (MFC Base Class) Command Targets Threads Application Documents Windows Frames Views Dialogs Controls Exceptions File Services DCs GDI Objects Menus Collections ODBC Support OLE Support Windows Socket Support Utility Classes Support Classes Collection Templates [5] 3

MFC 개요 주요클래스 Application Architecture 클래스 CWinApp, CDocument, CCmdTarget, CWinThread User-Interface 클래스 CFrameWnd, CControlBar, CDialog, CButton, CListBox, CScrollBar,... General purpose 클래스 CFile, CString, CException, CByteArray, CPoint,... [6] The Application Framework CWinApp CFrameWnd CDocument CView MYAPP.EXE CDocTemplate [7] 4

CWinApp Class CObject CCmdTarget CWnd CWnd Exceptions File Services Device Contexts Graphical Drawing Objects Menus OLE Support Collections Application Objects Document Architecture CCmdTarget CWinThread Frame Windows Control Bars Views Dialog Boxes Controls CWinApp Application objects are derived from CWinApp. derived application class class [8] CObject CFrameWnd Class CCmdTarget CWnd CWnd Exceptions File Services Device Contexts Graphical Drawing Objects Menus OLE Support Collections Application Objects Document Architecture CWnd CWnd CFrameWnd CFrameWnd CMDIChildWnd CMDIChildWnd Frame Windows Control Bars Views Dialog Boxes Controls user user MDI MDI windows windows Application window objects are derived from the CFrameWnd base class. CMDIFrameWnd CMDIFrameWnd user user MDI MDI workspaces workspaces [9] 5

Documents and Views Document Data 0 17 98 16 87 56 85 44 66 72 19 71 11 45 95 80 51 0 35 92 56 85 44 66 72 19 71 11 45 95 Possible Views [10] 객체간의통신 멤버함수들이객체간의통신을제공한다 View Object UpdateAllViews, GetNextView GetDocument Document Object GetActiveView GetActiveDocument Frame Object [11] 6

MFC Programming Framework classes CObject CCmdTarget CWinApp CDocTemplate CWnd CDocument CFrameWnd CView CDialog CYourApp CYourFrame CYourVw CYourDlg CYourDoc [12] 주요생성클래스 어플리케이션클래스 (CTestApp) 전역객체 (theapp) 생성 ~> MFC 프로그램시작 전역객체 theapp 에의해응용프로그램의초기화, 메시지루프, 종료작업이수행 Document Template Class(SDI:CSingleDocTemplate) 프레임클래스 (CMainFrame), 뷰클래스 (CTestView), 도큐먼트클래스 (CTestDoc), 리소스를유기적으로결합하여관리메인프레임클래스 응용프로그램의메인윈도우를표현 툴바, 상태바, 메뉴바등사용자영역을제외한부분 (Non-Client) 을관리 뷰클래스 실제데이타를보여주는사용자영역을관리도큐먼트클래스 각종데이터를유지 / 관리하며 Serialization 을통한파일입출력을담당 [13] 7

Messages and Commands 일반적인윈도우메시지 응용프로그램의윈도우에대한하드웨어, 소프트웨어이벤트커맨드메시지 (command) 사용자의요청과통신하는데사용모든메시지와커맨드는 On 핸들러 (handlers) 를가져야한다. MFC framework-supplied Programmer-supplied Default window procedure MFC 는메시지를그의핸들러에라우팅하기위해서 message maps 을사용한다. [14] MFC Naming Conventions Class names C stands for Class Capitalize first letter of each word: CCmdTarget Member functions and data members Capitalize beginning letters: ::UpdateAllViews m_ for data members: m_pmodify (Hungarian) Get and Set prefixes on member functions Prefixes for global names: AFX, Afx, and afx AFX : global identifiers (AFX_MSG_MAP) Afx : global functions (::AfxGetApp) afx : global variables (afxdump) AFX - Application Framework Commented sections within class declarations [15] 8

Visual C++ 사용하기 차 례 Visual C++ 프로그램 AppWizard 프로그램빌드과정프로젝트워크스페이스실습 : Dialog based 프로그램클래스위저드 (ClassWizard) 리소스에디터사용디버거사용법 [17] 9

Visual C++ 프로그램 MFC Application 작성단계 1. 새 Project 생성 2. MFC AppWizard 실행 3. 시각적인설계 (Control 정의 ) 4. 코드작성 (ClassWizard 사용 ) 5. compile & link & run 6. 필요에따라 debugging [18] Visual C++ 프로그램 프로젝트생성 [19] 10

Visual C++ 프로그램 응용프로그램타입설정 [20] Visual C++ 프로그램 기타사항설정 [21] 11

Visual C++ 프로그램 주석및라이브러리사용 [22] Visual C++ 프로그램 완료 [23] 12

실습 : Visual C++ 프로그램 Hello3 1. 메뉴에서 [File/New] 수행 MFC AppWizard(exe) 선택프로젝트이름 : Hello3 2. 응용프로그램종류 Dialog-based 선택 3. 메뉴에서 [Build/Build Hello.exe] 수행 4. 메뉴에서 [Build/Execute Hello.exe] 수행 [24] AppWizard Hello3 에서의 AppWizard AppWizard 선택된프로젝트의타입에따라코드골격을만들어주는역할 MFC AppWizard(exe) 1. 응용프로그램타입결정 (Dialog-based) 2. 기능설정 ( 디폴트 ) 3. 주석및라이브러리타입 ( 디폴트 ) MFC 라이브러리 : 어떤식으로링크할것인가? 4. 클래스와파일목록 ( 디폴트 ) [25] 13

윈도우프로그램의빌드과정 Source Code Files MyClass Resources Compiler Resource Compiler.OBJ binary.res.lib Static Library Modules linker.exe.lib Export Library (DLL Stubs) [26] 프로그램빌드 디버그모드와릴리즈모드 메뉴에서 [Build/Set Active Configuration] 선택디버그모드 : VC++ 에서디버깅할수있는코드를생성릴리즈모드 : 디버깅을위한추가코드를제거하고프로그램 Delivery 를위한모드현재빌드하려는형상 (Configuration) 을선택한다 [27] 14

프로젝트워크스페이스 프로젝트 워크스페이스 출력윈도우 [28] 프로젝트워크스페이스 구성뷰 ClassView : 프로젝트구성클래스 ResourceView : 리소스구성대화상자, 메뉴, 아이콘, 비트맵,... FileView : 프로젝트구성파일 InfoView : 도움말 [29] 15

실습 : Dialog based 프로그램 1. 리소스뷰선택 DIALOG 폴더에서 IDD_HELLO3_DIALOG 선택 2. 안녕하세요 누름버튼추가 버튼 ID : IDC_HELLO [30] 실습 : Dialog based 프로그램 3. 클래스위저드수행 IDC_HELLO 에대해 BN_CLICKED 선택한후 [Add Function] 수행. [Edit Code] 수행하여 OnHello 코드작성 MessageBox(" 안녕하세요 ", "Hello"); [31] 16

실습 : Dialog based 프로그램 4. 빌드후수행 [32] 클래스위저드 (ClassWizard) 컨트롤과코드를연결해주는도구 ClassWizard Landmark 역할 Control & Event & Event handler 관계를유지관리하는도구 Message Maps : message handler 추가, 삭제. Member Variables : 멤버변수를추가, 삭제또는 control 에연결하는기능 [33] 17

클래스위저드 (ClassWizard) IDC_HELLO 와 OnHello 함수 사용자가버튼을눌렀을때, 수행될일을 OnHello 와연결 CHello3Dlg 클래스의멤버함수선언 afx_msg void OnHello(); 메시지맵선언및구현 DECLARE_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CHello3Dlg, CDialog)... ON_BN_CLICKED(IDC_HELLO, OnHello) END_MESSAGE_MAP() [34] 리소스에디터사용 디폴트아이콘의변경 1. 워크스페이스의리소스탭선택 [Hello3 resources/icon/idr_mainframe] 선택 [35] 18

리소스에디터사용 2. 아이콘편집 3. 빌드후수행 [36] 디버거사용법 디버거 프로그래머가프로그래밍오류를파악하고, 이를수정하도록도와주는프로그램응용프로그램을단계적으로실행데이터를검사조건을확인 [37] 19

디버거사용법 1. Hello3 프로젝트에서, CHello3Dlg 의 OnHello() 코드변경 char sztemp[30] = To Test Debugger ; char seps[] = ; CString ret; char* p = strtok(sztemp, seps); while ( p ) ret += p; ret += - ; p = strtok(null, seps); MessageBox(ret, 테스트, MB_OK); [38] 디버거사용법 2. Break Point 설정 디버그모드로빌드한다. 다음라인에마우스를대고 F9 를누른다. char* p = strtok(sztemp, seps); F5 키를눌러서디버깅작업을시작한다. [39] 20

디버거사용법 3. 디버그시변수값보기 Variable 윈도우와 Watch 윈도우를사용한다. [40] Debug Tools in Visual C++ Build controls Restart Set Default Project Configuration The Debug Toolbar Step Out Step Into Debug controls Locals Disassembly QuickWatch Memory Stop Debugging Step Over Watch Call Stack Step to Cursor Registers Debug Window Controls [41] 21

디버거사용법 Debugging command Restart : 프로그램처음부터다시시작 Stop debugging : 디버거모드강제종료 Step Into : 함수내부로 (F11) Step Over : 한줄단위로실행 (F10) Step Out : 현재함수밖으로 Quick Watch : 마우스로특정변수선택 & Quick Watch 클릭하면선택한변수의값을볼수있음 Tip 임의의변수위에마우스를멈추면해당변수의값을볼수있다. [42] Document/View 구조 문서클래스 2. 그내용을반영한다. 뷰클래스 1. 사용자의입력을받는다 3. 윈도우로출력한다. [43] 22

MFC MDI 프로그램의윈도우구조 파일 편집 타이틀 MDI 메인윈도우 타이틀 MDI 클라이언트윈도우 MDI 자식윈도우 뷰윈도우 [44] WinMain int WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) if (!hprevinstance) // 처음으로실행되는경우에는 InitApplication(hInstance); // 윈도우클래스를등록한다. InitInstance(hInstance); // 메인윈도우를생성한다. while(getmessage(...))... DispatchMessage(...); // 메시지루프 // 메시지를윈도우프로시저로나눔 // 프로그램이종료되기전에청소작업을행한다.... return msg.wparam; [45] 23

MFC 의 WinMain MFC\SRC\winmain.cpp CWinApp 클래스에존재 CWinApp::InitApplication CWinApp::InitInstance CWinApp::Run CWinApp::ExitInstance InitInstance, ExitInstance 만 override 하여사용가능가상함수의중요성 [46] CObeditApp 클래스 class CObeditApp : public CWinApp public: CObeditApp(); // Overrides // ClassWizard generated virtual function overrides //AFX_VIRTUAL(CObeditApp) public: virtual BOOL InitInstance(); // 프로그램의초기화 //AFX_VIRTUAL // Implementation //AFX_MSG(CObeditApp) afx_msg void OnAppAbout();... //AFX_MSG [47] 24

InitInstance 함수 BOOL CObeditApp:InitInstance()... LoadStdProfileSettings(); // 표준 INI 화일 option 을읽어들임 CMultiDocTemplate* pdoctemplate; pdoctemplate = new CMultiDocTemplate( IDR_OBEDITTYPE, RUNTIME_CLASS(CObeditDoc), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CObeditView)); AddDocTemplate(pDocTemplate); // View-Doc 등록 CMainFrame* pmainframe = new CMainFrame; // main window 생성 if (!pmainframe->loadframe(idr_mainframe)) return FALSE; m_pmainwnd = pmainframe;... [48] RegisterShellFileTypes(TRUE); // 화일의 icon, 확장자등록 CCommandLineInfo cmdinfo; ParseCommandLine(cmdInfo); if (!ProcessShellCommand(cmdInfo)) return FALSE; pmainframe->showwindow(m_ncmdshow); pmainframe->updatewindow(); return TRUE; Obedit.ini 화일 [Recent File List] File1=D:\obedit\step8\new.OBE File2=D:\obedit\step7\test4.OBE [49] 25

레지스트리작업 WriteProfileInt, GetProfileInt, WriteProfileString, GetProfileString void CObeditApp::LoadStdProfileSettings()... // 나름대로초기화값을읽어다저장한다. CWinApp::LoadStdProfileSettings(); // 선조함수호출 SetRegistryKey [50] Run() CObeditApp 안에서수행 CWinApp 로부터상속되어 virtual 로선언됨윈도우운영체제로부터의모든메시지를응용프로그램에대해사용할것을요구응용프로그램이실행되는한계속실행됨응용프로그램종료시수행중단 [51] 26

CMainFrame 클래스 class CMainFrame : public CMDIFrameWnd DECLARE_DYNAMIC(CMainFrame)... protected: CStatusBar m_wndstatusbar; CToolBar m_wndtoolbar; protected: //AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpcreatestruct); //AFX_MSG DECLARE_MESSAGE_MAP() // 메시지맵 ; WM_CREATE OnCreate 함수호출 [52] OnCreate 함수 int CMainFrame::OnCreate(LPCREATESTRUCT lpcreatestruct) if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndtoolbar.create(this)!m_wndtoolbar.loadtoolbar(idr_mainframe)) return -1; if (!m_wndstatusbar.create(this)!m_wndstatusbar.setindicators(indicators, sizeof(indicators)/sizeof(uint))) return -1; m_wndtoolbar.setbarstyle(m_wndtoolbar.getbarstyle() CBRS_TOOLTIPS CBRS_FLYBY CBRS_SIZE_DYNAMIC); m_wndtoolbar.enabledocking(cbrs_align_any);... [53] 27

CDocument class CDocument : public CCmdTarget void OnFileOpen(); // 파일오픈명령을실행하면불려진다. BOOL GetOpenFileName(LPCTSTR); // 다이얼로그를띄워파일이름을입력 void Serialize(CFile cfile); // 화일입출력을담당하는함수 CWnd* GetWindow(); // 현재문서의내용을보여주는윈도우포인터를리턴... void CDocument::OnFileOpen() CString szfilename; // CString 은문자배열에해당하는클래스 if (!GetOpenFileName(szFileName)) // 다이얼로그박스를띄워파일이름을 return; // 입력받는다. CFile cfile(szfilename); // CFile 은 MFC 에서화일 I/O 를담당 cfile.open(); // 화일을오픈한다. [54] Serialize(cfile); // 화일의내용을읽어들인다 (user가작성 ) cfile.close(); // 화일을닫는다. CWnd* pwnd = GetWindow(); // 이문서의내용을보여주는윈도의핸들을 pwnd->invalidate(null); // 얻어그내용을그리도록 WN_PAINT 메시지 // 발생 // CDocument 는실제바로사용하지못함 (MFC class) // 계승하여사용하여야 class CMyDocument : public CDocument // My data structure int m_nnumofobjects; Objects obj[100]; public: void Serialize(CFile cfile); // virtual function ; [55] 28

CObeditView 클래스 class CObeditView : public CView... public: CObeditDoc* GetDocument(); // 뷰에연결된문서객체의포인터반환... //AFX_VIRTUAL(CObeditView) public: virtual void OnDraw(CDC* pdc); // WM_PAINT 가왔을때실행 virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual BOOL OnPreparePrinting(CPrintInfo* pinfo); virtual void OnBeginPrinting(CDC* pdc, CPrintInfo* pinfo); virtual void OnEndPrinting(CDC* pdc, CPrintInfo* pinfo); //AFX_VIRTUAL... [56] 주요 CView 멤버함수 GetDocument 뷰와연계된문서오브젝트에대한포인터를돌려준다. AddDocTemplate 함수를통해 m_pdocument 멤버는 MFC가뷰를생성할때알아서초기화 OnInitialUpdate 뷰가처음만들어질때호출된다. OnDraw 뷰와연계된문서오브젝트의내용을윈도우위에그려준다. OnPrint 뷰와연계된문서오브젝트의내용을프린터로출력 OnUpdate 문서오브젝트의내용이변경되었을때문서오브젝트쪽에불러준다. [57] 29

CObeditDoc 클래스 class CObeditDoc : public CDocument... //AFX_VIRTAUL(CObeditDoc) public: virtual BOOL OnNewDocument(); virtual void Serialize(CArchive& ar); // file I/O //AFX_VIRTUAL... ; [58] 주요 CDocument 멤버함수 IsModified 문서오브젝트의내용이마지막으로저장된후에변경된적이있는지알려준다. SetModifiedFlag 문서오브젝트의내용이변경되었음을표시했다. UpdateAllViews 문서오브젝트의내용이바뀌었을때이내용을연계된뷰에게알려준다. 이안에서는뷰클래스의 OnUpdate 함수를부른다. DeleteContent 문서오브젝트가닫힐때불려진다. 이때문서오브젝트의청소작업을해야한다. OnNewDocument 사용자가 File 메뉴의 New 명령을수행하면불린다. OnOpenDocument 사용자가 File 메뉴의 Open 명령을수행하면불린다. OnSaveDocument 사용자가 File 메뉴의 Save 명령을수행하면불린다. OnCloseDocument 사용자가 File 메뉴의 Close 명령을수행하면불린다. [59] 30

실습 1 : AppWizard 를사용하지않는 MFC 응용프로그램 Project : Win32 Application An empty project Alt+F7 : Use MFC in a Shared DLL #include<afxwin.h> [60] 응용프로그램클래스 class COurApp:public CWinApp public: virtual BOOL InitInstance(); ; [61] 31

윈도우클래스 class COurWnd:public CFrameWnd public: COurWnd() Create(0,"Our Dumb MFC Application"); ; [62] 프로그램작성하기 BOOL COurApp::InitInstance(void) m_pmainwnd=new COurWnd; m_pmainwnd->showwindow(m_ncmdshow); return TRUE; COurApp AnApplication; [63] 32

프로젝트가나타나는방식 탭 형식 클래스와함수멤버이름 글로벌엔티티 리소스형식 파일이름 [64] AppWizard 가생성한커멘트 //Implementation //Attributes //Operations //Overrides //Constructor Version에따라달라지는코드. 모든것이포함됨 (data member, 함수 member ) 사용자코드추가가능. 클래스객체속성정의.Get()/Set() 형식. 클래스데이터멤버들에게작동하는함수멤버들을선언한다. 따라서클래스객체의속성을바꾸게된다. 파생클래스안에서오버라이드할수있는함수멤버선언클래스의섹션정의 컨스트럭터선언. 클래스멤버초기화에사용되는다른함수도포함. [65] 33

Precompiled Header.pch 에헤더를컴파일하여저장 Project Settings -> C/C++ -> Category -> Precompiled Header Automatic use of precompiled headers Use precompiled header [66] 프로그램작동방식 CTextEditorApp theapp; theapp 객체생성 WinMain() 호출 InitInstance() 수행 Run() 수행 [67] 34

응용프로그램의작업 ( 정리 ) theapp 생성 MFC 에서제공되는 WinMain() 실행 WinMain() 이 InitInstance() 호출 InitInstance() 는 document template, main frame window, document, view 를생성 WinMain() 이 Run() 을호출 Run() 은윈도우운영체제메시지를얻어서전달하기위한메인메시지루프를실행 [68] View ClassWizard.. <Ctrl+W> 메뉴바의 ClassWizard [69] 35

Summary AppWizard SDI/MDI SDI 의기초적인클래스 App Class FrameWindow Class Document Class View Class 응용프로그램객체 theapp Doc/View Document Template Class 객체 SDI : CSingleDocTemplate MDI : CMultiDocTemplate [70] From This Class You Can Access This Class Using CWinApp CMainFrame CChildFrame CDocument CView CWinApp AfxGetMainWnd() GetAfxMainWnd() GetAfxMainWnd()->GetActiveView() GetAfxManinWnd() or ->MDIGetActive() ->GetDocument() ->GetActiveView() m_pmainwnd CMainFrame AfxGetApp() MDIGetActive() If SDI: If SDI: or Or GetActiveView()->GetDocument() GeActiveView() theapp GetActiveFrame() If MDI: if MDI: MDIGetActive()->GetActiveView() MDIGetActive() ->GetDocument() ->GetActiveView() CChildFrame AfxGetApp() GetParentFrame() GetActiveView()->GetDocument() GetActiveView() Or theapp CDocument AfxGetApp() AfxGetMainWnd() GetAfxMainWnd()- POSITION pos = Or >MDIGetActive() GetFirstViewPosition(); theapp GetNextView(pos); CView AfxGetApp() AfxGetMainWnd() GetParentFrame() GetDocument() Or theapp Any other class AfxGetApp() AfxGetMainWnd() AfxGetMainWnd() If SDI: If SDI: ->MDIGetActive() AfxGetMainWnd()->GetActiveView() AFxGetMainWnd() Or ->GetDocument() ->GetActiveView() AfxGetMainWNd() Or if MDI: If MDI: ->GetActiveFrame() AfxGetMainWnd()->MDIGetActive() AfxGetMainWnd() ->GetActiveView()->GetDocument() ->MDIGetActive() ->GetActiveView() [71] 36

Message Map Message Map 구성 메세지맵은 3개의매크로이루어진다 DECLARE_MESSAGE_MAP 클래스선언부에있음 BEGIN_MESSAGE_MAP 함수정의부 END_MESSAGE_MAP 함수정의부 [73] 37

Message Map define ON_COMMAND() 매크로일단파악 #define ON_COMMAND(id, memberfxn) \ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMSG)&memberFxn, #define DECLARE_MESSAGE_MAP() \ private: \ static const AFX_MSGMAP_ENTRY _messageentries[]; \ protected: \ static AFX_DATA const AFX_MSGMAP messagemap; \ virtual const AFX_MSGMAP* GetMessageMap() const; \ [74] #define BEGIN_MESSAGE_MAP(theClass, baseclass) \ const AFX_MSGMAP* theclass::getmessagemap() const \ return &theclass::messagemap; \ AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theclass::messagemap = \ &baseclass::messagemap, &theclass::_messageentries[0] ; \ AFX_COMDAT const AFX_MSGMAP_ENTRY theclass::_messageentries[] = \ \ ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) #define END_MESSAGE_MAP() \ 0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 \ ; \ [75] 38

DECRARE_MESSAGE_MAP 에이해 [76] 1.messageEntries[]( 메세지 (+ 인식코드 ) 와 void 함수포인터를쌍들의배열 ) 와 2.messageMap( 상위클래스의 messagemap 주소와나의 _messageentries 배열의시작주소로이루어진구조체 ) 와 3.messageMap 구조체의주소를리턴하는 GetMessageMap() 함수가선언된다 BEGIN_MESSAGE_MAP 에의해 _messageentries 배열값을받고 배열값은 BEGIN 매크로와 END 매크로사이에놓인매크로들로채워진다 END_MESSAGE_MAP 에의해배열에마지막에 NULL 이저장된다 [77] 39

MESSAGE DRIVEN [78] Class CWnd virtual LRESULT WindowProc(UINT message, WPARAM wparam, LPARAM lparam); virtual BOOL OnWndMsg(UINT message, WPARAM wparam, LPARAM lparam, LRESULT* presult); 클라이트영역에서마우스가눌렸을때 WM_PAINT 메세지를 CSketcherView 가받게되는데 WM_LBUTTONDWON 메세지같은일반메세지는그메세지와해당이있는즉여기서는마우스커서밑에있는 VIEW 가받게되지 FRAME 에핸들러가있다해도그쪽으로전달되지않는 WM_COMMAND 는좀다른경우인데 CCMDTARGET 의하위 CLASS 모두에게전달되게하는 COMMAND ROUTING(VIEW->DOC->FRAME) 을한다하였튼이메세지를전달하기위해 CWnd 에서상속받은가상 CSketcherView 의 WindowProc 함수가호출된다 [79] 40

WindowProc 은내부적으로 OnWndMsg 를호출하고 OnWndMsg 함수는 CSketcherView::messageMap 의포인터를얻는 GetMessageMap 을호출하고 CSketcherView::_messageEntries 에서현재처리를기다리고있는 WM_PAINT 메시지의 ID 와일치하는항목을찾는작업이수행하여찾으면 ID 에해당하는 CSketcherView 의함수를호출하고없으면 CSketcherView::messageMap 을참조하여 CSketcherView 의상위클래스인 CView::messageMap 의포인터를얻은다음기반클래스에대해위의작업을반복하고끝까지없으면 window 로다시돌려보낸다. [80] User Defined Windows Messages 코드직접넣기 User-defined messages may be included in a message map by using the ON_MESSAGE macro. This macro accepts a message number and a member function of the form: // inside the class declaration afx_msg LRESULT OnMyMessage(WPARAM wparam, LPARAM lparam); For example: #define WM_MYMESSAGE (WM_USER + 100) BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass) ON_MESSAGE(WM_MYMESSAGE, OnMyMessage) END_MESSAGE_MAP() [81] 41

In this example, we establish a handler for a custom message with a Windows message ID derived from the standard WM_USER base for user-defined messages. You might invoke this handler with code such as: CWnd* pwnd =...; pwnd->sendmessage(wm_mymessage); The range of user defined messages using this approach must be in the range WM_USER to 0x7fff. [82] Registered Windows Messages 코드직접넣기 The ::RegisterWindowMessage function is used to define a new window message that is guaranteed to be unique throughout the system. The macro ON_REGISTERED_MESSAGE is used to handle these messages. This macro accepts a the name of a near UINT variable that contains the registered windows message ID. For example [83] 42

class CMyWnd : public CMyParentWndClass public: CMyWnd(); //AFX_MSG(CMyWnd) afx_msg LRESULT OnFind(WPARAM wparam, LPARAM lparam); //AFX_MSG DECLARE_MESSAGE_MAP() ; [84] static UINT NEAR WM_FIND = RegisterWindowMessage("COMMDLG_FIND"); BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass) //AFX_MSG_MAP(CMyWnd) ON_REGISTERED_MESSAGE(WM_FIND, OnFind) //AFX_MSG_MAP END_MESSAGE_MAP() The registered Windows message ID variable (WM_FIND in the example above) must be a NEAR variable because of the way ON_REGISTERED_MESSAGE is implemented. The range of user defined messages using this approach will be in the range 0xC000 to 0xFFFF. [85] 43

Command Messages Command messages from menus and accelerators are handled in message maps with the ON_COMMAND macro. This macro accepts a command ID as well as a member function. Only the specific WM_COMMAND message with a wparam equal to the specified command ID is handled by the member function specified in the message-map entry. Command handler member functions take no parameters and return void. The macro has the form: ON_COMMAND(id, memberfxn) [86] Command update messages are routed through the same mechanism as ON_COMMAND handlers. The ON_UPDATE_COMMAND_UI macro is used instead. Command update handler member functions take a single parameter, a pointer to a CCmdUI object, and return void. The macro has the form ON_UPDATE_COMMAND_UI(id, memberfxn) An extended form of command message handlers is available for advanced uses. The ON_COMMAND_EX macro is used instead and provides a superset of the ON_COMMAND functionality. Extended command-handler member functions take a single parameter, a UINT containing the command ID, and return a BOOL. The BOOL return should be TRUE to indicate that the command has been handled, otherwise routing will continue to other command target objects. [87] 44

Control Notification Messages 코드직접넣기 Messages that are sent from child controls to a window have an extra bit of information in their message map entry: the control's ID. The message handler specified in a message map entry is called only if (1) the control notification code (high word of lparam), such as BN_CLICKED, matches the notification code specified in the message-map entry and (2) control ID (wparam) matches the control ID specified in the message-map entry. Custom control notification messages may use the ON_CONTROL macro to define a message map entry with a custom notification code. This macro has the form ON_CONTROL(wNotificationCode, id, memberfxn) [88] 메뉴와툴바사용하기 45

강의내용 MFC 기반프로그램의메시지를처리방법메뉴리소스의정의, 생성및수정메뉴속성의정의, 생성및수정메뉴항목이선택시생성되는메시지보조함수생성방법메뉴속성들을업데이트하기위해핸들러를추가하는방법툴바버튼의추가방법과메뉴항목들과의연결 [90] 목차 MFC 기반프로그램의메시지처리방법메뉴리소스의생성및수정메뉴속성의생성및수정메뉴항목선택시생성되는메시지보조함수메뉴속성갱신을위한핸들러추가툴바버튼의추가와기존메뉴항목과의연결 [91] 46

SDK/MFC 에서의메시지처리 LONG export FAR PASCAL MainWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) switch(msg) case WM_CREATE : OnCreate(); break; case WM_PAINT : OnPaint(); break; case WM_DESTROY : OnDestroy(); break; default : DefWindowProc(); return OL; BEGIN_MESSAGE_MAP(CMyWnd, CWnd) ON_WM_CREATE() ON_WM_PAINT() ON_WM_DESTROY() END_MESSAGE_MAP() AFX_MSGMAP_ENTRY _messageentries[]= WM_CREATE, OnCreate, WM_PAINT, OnPaint, WM_DESTROY, OnDestroy ; [92] MFC 에서의메시지처리 CWnd _AFXWIN_INLINE afx_msg int CWnd::OnCreate(LPCREATESTRUCT) return (int)default(); // DefWindowProc() 을부름 대부분의메시지는거의모두 Default() 를부름 CMainFrame BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_WM_CREATE() END_MESSAGE_MAP() int CMainFrame::OnCreate(LPCREATESTRUCT lpcreatestruct) // 상위클래스의 OnCreate 부터부른다음작업수행 if(cmdiframewnd::oncreate(lpcreatestruct) == -1) return -1; if (!m_wndtoolbar.create(this)!m_wndtoolbar.loadtoolbar(idr_mainframe))... [93] 47

명령경로배정 (command routing) WM_COMMAND, WM_UPDATE_COMMAND_UI CCmdTarget 로부터계승받은클래스만받을수있다. 메뉴처리 CWnd 가아닌 CDocument, CView 에서처리하는것이자연스러움 예 ) 화일저장, 색선택 CObject CCmdTarget CWinApp CDocTemplate CWnd CDocument CMultiDocTemplate CSingleDocTemplate CFrameWnd CView CDialog [94] Routing 순서 Comand 를받은오브젝트 routing 순서 프레임윈도우 (Frame Window) 1. 활성화된자식윈도우혹은뷰 2. 자기자신 3. CWinApp 오브젝트 뷰 (View) 문서 (Document) 다이얼로그 (Dialog) 1. 자기자신 2. 자신과연관된문서오브젝트 1. 자기자신 2. 이문서가속한문서템플릿 1. 자기자신 2. 이다이얼로그를소유한윈도우오브젝트 3. CWinApp 오브젝트 [95] 48

CCmdUI 의멤버함수 멤버함수이름 기능 Enable 메뉴항목의상태를활성화시키거나그레이상태로만든다. SetCheck 메뉴항목의옆에체크표시를만든다. 툴바버튼의경우에는눌려진 상태로표시한다. SetRadio 기능자체는 SetCheck와같은데체크표시대신에 표시를사용한다. SetText 메뉴항목의텍스트를변경한다. 툴바버튼에대해서는별의미가없다. [96] 메시지맵매크로 기존의윈도우메시지 WM_XXXX, ON_WM_XXXX, OnXxxxx 예 ) WM_CHAR, ON_WM_CHAR, OnChar WM_COMMAND, WM_UPDATE_COMMAND_UI 메시지는예외함수의이름을사용자가정할수있음, void 처리함수이름 (void); 사용자정의메시지 WM_USER 에서 0x7FFF 사이의값 ON_MESSAGE LONG 처리함수이름 (DWORD, LONG); 등록된메시지 RegisterWindowMessage 함수를이용해메시지값을만든경우 ON_REGISTERED_MESSAGE, 함수의인자는사용자정의메시지와동일콘트롤로부터의알림 (notification) 메시지 ON_CONTROL( 알림코드, 컨트롤 ID, 처리함수이름 ) void 처리함수이름 (void); [97] 49

윈도우운영체제와의통신 Message Map // Implementation //AFX_MSG(CSketcherApp) afx_msg void OnAppAbout(); // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code! //AFX_MSG DECLARE_MESSAGE_MAP() [98] CCmdTarget CWinThread CWnd CDocument CWinApp CFrameWnd CView CCtrlView CMDIChildWnd CMDIFrameWnd CEditView [99] 50

Message Handler 정의 BEGIN_MESSAGE_MAP(CSketcherApp, CWinApp) //AFX_MSG_MAP(CSketcherApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //AFX_MSG_MAP // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) // Standard print setup command ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup) END_MESSAGE_MAP() [100] Message 종류 Window Message Control notification message Command Message WM_ 으로시작 (WM_COMMAND 메시지제외 ) 예를들어, WM_PAINT, WM_LBUTTONUP 등자식윈도우에서부모윈도우에전달되는 WM_COMMAND 메시지. 메뉴항목과툴바버튼등과같이사용자인터페이스요소로부터오는 WM_COMMAND 메시지. MFC 는표준메뉴와툴바명령메시지에대해서특유의식별자를정의한다. [101] 51

메시지처리 SDI 메뉴객체 도큐먼트객체 도큐먼트템플릿객체 메인프레임윈도우객체 응용프로그램객체 MDI 활성화된뷰객체 활성된뷰와연계된도큐먼트객체 활성화된도큐먼트에대한도큐먼트템플릿객체 활성화된뷰에대한프레임윈도우객체 메인프레임윈도우객체 응용프로그램객체 [102] 실습 1 : Sketcher 프로그램확장 메인메뉴바와각각의메뉴에서나타나는메뉴항목정의어떤클래스가각각의메뉴항목에대한메시지를처리할것인지결정메시지처리함수클래스에추가메뉴모양갱신함수를클래스에추가툴팁을갖추고있는툴바버튼추가 [103] 52

리소스생성및편집 메뉴항목추가 Sketcher.rc 안의리소스형식 IDR_SKETCHTYPE 에해당되는메뉴. 편집, 확장가능 [104] 리소스생성및편집 서브메뉴항목유뮤 Element 가메뉴바에나타남 비활성화시킴 바위의메뉴항목들이실행시오른쪽정렬 응용프로그램시작시비활성화 [105] 53

리소스생성및편집 항목사이에분리자생성 메뉴항목식별 ID 새로운열에항목출력 체크표시가나타남 항목선택시상태바에출력 [106] Class Wizard 의사용 제어 Project: Class Name: Object Ids: Messages: Member functions: 사용법 현재의프로젝트 현재작업클래스 현재의클래스에추가할수있는핸들러 ID 특정객체 ID 에대해사용할수있는메시지형식 현재클래스안에서이미정의되어있는메시지핸들러 [107] 54

메뉴메시지함수생성 메시지탭 메시지형식을선택하면 Add Function 이활성화된다. 클래스선택 함수생성 처리될메시지 ID 선택 [108] Messages 메시지 COMMAND UPDATE_COMMAND_UI 발생하는경우 특정메뉴항목이선택될때발생. 핸들러는선택된항목에대해적절한작업을제공해야한다. 메뉴가상태에따라서업데이트되어야할때발생. 팝업메뉴가나타나기전에발생하므로, 그것을보기전에메뉴항목의외관을설정할수있다. [109] 55

Add Function [110] 생성된메시지맵함수 protected: //AFX_MSG(CSketcherDoc) afx_msg void OnColorGreen(); afx_msg void OnColorRed(); afx_msg void OnElementCircle(); afx_msg void OnElementCurve(); afx_msg void OnElementLine(); afx_msg void OnElementRectangle(); afx_msg void OnColorBlue(); afx_msg void OnUpdateColorBlack(CCmdUI* pcmdui); afx_msg void OnUpdateColorBlue(CCmdUI* pcmdui); afx_msg void OnUpdateColorGreen(CCmdUI* pcmdui); afx_msg void OnUpdateColorRed(CCmdUI* pcmdui); afx_msg void OnUpdateElementCircle(CCmdUI* pcmdui); afx_msg void OnUpdateElementCurve(CCmdUI* pcmdui); afx_msg void OnUpdateElementLine(CCmdUI* pcmdui); afx_msg void OnUpdateElementRectangle(CCmdUI* pcmdui); afx_msg void OnColorBlack(); //AFX_MSG DECLARE_MESSAGE_MAP() ; [111] 56

BEGIN_MESSAGE_MAP(CSketcherDoc, CDocument) //AFX_MSG_MAP(CSketcherDoc) ON_COMMAND(ID_COLOR_GREEN, OnColorGreen) ON_COMMAND(ID_COLOR_RED, OnColorRed) ON_COMMAND(ID_ELEMENT_CIRCLE, OnElementCircle) ON_COMMAND(ID_ELEMENT_CURVE, OnElementCurve) ON_COMMAND(ID_ELEMENT_LINE, OnElementLine) ON_COMMAND(ID_ELEMENT_RECTANGLE, OnElementRectangle) ON_COMMAND(ID_COLOR_BLUE, OnColorBlue) ON_UPDATE_COMMAND_UI(ID_COLOR_BLACK, OnUpdateColorBlack) ON_UPDATE_COMMAND_UI(ID_COLOR_BLUE, OnUpdateColorBlue) ON_UPDATE_COMMAND_UI(ID_COLOR_GREEN, OnUpdateColorGreen) ON_UPDATE_COMMAND_UI(ID_COLOR_RED, OnUpdateColorRed) ON_UPDATE_COMMAND_UI(ID_ELEMENT_CIRCLE, OnUpdateElementCircle) ON_UPDATE_COMMAND_UI(ID_ELEMENT_CURVE, OnUpdateElementCurve) ON_UPDATE_COMMAND_UI(ID_ELEMENT_LINE, OnUpdateElementLine) ON_UPDATE_COMMAND_UI(ID_ELEMENT_RECTANGLE, OnUpdateElementRectangle) ON_COMMAND(ID_COLOR_BLACK, OnColorBlack) //AFX_MSG_MAP END_MESSAGE_MAP() [112] 메뉴메시지함수작성 색깔과요소모드를저장하기위한멤버추가 COLORREF m_color; WORD m_element; 멤버추가방법 Mouse popup menu -> Add Member Variable [113] 57

새로운클래스데이터멤버초기화 //Definitions of constants #ifndef OurConstants_h #define OurConstants_h // Element type definitions // Each type value must be unique const WORD LINE = 101U; const WORD RECTANGLE = 102U; const WORD CIRCLE = 103U; const WORD CURVE = 104U; /////////////////////////////////// // Color values for drawing const COLORREF BLACK = RGB(0,0,0); const COLORREF RED = RGB(255,0,0); const COLORREF GREEN = RGB(0,255,0); const COLORREF BLUE = RGB(0,0,255); /////////////////////////////////// #endif //!defined(ourconstants.h) Sketcher.h 에 include [114] 컨스트럭터및메뉴함수 CSketcherDoc::CSketcherDoc() // TODO: add one-time construction code here m_element = LINE; // Set initial element type m_color = BLACK; // Set initial drawing color void CSketcherDoc::OnColorBlack() m_color = BLACK; // Set the drawing color to black void CSketcherDoc::OnElementLine() m_element = LINE; // Set element type as a line [115] 58

UPDATE_COMMAND_UI ON_UPDATE_COMMAND_UI(ID_COLOR_BLACK,OnUpdateColorBlack) [116] 명령업데이트핸들러작성 void CSketcherDoc::OnUpdateColorBlack(CCmdUI* pcmdui) // TODO: Add your command update UI handler code here pcmdui->setcheck(m_color==black); void CSketcherDoc::OnUpdateElementLine(CCmdUI* pcmdui) // Set Checked if the current element is a line pcmdui->setcheck(m_element==line); [117] 59

Method ContinueRouting() Enable() SetCheck() SetRadio() 목적 메시지를그다음의우선순위를갖는핸들러에전달한다. 관계되는인터페이스항목을인에이블또는디스에이블시킨다. 관계되는인터페이스항목에대한체크표시를설정한다. 라디오그룹안에있는하나의버튼을 on/off시킨다. 관계되는인터페이스항목에대한텍스트를설정한다. SetText() [118] CToolBar 클래스의주요함수 CommandToIndex 버튼 ID를주면툴바의좌측부터세어그에해당하는 인덱스를준다. 0부터센다. GetItemID CommandToIndex와는반대로버튼의인덱스 로부터 버튼 ID를얻어준다. Create 툴바를생성한다. EnableDocking 도커블툴바로동작할수있도록설정하며프로임 윈도우의어느곳에붙을수있는지도명시한다. GetBarStyle 툴바의스타일을얻어온다. SetBarStyle 툴바의스타일을설정한다. GetButtonInfo 특정버튼에대한정보를얻어온다. SetButtonInfo 특정버튼의정보를변경한다. GetCount 툴바버튼의총수를얻어온다 (SEPARATOR 포함 ). GetItemRect 버튼 ID를주면그버튼의툴바에서의위치를돌려준다. LoadBitmap 버튼모양을담고있는비트맵을로드한다. SetHeight 툴바의버튼높이를변경한다. SetSizes 툴바의크기를변경한다. [119] 60

MFC 의주요전역함수 AfxGetApp 프로그램을대표하는프로그램오브젝트에대한 포인터를돌려준다. AfxGetAppName 프로그램의이름을돌려준다. AfxGetInstanceHandle 프로그램의인스턴스핸들을돌려준다. AfxGetMainWnd 메인프레임윈도우오브젝트에대한포인터를 돌려준다. GetCurrentMessage 현재처리중인메시지에대한메시지스트럭처를 돌려준다. 메시지핸들러등에서메시지스트럭처 를직접접근하고싶을때이용한다. AfxSocketInit 윈도우소켓을초기화하기위해부른다. AfxBeginThread 새로운스레드를시작한다. AfxEndThread 현재의스레드를끝낸다. AfxGetThread 현재실행중인스레드에대한포인터 (CWinThread) 를돌려준다. [120] 툴바버튼추가 추가될다음버튼 편집되는리소스 ID 마우스로편집가능 사용하고자하는색깔 [121] 61

툴바버튼속성편집 버튼을더블클릭하여속성윈도우에서 ID 선택 [122] Resource View 의 String Table 리소스편집하려는 ID 를선택 \n 으로툴팁생성 툴팁추가하기 [123] 62

SUMMARY MFC 는클래스에대한.cpp 안에나타나는메시지맵안에서클래스에대한메시지핸들러를정의한다. 메뉴와툴바에서발생한명령메시지는 CCmdTarget 으로부터파생되는어떠한클래스안에서도처리될수있다. 명령메시지가아닌메시지들은 CWnd 로부터파생된클래스안에서만처리된다. MFC 는명령메시지에대한핸들러를찾기위해미리정해진순서로클래스를검색한다. 메뉴와툴바의외관은리소스파일안에서정의된다. 메뉴항목은 ID_ 라는전치사를갖는심볼상수에의해명령메시지를발생시킨다. 그러한 ID 들은핸들러를메뉴항목의메시지와연계시키는데사용된다. 툴바버튼을특정한메뉴항목과연계시키려면메뉴항목과동일한 ID 를부여하면된다. 툴팁을추가하기위해서는 String Table 리소스안의항목엔트리에 \n 을추가하면된다. [124] Device Context 63

OnDraw() 의이중작업 WM_PAINT File Print,PrintPreview ID_FILE_PRINT, ID_FILE_PRINT_PREVIEW Void CView::OnPaint() void CView::OnPrint(CDC* pdc, CPrintInfo*) CPaintDC dc(this); OnPrepareDC(&dc); ASSERT_VALID(pDC); OnDraw(&dc); OnDraw(pDC); Void CView::OnDraw(CDC* pdc) [126] Device Context CDC* GetDC( ); Identifies the device context for the CWnd client area if successful; otherwise, the return value is NULL. The pointer may be temporary and should not be stored for later use. CClientDC( CWnd* pwnd ); pwnd : The window whose client area the device context object will access. [127] 64

CDC 객체의생성과소멸 void CSketcherView::OnLButtonDown(UINT nflags, Cpoint point) CRect rect; CClientDC dc(this); // 스택상에 dc 생성 dc.getclipbox(rect); // 클리핑사각형얻는다. //dc 자동해제 [128] CDC 객체의생성과소멸 void CSketcherView::OnLButtonDown(UINT nflags,cpoint point) CRect rect; CDC* pdc = GetDC(); //dc 포인터 pdc->getclipbox(rect); ReleaseDC(pDC) // 반드시호출해야한다. **OnDraw() 함수에전달된 CDC 객체포인터는 Application Framework 가소멸시켜주기때문에자신이직접소멸시키면안된다. [129] 65

CDC 클래스의주요함수 (1) CreateCompatibleDC 인자로주어진 DC와같은속성을갖는 DC를 메모리에만든다. GetSafeHdc 현재오브젝트가둘러싸고있는디바이스컨텍 스트핸들을돌려준다. IsPrinting 프린트 DC인지아닌지의여부를돌려준다. SetROP2 그리기모드를변경하는데사용된다. SetBkColor 글자출력시의배경색을지정한다. SetTextColor 글자출력시의글자색을지정한다. MoveTo, LineTo 직선을긋는데사용한다. Arc, ArcTo 원호를그리는데사용한다. PolyDraw 직선과베지어스프라인을연속적으로그림 PloyLine 직선을연속적으로그리는데사용 Polygon 직선을연속적으로그리는데처은점과마지막 점을잇는다 [130] CDC 클래스의주요함수 (2) PolyBezier 베이어스프라인을연속적으로그리는데사용 InvertRect 주어진영역을반전하는데사용한다. DrawIcon 주어진위치에주어진아이콘을그려준다. Draw3dRect 입체적인사각형을그리는데사용한다. Ellipse 타원 ( 원포함 ) 을그리는데사용한다. Pie 부채꼴을그리는데사용한다. Rectangle 사각형을그리는데사용한다. RountRect 모서리가둥근사각형을그리는데사용한다. SetPixel 점을찍는데사용한다. BitBlt 한디바이스컨텍스트의내용을다른디바이스컨텍스트로복사한다. TextOut 주어진위치에텍스트를출력한다. DrawText 주어진사각형내에텍스트를출력한다. [131] 66

CPaintDC Class Void CSketcherView::OnPaint() CPaintDC dc(this); OnPrepareDC(&dc); OnDraw(&dc); **CPaintDC 생성자는 BeginPaint() 함수를호출하고소멸자는 EndPaint() 함수를호출한다. 스택상에디바이스컨텍스트를생성한경우 EndPaint() 함수는자동으로호출된다. [132] GDI 객체 기초클래스 : CGdiObject CBitmap CBrush CFont CPalette CPen CRgn [133] 67

GDI 객체의생성 CGdiObject 클래스는 GDI 객체를생성할수없다. CPen 과 CBrush 는생성자로만 GDI 생성가능 CFont 와 CRgn 는클래스는디폴트생성자사용후, CreateFont() 또는 CreatePolygonRgn() 과같은생성함수호출. [134] GDI 객체의소멸 소멸자는 C++ 객체에 attach 된윈도우 GDI 객체를삭제한다. CGdiObject 클래스에서파생된클래스의객체를생성한경우프로그램이종료되기전에반드시 GDI 객체를삭제해야한다. GDI 객체를삭제하려면, 해당객체를 DC 에서분리시켜야한다. [135] 68

전형적인 GDI 객체생성및소멸 Void CSketcherView::OnDraw(CDC* pdc) CPen newpen(ps_dashdotdot,2,(colorref)0); CPen* poldpen = pdc->selectobject(&newpen); pdc->moveto(10,10); pdc->lineto(110,110); pdc->selectobject(poldpen); //newpen 이선택해제된다. //newpen 이자동소멸된다. ** 디바이스컨텍스트객체가소멸될때디바이스컨텍스트에선택된모든 GDI 객체도해제된다. 따라서디바이스컨텍스트가먼저소멸되는경우굳이 GDI 객체를해제할필요는없다. [136] Stock GDI 객체 Stock GDI 객체는윈도우에종속적이므로객체에대한해제는신경쓸필요가없다. virtual CGdiObject* SelectStockObject( int nindex ); [137] 69

Void CSketcherView::OnDraw(CDC* pdc) Cpen newpen(ps_dashdotdot,2,(colorref)0); Cpen* poldpen = pdc->selectobject(&newpen); pdc->moveto(10,10); pdc->lineto(110,110); pdc->selectstockobject(black_pen); //newpen 이선택해제된다 //newpen 이자동소멸된다. [138] 매핑모드 매핑모드 (mapping mode) 윈도우출력함수 (GDI) 에서출력좌표를해석하는방법 디바이스컨텍스트 (device context) 마다존재 디폴트매핑모드는 MM_TEXT MM_TEXT 출력원점이윈도우클라이언트영역의좌측상단 출력원점에서 X 좌표는오른쪽으로증가, Y 좌표는아래방향으로증가 단위 : 픽셀 (pixel) 단점 : 해상도에따라출력되는내용의크기가달라진다. 예 ) 프린트 [139] 70

매핑모드의종류 매핑모드 단위 X 방향증가 Y방향증가 MM_TEXT 픽셀 오른쪽 아래쪽 MM_LOMETRIC 0.1 mm 오른쪽 위쪽 MM_HIMETRIC 0.01 mm 오른쪽 위쪽 MM_LOENGLISH 0.1 in 오른쪽 위쪽 MM_HIENGLISH 0.01 in 오른쪽 위쪽 MM_TWIPS 1/1440 in 오른쪽 위쪽 MM_ISOTROPIC 지정가능 지정가능 지정가능 MM_ANISOTROPIC 지정가능 지정가능 지정가능 MM_ISOTROPIC, MM_ANISOTROPIC 을이용하여화면확대 / 축소가능 [140] 매핑모드의변경 CDC 클래스의 SetMapMode 함수이용 CClientDC dc(this); dc.setmapmode(mm_lometric); dc.textout(100, 500, 테스트중입니다.-1 ); dc.textout(100, -500, 테스트중입니다.-2 ); 테스트중입니다.-1 500 윈도우밖으로출력되어보이지않는다. 500 100 테스트중입니다.-2 [141] 71

좌표계 디바이스 (device) 좌표 실제출력장치의좌표논리 (logical) 좌표 출력함수에사용하는좌표디바이스좌표와논리좌표간의변환이필요 DPtoLP LPtoDP 좌표계의원점이동 SetWindowOrg 논리좌표의원점이동 SetViewportOrg 디바이스좌표의원점이동 [142] CClientDC dc(this); dc.setmapmode(mm_lometric); dc.moveto(0,0); dc.lineto(100, -100); (0,0) 1 cm 1 cm [143] 72

CClientDC dc(this); dc.setmapmode(mm_lometric); dc.setviewportorg(100,100); // 디바이스좌표의원점이동 dc.moveto(0,0); dc.lineto(100,-100); (0,0) (100,100) 1 cm 1 cm [144] CClientDC dc(this); dc.setmapmode(mm_lometric); dc.setwindoworg(100,100); // 윈도우좌표의원점이동 dc.moveto(0,0); dc.lineto(100,-100); (0,0) 변경된원점 1 cm 1 cm 1 cm 1 cm [145] 73

윈도우안에서그리기 WM_PAINT->OnDraw() void CSketcherView::OnDraw(CDC* pdc) CSketcherDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here [146] CDC Class CObject CDC The CDC class defines a class of device-context objects. The CDC object provides member functions for working with a device context, such as a display or printer, as well as members for working with a display context associated with the client area of a window. [147] 74

CDC Class POINT struct typedef struct tagpoint LONG x; LONG y; POINT; 점의이동 CPoint MoveTo(int x,int y);//x,y 위치로이동 CPoint MoveTo(POINT apoint);//apoint 에의해정의되는위치로이동 선그리기 BOOL LineTo(int x,int y); // 선을 x,y, 위치까지그린다. BOOL LintTo(POINT apoint); //apoint 에의해정의되는위치까지선을그린다. [148] 호그리기 BOOL Arc(int x1,int y1, int x2, int y2, intx3, inty3, intx4, inty4); //(x1,y1) 과 (x2,y2) 에의해형성되는직사각형내의 (x3,y3) 점에서시작하 // 여, (x4,y4) 까지반시계방향으로그려지는호. (x3,y3) 와 (x4,y4) 가같으 // 면원이된다. BOOL Arc(LPCRECT lprect, POINT StartPt, POINT EndPt); 색상사용하기 CPen apen; // 펜객체생성 BOOL CreatePen(int apenstyle, int awidth, COLORREF acolor); 펜스타일 의미 PS_SOLID 실선 PS_DASH dash라인. 펜의폭이1일때만유효. PS_DOT 점선. 펜의폭이 1일때만유효. PS_DASHDOTDOT dash와두개의점이반복되어나타나는선. 펜폭이 1일때만유효. PS_NULL 어떤것도그리지않음. PS_INSIDEFRAME 실선. 선을지정하는점들이펜의중심이아닌 펜의가장자리에나타난다. [149] 75

샘플코드 void CSketcherView::OnDraw(CDC* pdc) CSketcherDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here // 펜객체를선언하며, 그것을 2 픽셀폭을갖는빨간실선펜으로서초기화한다. CPen apen; apen.createpen(ps_solid,2,rgb(255,0,0); Cpen.pOldPen=pDC->SelectObject(&aPen); //apen 을펜으로서선택한다. pdc->arc(50,50,150,150,100,50,150,100); // 첫번째원을그린다. // 두번째의보다작은원을감싸는직사각형을정의한다. CRect* prect=new Crect(250,50,300,100); CPoint Start(275,100); // 호의시작점 Cpoint End(250,75); // 호의끝점 pdc->arc(prect,start,end); // 두번째원을그린다. delete prect; pdc->selectobject(poldpen); // 이전펜을복구한다. [150] 브러시생성하기 CBrush abrush(hs_diagcross,rgb(255,0,0)); // 빨간색브러시정의 해치스타일 HS_HORIZONTAL HS_VERTICAL HS_BDIAGONAL HS_FDIAGONAL HS_CROSS HS_DIAGCROSS 의미수평해칭수직해칭왼쪽에서오른쪽의 45도각도윗방향으로의대각선해칭왼쪽에서오른쪽의 45도각도아랫방향으로의대각선해칭수평과수직의교차해칭 45도각도의교차해칭 CBrush abrush; abrush.createhatchbrush(hs_diagcross, RGB(255,0,0); [151] 76

브러시사용하기 pdc->selectobject(&abrush); // 브러시를디바이스컨텍스트안으로선택해서갖고온다. pdc->selectstockobject(null_brush); GRAY_BRUSH LTGRAY_BRUSH DKGRAY_BRUSH BLACK_BRUSH WHITE_BRUSH HOLLOW_BRUSH NULL_BRUSH [152] 마우스메시지의처리 마우스이벤트의종류 WM_LBUTTONDBLCLK WM_LBUTTONDOWN WM_LBUTTONUP WM_MOUSEMOVE WM_RBUTTONDBLCLK WM_RBUTTONDOWN WM_RBUTTONUP [153] 77

ClassWizard 에서 Mouse Event 생성 [154] ClassWizard 가생성한코드 void CSketcherView::OnLButtonDown(UINT nflags, CPoint point) // TODO: Add your message handler code here and/or call default Cview::OnLButtonDown(nFlags, point); Flag MK_CONTROL MK_LBUTTON MK_MBUTTON MK_RBUTTON MK_SHIFT 의미 <Ctrl> 키가눌려지고있는것에해당마우스왼쪽버튼이눌려지고있는것에해당마우스중간버튼이눌려지고있는것에해당마우스오른쪽버튼이눌려지고있는것에해당 Shift키가눌려지고있는것에해당 [155] 78

클라이언트영역다시그리기 void InvalidateRect( LPCRECT lprect, BOOL berase =TRUE); Parameters lprect Points to a CRect object or a RECT structure that contains the rectangle (in client coordinates) to be added to the update region. If lprect is NULL, the entire client area is added to the region. berase Specifies whether the background within the update region is to be erased. Remarks Invalidates the client area within the given rectangle by adding that rectangle to the CWnd update region. The invalidated rectangle, along with all other areas in the update region, is marked for painting when the next WM_PAINT message is sent. The invalidated areas accumulate in the update region until the region is processed when the next WM_PAINT call occurs, or until the region is validated by the ValidateRect or ValidateRgn member function. [156] Element.h #if!defined(elements_h) #define Elements_h class CElement : public CObject protected: COLORREF m_color; // Color of an element CRect m_enclosingrect; // Rectangle enclosing an element int m_pen; // Pen width public: virtual ~CElement() // Virtual destructor // Virtual draw operation virtual void Draw(CDC* pdc) const CRect GetBoundRect() const; // Virtual draw operation // Get the bounding rectangle for an element protected: CElement() ; // Default constructor // Class defining a line object class CLine : public CElement public: virtual void Draw(CDC* pdc) const; // Function to display a line [157] 79

// Constructor for a line object CLine(const CPoint& Start, const CPoint& End, const COLORREF& Color); protected: CPoint m_startpoint; CPoint m_endpoint; // Start point of line // End point of line CLine() ; // Default constructor - should not be used // Class defining a rectangle object class CRectangle : public CElement public: virtual void Draw(CDC* pdc) const; // Function to display a rectangle // Constructor for a rectangle object CRectangle(const CPoint& Start, const CPoint& End, const COLORREF& Color); protected: CRectangle() ; // Default constructor - should not be used [158] // Class defining a circle object class CCircle : public CElement public: virtual void Draw(CDC* pdc) const; // Function to display a circle // Constructor for a circle object CCircle(const CPoint& Start, const CPoint& End, const COLORREF& Color); protected: CCircle() ; // Default constructor - should not be used // Class defining a curve object class CCurve : public CElement public: virtual void Draw(CDC* pdc) const; // Function to display a curve // Constructor for a curve object CCurve(const COLORREF& Color); protected: CCurve() ; // Default constructor - should not be used #endif //!defined(elements_h) [159] 80

CLine Class 구현 class CLine : public CElement public: virtual void Draw(CDC* pdc) const; // Function to display a line // Constructor for a line object CLine(const CPoint& Start, const CPoint& End, const COLORREF& Color); protected: CPoint m_startpoint; CPoint m_endpoint; // Start point of line // End point of line CLine() ; // Default constructor - should not be used [160] Cline 클래스컨스트럭터 CLine::CLine(const CPoint& Start, const CPoint& End, const COLORREF& Color) m_startpoint = Start; // Set line start point m_endpoint = End; // Set line end point m_color = Color; // Set line color m_pen = 1; // Set pen width // Define the enclosing rectangle m_enclosingrect = CRect(Start, End); m_enclosingrect.normalizerect(); [161] 81

Draw() 함수구현 // Draw a CLine object void CLine::Draw(CDC* pdc) const // Create a pen for this object and // initialize it to the object color and line width CPen apen; if(!apen.createpen(ps_solid, m_pen, m_color)) // Pen creation failed. Abort the program AfxMessageBox("Pen creation failed drawing a line", MB_OK); AfxAbort(); CPen* poldpen = pdc->selectobject(&apen); // Select the pen // Now draw the line pdc->moveto(m_startpoint); pdc->lineto(m_endpoint); pdc->selectobject(poldpen); // Restore the old pen [162] Ccurve Class 구현 // Constructor for a curve object CCurve::CCurve(const COLORREF& Color) m_color = Color; // Store the color m_enclosingrect = CRect(0,0,0,0); m_pen = 1; // Set pen width // Draw a curve void CCurve::Draw(CDC* pdc) const [163] 82

드로잉모드설정 드로잉모드 R2_BLACK R2_WHITE R2_NOP R2_NOT R2_COPYPEN R2_NOTCOPYPEN R2_MERGEPENNOT R2_MERGENOTPEN R2_MERGEPEN R2_NOTMERGEPEN R2_MASKPEN R2_NOTMASKPEN R2_XORPEN R2_NOTXORPEN 효과모든그림은검은색모든그림은흰색아무것도하지않음화면색의반대펜의색깔로그려짐. 디폴트모드펜의색깔과반대펜의색과배경의반대색을 OR 연산한색펜의반대색과배경색을 OR 연산한색펜의색과배경색을OR 연산한색 R2_MERGEPEN의반대색배경색과펜의색을 AND 연산한색 R2_MASKPEN 색의반대색펜의색과배경색을 XOR 연산한색 R2_XORPEN 의반대색 [164] R2_NOTXORPEN R G B 배경-흰색 1 1 1 펜-붉은색 1 0 0 XOR 0 1 1 NOT XOR 1 0 0 ( 붉은색 ) 배경-흰색 1 0 0 펜-붉은색 1 0 0 XOR 0 0 0 NOT XOR 1 1 1 ( 흰색 ) [165] 83

OnMouseMove() 핸들러작성 void CSketcherView::OnMouseMove(UINT nflags, CPoint point) // Define a Device Context object for the view CClientDC adc(this); adc.setrop2(r2_notxorpen); // Set the drawing mode if((nflags & MK_LBUTTON) && (this == GetCapture())) m_secondpoint = point; // Save the current cursor position if(m_ptempelement) // Redraw the old element so it disappears from the view m_ptempelement->draw(&adc); delete m_ptempelement; // Delete the old element m_ptempelement = 0; // Reset the pointer to 0 // Create a temporary element of the type and color that // is recorded in the document object, and draw it m_ptempelement = CreateElement(); // Create a new element m_ptempelement->draw(&adc); // Draw the element [166] Element 생성 CElement* CSketcherView::CreateElement() // Get a pointer to the document for this view CSketcherDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); // Verify the pointer is good // Now select the element using the type stored in the document switch(pdoc->getelementtype()) case RECTANGLE: return new CRectangle(m_FirstPoint, m_secondpoint, pdoc- >GetElementColor()); case CIRCLE: return new CCircle(m_FirstPoint, m_secondpoint, pdoc->getelementcolor()); case CURVE: return new CCurve(pDoc->GetElementColor()); case LINE: return new CLine(m_FirstPoint, m_secondpoint, pdoc->getelementcolor()); [167] 84

default: // Something's gone wrong AfxMessageBox("Bad Element code", MB_OK); AfxAbort(); return NULL; class CSketcherDoc : public CDocument protected: // create from serialization only CSketcherDoc(); DECLARE_DYNCREATE(CSketcherDoc) // Attributes public: protected: COLORREF m_color; WORD m_element; // Current drawing color // Current element type // Operations public: WORD GetElementType() const return m_element; COLORREF GetElementColor() const return m_color; // Get the element type // Get the element color [168] WM_LBUTTONUP 메시지처리 void CSketcherView::OnLButtonUp(UINT nflags, CPoint point) if(this == GetCapture()) ReleaseCapture(); // Stop capturing mouse messages // Make sure there is an element if(m_ptempelement) // Call a document class function to store the element // pointed to by m_ptempelement in the document object delete m_ptempelement; // This code is temporary m_ptempelement = 0; // Reset the element pointer [169] 85

마우스메시지포착하기 void CSketcherView::OnLButtonDown(UINT nflags, CPoint point) // TODO: Add your message handler code here and/or call default m_firstpoint = point; // Record the cursor position SetCapture(); // Capture subsequent mouse messages [170] SUMMARY 클라이언트좌표계 CDC 맵핑모드 WM_PAINT -> OnDraw(); InvalidateRect(); 마우스이벤트 SetCapture()/ReleaseCapture() 드로잉모드 [171] 86

Collection Classes Collection Topics The MFC Library provides collection classes to manage groups of objects. These classes are of two types: Collection classes created from C++ templates Collection classes not created from templates [173] 87

Collection Shapes Array The array class provides a dynamically sized, ordered, and integer-indexed array of objects. List The list class provides an ordered, nonindexed list of elements, implemented as a doubly linked list. A list has a head and a tail, and adding or removing elements from the head or tail, or inserting or deleting elements in the middle, is very fast. Map (also known as a dictionary) A map is a collection that associates a key object with a value object. [174] Collection Classes Based on Templates Collection Contents Arrays Lists Maps Collections of objects of any type CArray CList CMap Collections of pointers to objects of any type CTypedPtrArray CTypedPtrList CTypedPtrMap [175] 88

Collection Classes Not Based on Templates Arrays CObArray CByteArray Lists CObList CPtrList Maps CMapPtrToWord CMapPtrToPtr CDWordArray CStringList CMapStringToOb CPtrArray CStringArray CStringArray CMapStringToPtr CMapStringToString CMapWordToOb CUIntArray CMapWordToPtr [176] Choosing a Collection Class The features of the class shape: order, indexing, and performance Whether the class uses C++ templates Whether the elements stored in the collection can be serialized Whether the elements stored in the collection can be dumped for diagnostics Whether the collection is type-safe [177] 89

Collection Shape Features Shape Ordered? Indexed? Insert an element Search for specified element Duplicate elements? Array Yes By int Slow Slow Yes List Yes No Fast Slow Yes Map No By key Fast Fast No (keys) Yes (values) [178] Characteristics of MFC Collection Classes [179] 90

[180] Example: CStringArray CStringArray strarray; strarray.setsize( 3 ); strarray[ 0 ] = " 가 "; strarray[ 1 ] = " 나 "; strarray[ 2 ] = " 다 "; int nsize = strarray.getsize(); // nsize == 3 int nlastindex = strarray.getupperbound(); // nlastindex == 2 strarray.add( " 마 " ); //strarray[ 3 ] = " 마 "; strarray.insertat( 3, " 라 ", 1 ); // 3번째인덱스에삽입, 원래 3번인덱스는 4번이됨. strarray.removeat( 4, 1 ); // 4번째인덱스제거 CStringArray strarray2; strarray2.copy( strarray ); // strarray를 strarray2에복사 strarray.removeall(); // strarray의모든요소를제거 [181] 91

CArray Template 아이콘핸들 (HICON) 을저장하는배열을만들어본다. 1 먼저적당한헤더파일에템플릿을정의한다. typedef CArray < HICON, HICON& > CHiconArray; 2 템플릿을정의한헤더에다음파일을인클루드시킨다. #include <afxtempl.h> // Collection template을위해필요 3 이제객체를선언하고사용하면된다. CHiconArray aryhicon; aryhicon.setsize( 100 );... [182] CMap (Dictionary) CMap<KeyType,KeyType&,ObjectType,ObjectType&> amap; Key1 Key2 Key3 Object1 Object2 Object3 Concept of Hashing HashValue = Key % N (N 은저장공간, 주로소수 ) 엔트리저장주소 = Base+HashValue*Length [183] 92

CList Template Class CList<ObjectType,ObjectType&> alist; 저장될객체의형식 Ex) CList<CPoint,CPoint&> PointList; 객체가 argument 안에서지정되는방법 [184] CPoint apoint; POSITION aposition; PointList.AddTail(aPoint); PointList.InsertBefore(aPosition,aPoint); PointList.InsertAfter(aPosition,aPoint); PointList.SetAt(aPosition,aPoint); PointList.GetNext(aPosition); CList Class Member Functions POSITION : A value used to denote the position of an element in a collection; used by MFC collection classes. [185] 93

CList Iteration Code CPoint CurrentPoint(0,0); // 첫번째리스트요소에대한위치를얻는다. POSITION aposition = PointList.GetHeadPosition(); While(aPosition) //aposition이null이아닌한계속수행 CurrentPoint = PointList.GetNext(aPosition); // 현재객체를처리한다. [186] CList 검색 (Find) POSITION aposition = PointList.Find(aPoint); POSITION Find( ARG_TYPE searchvalue, POSITION startafter = NULL) const; Searches the list sequentially to find the first element matching the specified searchvalue. Note that the pointer values are compared, not the contents of the objects. Calls CompareElements() to compare. [187] 94

CList Find 구현 CompareElements() 함수 Template<class TYPE,class ARG_TYPE> BOOL CompareElements(const TYPE* pelement1, const ARG_TYPE* pelement2); 함수프로토타입 BOOL CompareElements(const Cpoint* ppoint1, const Cpoint* ppoint2) return *ppoint1==*ppoint2 **operator() 에대한연산자오버로딩을구현해야한다. [188] CList 색인 (Indexing) POSITION FindIndex( int nindex ) const; nindex : zero-based index int GetCount() const; Gets the number of elements in this list. [189] 95

CList 객체삭제 RemoveHead(); RemoveTail(); RemoveAt(); RemoveAll(); If(!PointList.IsEmpty()) PointList.RemoveHead(); [190] CList 보조함수 Template<class TYPE> void COnstructElements(TYPE* pelements, int ncount); Template<class TYPE> void DestructElements(TYPE* pelements, int ncount); [191] 96

형식을갖는포인터컬렉션 객체들에대한포인터를저장하는컬렉션 CTypedPtrList<BaseClass, Type*> ListName; CObList : CObject 로부터파생되는객체들의포인터를지원하는리스트 CPtrList : void* 포인터리스트지원 Ex) CTypedPtrList<CObList,Celement*>m_ElementList CObList 또는 CPtrList 중택일 [192] CTypedPtrList Class Member Functions CList 클래스에서제공되는것과비슷하나, 작업이객체가아닌객체에대한포인터에대해서실행된다. [193] 97

View 향상하기 CDocument::UpdateAllViews void UpdateAllViews (CView* psender, LPARAM lhint = 0L, CObject* phint =NULL); psender Points to the view that modified the document, or NULL if all views are to be updated. lhint Contains information about the modification. phint Points to an object storing information about the modification. GetDocument()-> UpdateAllViews(0,0,m_pTempElement); [195] 98

CView::OnUpdate virtual void OnUpdate (CView* psender, LPARAM lhint, CObject* phint );. psender Points to the view that modified the document, or NULL if all views are to be updated. lhint Contains information about the modification. phint Points to an object storing information about the modification. [196] Sample Code Void CSketcherView::OnUpdate(CView* psender, LPARAM lhint, Cobject* phint) If(pHint) InvalidateRect(static_cast<Celement*> (phint)->getboundrect()); else InvalidateRect(0); [197] 99

View Scroll 수정할부분 class CSketcherView : public CScrollView IMPLEMENT_DYNCREATE(CSketcherView,CScrollView) BEGIN_MESSAGE_MAP(CSketcherView,CScrollView) void CSketcherView::OnInitialUpdate() CScrollView::OnInitialUpdate(); Csize DocSize(20000,20000); // 도큐먼트크기정의 SetScrollSizes(MM_TEXT,DocSize); // 매핑모드와도큐먼트크기 [198] CScrollView::SetScrollSizes void SetScrollSizes( int nmapmode, SIZE sizetotal, const SIZE& sizepage = sizedefault, const SIZE& sizeline = sizedefault ); sizetotal The total size of the scroll view. The cx member contains the horizontal extent. The cy member contains the vertical extent. Sizes are in logical units. Both cx and cy must be greater than or equal to 0. sizepage The horizontal and vertical amounts to scroll in each direction in response to a mouse click in a scroll-bar shaft. The cx member contains the horizontal amount. The cy member contains the vertical amount. sizeline The horizontal and vertical amounts to scroll in each direction in response to a mouse click in a scroll arrow. The cx member contains the horizontal amount. The cy member contains the vertical amount. [199] 100

논리좌표와장치좌표 p.915 참조 디바이스컨텍스트 : 논리좌표윈도우와의통신 : 장치좌표 [200] CScrollView::OnPrepareDC To adjust the viewport origin for the scrolling window, CScrollView overrides CView::OnPrepareDC. This adjustment is automatic for the CPaintDC device context that CScrollView passes to OnDraw, but you must call CScrollView::OnPrepareDC yourself for any other device contexts you use, such as a CClientDC. You can override CScrollView::OnPrepareDC to set the pen, background color, and other drawing attributes, but call the base class to do scaling. [201] 101

Sample Code(1/3) void CSketcherView::OnLButtonDown(UINT nflags, CPoint point) CClientDC adc(this); //DC 생성 OnPrepareDC(&aDC); // 원점조정 adc.dptolp(&point); // 논리좌표로변환 m_firstpoint = point; SetCapture(); [202] Sample Code(2/3) Void CSketcherView::OnMouseMove(UINT nflags, Cpoint point) CClientDC adc(this); OnPrepareDC(&aDC); if((nflags & MK_LBUTTON)&&(this==GetCapture())) adc.dptolp(&point); m_secondpoint = point; [203] 102

Sample Code(3/3) void CSketcherView::OnUpdate(CView* psender,lparam lhint, Cobject* phint) if(phint) CClientDC adc(this); OnPrepareDC(&aDC); // 둘러싸는직사각형을얻고, 장치좌표로변환한다. CRect arect = static_cast<celement*>(phint)->getboundrect(); adc.lptodp(arect); InvalidateRect(aRect); else InvalidateRect(0); [204] adc.dptolp(&point) adc.lptodp(arect) CRect::operator LPRECT Use this operator to convert a CRect object to an LPRECT. When you use this function, you don't need the address-of (&) operator. This operator will be automatically used when you pass a CRect object to a function that expects an LPRECT. void LPtoDP( LPRECT lprect ) const; void DPtoLP( LPRECT lprect ) const; [205] 103

MM_LOENGLISH 맵핑모드 void CSketcherView::OnInitialUpdate() CScrollView::OnInitialUpdate(); // 도큐먼트크기를 MM_LOENGLISH 에서 30*30 인치로정의 Csize DocSize(3000,3000); SetScrollSizes(MM_LOENGLISH,DocSize); [206] Popup Menu [207] 104

Sample Code Void CSketcherView::OnRButtonUp(UINT nflags, CPoint point) CMenu amenu; amenu.loadmenu(idr_cursor_menu); ClientToScreen(&point); // 화면좌표로변환 // 팝업을커서위치에나타낸다. amenu.getsubmenu(0)-> TrackPopupMenu(TPM_LEFTALIGN TPM_RIGHTBUTTON, point.x, point.y, this); [208] 논리좌표 좌표계 화면좌표 클라이언트좌표장치좌표 [209] 105

좌표계변환 화면 <-> 클라이언트 ScreenToClient(&point); ClientToScreen(&point); 논리 <-> 장치 LPtoDP(&point); DPtoLP(&point); [210] Popup Menu 검사 UINT CheckMenuItem(UINT nidcheckitem, UINT ncheck); 두번째파라미터 ( 어떻게체크될항목을지정하는가 ) MF_BYCOMMAND : 메뉴 ID로서선택 MF_BYPOSITION : 메뉴항목의순서로선택 사용예 > amenu.checkmenuitem(id_color_black,(black==color? MF_CHECKED : MF_UNCHECKED) MF_BYCOMMAND); amenu.checkmenuitem(id_element_line,(line==elementtype? MF_CHECKED : MF_UNCHECKED) MF_BYCOMMAND); [211] 106

대화상자와컨트롤사용하기 강의내용 대화상자리소스생성컨트롤을대화상자에추가하는방법컨트롤의기본적인종류대화상자클래스생성하는방법대화상자생성프로그램작성법 Modal/modeless 대화상자직접적인데이터교환과검증을구현하고사용하는방법 [213] 107

대화상자?? [214] 컨트롤?? Static control Button control Scroll Bar List Box Edit box Combo box [215] 108

대화상자리소스생성 [216] 컨트롤대화상자에추가 [217] 109

대화상자클래스추가하기 대화상자프로그래밍 [218] class CPenDialog : public CDialog // Construction public: CPenDialog(CWnd* pparent = NULL); // standard constructor // Dialog Data //AFX_DATA(CPenDialog) enum IDD = IDD_PENWIDTH_DLG ; // NOTE: the ClassWizard will add data members here //AFX_DATA ; [219] 110

Modal/modeless 대화상자 Modal : 대화상자가닫힐때까지응용프로그램의다른윈도우의작업을할수없다. Modeless : 응용프로그램안에있는다른윈도우의작업을할수있다. [220] 대화상자나타내기 void CSketcherDoc::OnPenwidth() CPenDialog adlg; // Create a local dialog object // Display the dialog as modal adlg.domodal() [221] 111

컨트롤초기화하기 BOOL CPenDialog::OnInitDialog() CDialog::OnInitDialog(); // Check the radio button corresponding to the pen width switch(m_penwidth) case 1: CheckDlgButton(IDC_PENWIDTH1,1); break; case 2: CheckDlgButton(IDC_PENWIDTH2,1); break; case 3: CheckDlgButton(IDC_PENWIDTH3,1); break; [222] case 4: CheckDlgButton(IDC_PENWIDTH4,1); break; case 5: CheckDlgButton(IDC_PENWIDTH5,1); break; default: CheckDlgButton(IDC_PENWIDTH0,1); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE [223] 112

라디오버튼메시지처리 ClassWizard 에서메시지핸들러생성 void CPenDialog::OnPenwidth0() m_penwidth = 0; [224] 대화상자작업작성하기 void CSketcherDoc::OnPenwidth() CPenDialog adlg; // Create a local dialog object // Set the pen width in the dialog to that stored in the document adlg.m_penwidth = m_penwidth; // Display the dialog as modal // When closed with OK, get the pen width if(adlg.domodal() == IDOK) m_penwidth = adlg.m_penwidth; [225] 113

펜의두께도큐먼트에추가 Sketcher.h에다음을정의 int m_penwidth; int GetPenWidth() const return m_penwidth; Sketcher.cpp에초기화 m_penwidth = 0; [226] 펜의폭을요소에추가 CRect CElement::GetBoundRect() const CRect BoundingRect; // Object to store bounding rectangle BoundingRect = m_enclosingrect; // Store the enclosing rectangle // Increase the rectangle by the pen width int Offset = m_pen == 0? 1:m_Pen; // Width must be at least 1 BoundingRect.InflateRect(Offset, Offset); return BoundingRect; [227] 114

CLine::CLine(const CPoint& Start, const CPoint& End, const COLORREF& Color, const int& PenWidth) m_startpoint = Start; // Set line start point m_endpoint = End; // Set line end point m_color = Color; // Set line color m_pen = PenWidth; // Set pen width // Define the enclosing rectangle m_enclosingrect = CRect(Start, End); m_enclosingrect.normalizerect(); [228] 뷰안에서요소생성 CElement* CSketcherView::CreateElement() // Get a pointer to the document for this view CSketcherDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); // Verify the pointer is good // Now select the element using the type stored in the document switch(pdoc->getelementtype()) case RECTANGLE: return new CRectangle(m_FirstPoint, m_secondpoint, pdoc->getelementcolor(), pdoc->getpenwidth()); case CIRCLE: return new CCircle(m_FirstPoint, m_secondpoint, pdoc->getelementcolor(), pdoc->getpenwidth()); [229] 115

case CURVE: return new CCurve(m_FirstPoint, m_secondpoint, pdoc->getelementcolor(), pdoc->getpenwidth()); case LINE: // Always default to a line return new CLine(m_FirstPoint, m_secondpoint, pdoc->getelementcolor(), pdoc->getpenwidth()); default: // Something's gone wrong AfxMessageBox("Bad Element code", MB_OK); AfxAbort(); return NULL; [230] DDX/DDV [231] 116

DDX/DDV 사용시 [232] 데이타맵 class CZoomDlg : public CDialog... // Dialog Data //AFX_DATA(CZoomDlg) enum IDD = IDD_ZOOMDLG ; CSpinButtonCtrl m_spinzoom; UINT m_editzoom; //AFX_DATA... ; [233] 117

DoDataExchange void CZoomDlg::DoDataExchange(CDataExchange* pdx) CDialog::DoDataExchange(pDX); //AFX_DATA_MAP(CZoomDlg) DDX_Control(pDX, IDC_SPINZOOM, m_spinzoom); DDX_Text(pDX, IDC_EDITZOOM, m_editzoom); DDX_MinMaxUInt(pDX, m_editzoom, 10, 800); //AFX_DATA_MAP 다이얼로그박스호출전에값을설정 OnInitDialog 에서컨트롤의값을설정한다. CDialog 클래스의데이타맵에있는변수 다이얼로그박스의실행이정상적으로끝나면값을읽어온다. OnOK 에서컨트롤의값을읽어온다. [234] DDX/DDV 매크로 DDX_CBIndex, DDX_CBString, DDX_CBStringExact 콤보박스관련 DDX_LBIndex, DDX_LBString, DDX_LBStringExact 리스트박스관련 DDX_Check 체크박스관련 DDX_Radio 라디오박스관련 DDX_Scroll 스크롤바관련 DDX_Text DDX_Control 에디트콘트롤관련 [235] 118

스핀버튼컨트롤사용하기 스케일메뉴항목과툴바버튼추가스핀버튼생성스케일대화상자클래스생성대화상자데이터교환과대화상자데이터검증 void CScaleDialog::DoDataExchange(CDataExchange* pdx) CDialog::DoDataExchange(pDX); //AFX_DATA_MAP(CScaleDialog) DDX_TEXT(pDX,IDC_SCALE,m_SCALE); DDV_MinMaxInt(pDX,m_Scale,1,8); //AFX_DATA_MAP [236] 대화상자초기화하기 BOOL CScaleDialog::OnInitDialog() CDialog::OnInitDialog(); //spin control 에대한포인터를먼저얻는다. CSpinButtonCtrl* pspin; pspin(cspinbuttonctrl*)getdlgitem(idc_spin_scale); //spin control 의속성안에있는 auto buddy 옵션을체크하지않았다면 // 여기에서 buddy control 을설정한다. //spin control 범위를설정한다. pspin->setrange(1,8); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE [237] 119

스핀버튼나타내기 void CSketcherView::OnViewScale() CScaleDialog adlg; // Create a dialog object adlg.m_scale = m_scale; // Pass the view scale to the dialog if(adlg.domodal() == IDOK) m_scale = adlg.m_scale; // Get the new scale InvalidateRect(0); // Invalidate the whole window [238] Scale factor 사용하기 Scale 할수있는맵핑모드파라미터설명 Window Origin 윈도우의왼쪽상단의논리좌표. CDC::SetWindowOrg() 호출하여설정 Window Extent 논리좌표안에지정되어있는윈도우크기. CDC::SetWindowExt() 호출하여설정 Viewport Origin 장치좌표 ( 픽셀 ) 로되어있는윈도우왼쪽상단의좌표. CDC::SetViewportOrg() 호출하여설정 Viewport Extent 장치좌표 ( 픽셀 ) 단위의윈도우크기. CDC::SetViewportExt() 호출하여설정 [239] 120

도큐먼트크기설정 CSketcherDoc::CSketcherDoc() // TODO: add one-time construction code here m_element = LINE; // Set initial element type m_color = BLACK; // Set initial drawing color m_penwidth = 0; // Set 1 pixel pen m_docsize = CSize(3000,3000); // Set initial document //size 30x30 inches [240] 맵핑모드설정 void CSketcherView::OnPrepareDC(CDC* pdc, CPrintInfo* pinfo) CScrollView::OnPrepareDC(pDC, pinfo); CSketcherDoc* pdoc = GetDocument(); pdc->setmapmode(mm_anisotropic); // Set the map mode CSize DocSize = pdoc->getdocsize(); // Get the document size // y extent must be negative because we want MM_LOENGLISH DocSize.cy = -DocSize.cy; // Change sign of y pdc->setwindowext(docsize); // Now set the window extent [241] 121

// Get the number of pixels per inch in x and y int xlogpixels = pdc->getdevicecaps(logpixelsx); int ylogpixels = pdc->getdevicecaps(logpixelsy); // Calculate the viewport extent in x and y int xextent = DocSize.cx * m_scale * xlogpixels / 100; int yextent = DocSize.cy * m_scale * ylogpixels / 100; pdc->setviewportext(xextent, -yextent); // Set viewport extent void CSketcherView::ResetScrollSizes() CClientDC adc(this); OnPrepareDC(&aDC); // Set up the device context CSize DocSize = GetDocument()->GetDocSize(); // Get the document size adc.lptodp(&docsize); // Get the size in pixels SetScrollSizes(MM_TEXT, DocSize); // Set up the scrollbars [242] 스케일기능을사용하여스크롤기능향상 void CSketcherView::ResetScrollSizes() CClientDC adc(this); OnPrepareDC(&aDC); // Set up the device context CSize DocSize = GetDocument()->GetDocSize(); // Get the document size adc.lptodp(&docsize); // Get the size in pixels SetScrollSizes(MM_TEXT, DocSize); // Set up the scrollbars [243] 122

스크롤바설정하기 void CSketcherView::OnInitialUpdate() ResetScrollSizes(); // Set up the scrollbars CScrollView::OnInitialUpdate(); CSketcherView::CSketcherView() // TODO: add construction code here m_movemode = FALSE; // Set move mode off m_cursorpos = CPoint(0,0); // Initialize as zero m_firstpos = CPoint(0,0); // Initialize as zero m_scale = 1; // Set scale to 1:1 SetScrollSizes(MM_TEXT, CSize(0,0));// Set arbitrary scrollers [244] void CSketcherView::OnViewScale() CScaleDialog adlg; // Create a dialog object adlg.m_scale = m_scale; // Pass the view scale to the dialog if(adlg.domodal() == IDOK) m_scale = adlg.m_scale; // Get the new scale ResetScrollSizes(); // Adjust scrolling to the new scale InvalidateRect(0); // Invalidate the whole window [245] 123

상태바생성하기 CMainFrame 의 m_wndstatusbar 멤버에접근예제 : CMainFrame* pframe=(cmainframe*)afxgetapp()->m_pmainwnd; pframe->setpanetext(0, Goodbye cruel world ); 상태바프레임에추가 CChildFrame에다음을정의, CStatusBar m_statusbar; [246] int CChildFrame::OnCreate(LPCREATESTRUCT lpcreatestruct) if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1) return -1; // Create the status bar m_statusbar.create(this); // Work out the width of the text we want to display CRect textrect; CClientDC adc(&m_statusbar); adc.selectobject(m_statusbar.getfont()); adc.drawtext("view Scale:99", -1, textrect, DT_SINGLELINE DT_CALCRECT); // Setup a part big enough to take the text int width = textrect.width(); m_statusbar.getstatusbarctrl().setparts(1, &width); // Initialize the text for the status bar m_statusbar.getstatusbarctrl().settext("view Scale:1", 0, 0); return 0; [247] 124

상태바의부분들정의 M_StatusBar.GetStatusBarCtrl().SetParts(1,&width); CStatusBarCtrl 의 SetText() 멤버에의해초기텍스트설정 SetText() 의세번째파라미터스타일코드모습 0 상태바안에파묻혀잇는것처럼보이는경계선을가진다. SBT_NOBORDERS 경계선이없이그려진다. SBT_OWNERDRAW 부모윈도우에의해그려진다. SBT_POPOUT 상태바에서튀어나와있는것처럼보인다. [248] 상태바업데이트 void CSketcherView::OnViewScale() CScaleDialog adlg; // Create a dialog object adlg.m_scale = m_scale; // Pass the view scale to the dialog if(adlg.domodal() == IDOK) m_scale = adlg.m_scale; // Get the new scale // Get the frame window for this view CChildFrame* viewframe = static_cast<cchildframe*>(getparentframe()); // Build the message string CString StatusMsg("View Scale:"); StatusMsg += static_cast<char>('0' + m_scale); // Write the string to the status bar viewframe->m_statusbar.getstatusbarctrl().settext(statusmsg, 0, 0); ResetScrollSizes(); InvalidateRect(0); // Adjust scrolling to the new scale // Invalidate the whole window [249] 125

리스트박스사용하기 스케일대화상자삭제 대화상자파일 (.h,.cpp) 삭제 ID삭제를위해 View Resource Symbols.. 사용 ClassWizard 에서 remove Build Clean File Close Workspace.. [250] 리스트박스컨트롤생성 [251] 126

대화상자클래스생성 ClassWizard 에서 SCaleDialog 로명명 Member Variable 탭에서 m_scale 멤버변수를해당리스트박스 ID인 IDC_SCALELIST에추가 BOOL CScaleDialog::OnInitDialog() CDialog::OnInitDialog(); CListBox* plistbox = static_cast<clistbox*>(getdlgitem(idc_scalelist)); plistbox->addstring("scale 1"); plistbox->addstring("scale 2"); plistbox->addstring("scale 3"); plistbox->addstring("scale 4"); plistbox->addstring("scale 5"); plistbox->addstring("scale 6"); plistbox->addstring("scale 7"); plistbox->addstring("scale 8"); plistbox->setcursel(m_scale - 1); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE [252] 대화상자나타내기 void CSketcherView::OnViewScale() CScaleDialog adlg; // Create a dialog object adlg.m_scale = m_scale; // Pass the view scale to the dialog if(adlg.domodal() == IDOK) m_scale = 1 + adlg.m_scale; // Get the new scale // Get the frame window for this view CChildFrame* viewframe = static_cast<cchildframe*>(getparentframe()); // Build the message string CString StatusMsg("View Scale:"); StatusMsg += static_cast<char>('0' + m_scale); // Write the string to the status bar viewframe->m_statusbar.getstatusbarctrl().settext(statusmsg, 0, 0); ResetScrollSizes(); InvalidateRect(0); // Adjust scrolling to the new scale // Invalidate the whole window [253] 127

편집박스컨트롤사용하기 대화상자리소스와그것과연계된클래스생성새로운메뉴항목추가요소를생성할대화상자를여는코드를추가 CText 클래스를지원하는코드추가 [254] 편집박스리소스생성 [255] 128

대화상자클래스생성 [256] Cstring 클래스 연산자사용법 = 하나의문자열을다른것으로복사 Str1=Str2; //Str1의내용을 Str2로복사 Str1= A normal String // 문자열을 Str1에복사 + 두개이상의문자열을연결 Str1=Str2+Str3+ more ; //3개의문자열로부터 Str1생성 += 문자열을기본의 Cstring 객체에추가 == 두개의문자열이동일한가비교 if(str1==str2) // 어떤비교 < <= 작거나혹은작거나같은가검사 > >= 크거나혹은크거나같은가검사 [257] 129