Programming hwp

Similar documents
Programming hwp

<4D F736F F F696E74202D203031C0E520C0A9B5B5BFEC20C7C1B7CEB1D7B7A1B9D620B1E2C3CA5FBFB5B3B2C0CCB0F8B4EB205BC8A3C8AF20B8F0B5E55D>

Programming hwp

윈도우시스템프로그래밍

윈도우 프로그래밍의 개념

PowerPoint Presentation

Microsoft PowerPoint - hci2-lecture5-messagemap.ppt

5장 MFC기반 다지기

PowerPoint Template

MFC 프로그래밍

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

<4D F736F F F696E74202D203038C0E520C7A5C1D820C4C1C6AEB7D1205BC8A3C8AF20B8F0B5E55D>

윈도우시스템프로그래밍

PowerPoint Presentation

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

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

PowerPoint 프레젠테이션

C++ Programming

<4D F736F F F696E74202D20C1A63034B0AD202D20C7C1B7B9C0D3B8AEBDBAB3CABFCD20B9ABB9F6C6DBC0D4B7C2>

Visual Basic 반복문

Microsoft PowerPoint UI-Event.Notification(1.5h).pptx

var answer = confirm(" 확인이나취소를누르세요."); // 확인창은사용자의의사를묻는데사용합니다. if(answer == true){ document.write(" 확인을눌렀습니다."); else { document.write(" 취소를눌렀습니다.");

슬라이드 1

Design Issues

슬라이드 1

설계란 무엇인가?

윈도우즈 프로그래밍

슬라이드 1

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

Microsoft PowerPoint - ch07 - 포인터 pm0415

Programming hwp

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

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

歯Lecture2.PDF

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

어댑터뷰

04장 메시지 처리 유형

K&R2 Reference Manual 번역본

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

<4D F736F F F696E74202D2036C0CFC2B05FB0B4C3BCC1F6C7E2C7C1B7CEB1D7B7A1B9D62E707074>

UI TASK & KEY EVENT

12 강. 문자출력 Direct3D 에서는문자를출력하기위해서 LPD3DXFONT 객체를사용한다 LPD3DXFONT 객체생성과초기화 LPD3DXFONT 객체를생성하고초기화하는함수로 D3DXCreateFont() 가있다. HRESULT D3DXCreateFont

Microsoft PowerPoint - Chapter 6.ppt

Microsoft PowerPoint - C++ 5 .pptx

PowerPoint Presentation

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

Microsoft PowerPoint - hci2-lecture1.ppt

PowerPoint 프레젠테이션

학습목표 함수프로시저, 서브프로시저의의미를안다. 매개변수전달방식을학습한다. 함수를이용한프로그래밍한다. 2

제8장 자바 GUI 프로그래밍 II

오버라이딩 (Overriding)

Microsoft PowerPoint - 09-CE-14-리스트콤보박스

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

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

. 스레드 (Thread) 란? 스레드를설명하기전에이글에서언급되는용어들에대하여알아보도록하겠습니다. - 응용프로그램 ( Application ) 사용자에게특정서비스를제공할목적으로구현된응용프로그램을말합니다. - 컴포넌트 ( component ) 어플리케이션을구성하는기능별요

PowerPoint Presentation

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

PowerPoint Template

Visual C++의 개요

Microsoft PowerPoint - CSharp-10-예외처리

<4D F736F F F696E74202D B3E22032C7D0B1E220C0A9B5B5BFECB0D4C0D3C7C1B7CEB1D7B7A1B9D620C1A638B0AD202D20C7C1B7B9C0D320BCD3B5B5C0C720C1B6C0FD>

ThisJava ..

gnu-lee-oop-kor-lec10-1-chap10

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

윈도우시스템프로그래밍

PowerPoint 프레젠테이션

Modern Javascript

11장 포인터

Microsoft PowerPoint - hci2-lecture8.ppt

쉽게 풀어쓴 C 프로그래밍

슬라이드 1

UI TASK & KEY EVENT

제11장 프로세스와 쓰레드

제이쿼리 (JQuery) 정의 자바스크립트함수를쉽게사용하기위해만든자바스크립트라이브러리. 웹페이지를즉석에서변경하는기능에특화된자바스크립트라이브러리. 사용법 $( 제이쿼리객체 ) 혹은 $( 엘리먼트 ) 참고 ) $() 이기호를제이쿼리래퍼라고한다. 즉, 제이쿼리를호출하는기호

17장 클래스와 메소드

Microsoft PowerPoint - chap06-2pointer.ppt

쉽게 풀어쓴 C 프로그래밍

<33372DC0A9B5B5BFECC7C1B7CEB1D7B7A1B9D62E687770>

윈도우시스템프로그래밍

금오공대 컴퓨터공학전공 강의자료

예제 2) Test.java class A intvar= 10; void method() class B extends A intvar= 20; 1"); void method() 2"); void method1() public class Test 3"); args) A

슬라이드 1

슬라이드 1

슬라이드 1

윈도우 프로그래밍의 개념

Microsoft PowerPoint - hci2-lecture8.ppt

Microsoft PowerPoint - additional01.ppt [호환 모드]

JUNIT 실습및발표

PowerPoint 프레젠테이션

Microsoft PowerPoint - 09-Object Oriented Programming-3.pptx

(Microsoft PowerPoint - 07\300\345.ppt [\310\243\310\257 \270\360\265\345])

Microsoft PowerPoint - hci2-lecture1.ppt

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

<4D F736F F F696E74202D203036C0E520BBE7BFEBC0DA20C0CEC5CDC6E4C0CCBDBA205BC8A3C8AF20B8F0B5E55D>

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

윈도우 프로그래밍의 개념

Microsoft PowerPoint - e pptx

Microsoft PowerPoint - additional06.ppt [호환 모드]

Microsoft PowerPoint - ÀÚ¹Ù08Àå-1.ppt

Transcription:

CHelloWindow::CHelloWindow() { CRect r; // Create the window itself Create(NULL, _T("CStatic Tests"), WS_OVERLAPPEDWINDOW, CRect(0, 0, 300, 200)); // Get the size of the client rectangle GetClientRect(&r); r.inflaterect(-40, -20); // Create a static label cs = new CStatic(); cs->create(_t("hello World"), WS_CHILD WS_VISIBLE WS_BORDER SS_CENTER, r, this); // Create a new 36 point Arial font CFont *font = new CFont(); font->createfont(36, 0, 0, 0, 700, 0, 0, 0, ANSI_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH FF_DONTCARE, _T("Arial")); // Cause the label to use the new font cs->setfont(font); 3.5 메시지맵 (message map) 응용프로그램에서창안에배치한사용자인터페이스요소는두가지제어가능한특성을갖는데, 이들은외관과이벤트반응동작이다. 4절에서 CStatic 컨트롤의예를통해사용자인터페이스요소의외관을조정하기위해스타일속성을이용한다는것을살펴보았다. 이러한방식은 MFC 안의모든컨트롤클래스들에적용된다. 이절에서는메시지맵과간단한이벤트처리의이해에도움을주기위해먼저 CButton 컨트롤을살펴본다. 또컨트롤이아니라창자체에서발생하는이벤트들에대한처리방법도알아본다. 그런다음조금더복잡한예로 CScrollBar 컨트롤의경우를알아볼것이다. - 87 -

메시지맵이해하기 3절에서알아본것처럼 MFC 프로그램들에서 main() 함수나이벤트루프가드러나있지않다. 모든이벤트처리가 CWinApp 클래스안에숨겨진 C++ 코드들에의해수행된다. 운영체제로부터전달되어온이벤트들의큐에서이벤트들을하나씩차례로꺼내살펴보는이벤트루프가숨겨져있기때문에, 이벤트루프에서응용프로그램에의미있는이벤트들이나타났을때이벤트루프가이사실을프로그램에전달할수있는방법이필요하며, 바로메시지맵이이를위한메커니즘이다. 메시지맵은어떤이벤트가프로그램에의미있는이벤트인지, 또이러한이벤트들에반응하여호출될함수가무엇인지등을표시한다. 예를들어사용자가 "Quit" 이라는레이블을갖는버튼을누를때마다종료되는프로그램을작성한다고하자. 이를위해먼저적절한레이블을갖는버튼을생성할것이다. 그다음에버튼컨트롤의부모창에해당하는클래스안에메시지맵을만든다. 이는사용자가버튼컨트롤을클릭할때마다버튼은그부모창을나타내는객체에메시지를전달하기때문이다. 부모창을위한메시지맵을만들어줌으로써버튼에서발생하는메시지를가로채어이용할수있는메커니즘이확립된다. 메시지맵은그버튼에특정이벤트가발생했을때 MFC로하여금특정함수를호출하게만든다. 이경우 "Quit" 버튼에대한클릭이의미있는이벤트이며, 이의처리를위해지정된함수안에응용프로그램종료를위한코드를넣어주어야할것이다. 메시지맵의작성과이벤트처리함수를정의하는것이외의나머지작업들은모두 MFC가처리해준다. 사용자가 "Quit" 버튼을클릭하면, 버튼경계선안쪽에점선모양이생기며버튼에강조효과가발생하며, 자동적으로 "Quit" 버튼클릭에연계된함수가호출되고프로그램이종료될것이다. 간단한코드의추가로이와같이사용자이벤트에반응할수있는프로그램이만들어진다. CButton 클래스 CStatic 컨트롤은사용자이벤트에반응하지않는유일한컨트롤이다. CStatic 컨트롤을아무리많이클릭하더라도묵묵부답의상태가유지될것이다. 그러나 CStatic 컨트롤을제외한나머지컨트롤들은모두사용자이벤트에대해두가지로반응한다. 첫째, 사용자가해당컨트롤을건드리면컨트롤의외관에약간의변화가생긴다. 둘째, 각컨트롤은프로그램이필요한반응을할수있도록코드에게메시지를보내고자시도한다. 이러한절차를알아보기위해먼저 CButton 컨트롤을포함하는간단한예제프로그램을살펴보자. 이프로그램은 CStatic 컨트롤대신 CButton 컨트롤을사용한다는점을제외하면 3절의예제와유사하다. 이프로그램은메시지맵을사용하지않고있으며따라서버튼이벤트처리함수도정의되어있지않다. 그러나버튼을클릭했을때외관변화는일어나며, 따라서컨트롤의기본적인외관변화는 MFC에의해자체적으로수행된다는것을알수있다. // button1.cpp #include <afxwin.h> - 88 -

#define IDC_BUTTON 100 // Declare the application class class CButtonApp : public CWinApp { virtual BOOL InitInstance(); ; // Create an instance of the application class CButtonApp ButtonApp; // Declare the main window class class CButtonWindow : public CFrameWnd { CButton *button; CButtonWindow(); ; // The InitInstance function is called once // when the application first executes BOOL CButtonApp::InitInstance() { m_pmainwnd = new CButtonWindow(); m_pmainwnd->showwindow(m_ncmdshow); m_pmainwnd->updatewindow(); return TRUE; // The constructor for the window class CButtonWindow::CButtonWindow() { // Create the window itself Create(NULL, _T("CButton Tests"), WS_OVERLAPPEDWINDOW, CRect(0, 0, 300, 200)); // Get the size of the client rectangle CRect r; GetClientRect(&r); r.inflaterect(-20, -20); - 89 -

// Create a button button = new CButton(); button->create(_t("push me"), WS_CHILD WS_VISIBLE BS_PUSHBUTTON, r, this, IDC_BUTTON); CButton 클래스의 Create() 함수에서다섯번째파라미터는해당버튼컨트롤에부여된고유번호를나타내는데, 문맥에따라컨트롤 ID 또는객체 ID 등으로불린다. CStatic의경우에도이파라미터가있지만디폴트인수가 -1로정해져있고쓰임새가없어잘사용하지않지만, 다른컨트롤들에서는메시지맵에서컨트롤을식별하는중요한역할을한다. 컨트롤 ID로는 100 이상의값을사용하며, 컨트롤마다다른번호를부여해야한다. 99 이하의값은시스템이리소스 ID 값으로예약해두고있다. 다른용도로이예제에서는숫자를직접사용하는대신 IDC_BUTTON이라는심볼상수를정의하여쓰고있다. 심볼앞부분의 "IDC_" 는컨트롤을위한 ID임을의미한다. CButton 클래스를위한스타일파라미터도 CStatic 클래스의경우와차이가있는데, BS_PUSHBUTTON( 일반버튼 ), BS_AUTORADIOBUTTON( 라디오버튼 ), BS_AUTOCHECKBOX ( 체크박스 ), BS_AUTO3STATE( 체크박스에부분체크상태추가 ), BS_LEFTTEXT 등을포함하는 11개의 "BS" ("Button Style") 스타일상수들이사용될수있다. 메시지맵의작성 아래의코드는앞의코드에버튼클릭처리를위한메시지맵과처리함수를추가한것이다. // button2.cpp #include <afxwin.h> #define IDC_BUTTON 100 // Declare the application class class CButtonApp : public CWinApp { virtual BOOL InitInstance(); ; // Create an instance of the application class CButtonApp ButtonApp; - 90 -

// Declare the main window class class CButtonWindow : public CFrameWnd { CButton *button; CButtonWindow(); afx_msg void HandleButton(); DECLARE_MESSAGE_MAP() ; // The message handler function void CButtonWindow::HandleButton() { MessageBeep(-1); // The message map BEGIN_MESSAGE_MAP(CButtonWindow, CFrameWnd) ON_BN_CLICKED(IDC_BUTTON, HandleButton) END_MESSAGE_MAP() // The InitInstance function is called once // when the application first executes BOOL CButtonApp::InitInstance() { m_pmainwnd = new CButtonWindow(); m_pmainwnd->showwindow(m_ncmdshow); m_pmainwnd->updatewindow(); return TRUE; // The constructor for the window class CButtonWindow::CButtonWindow() { // Create the window itself Create(NULL, _T("CButton Tests"), WS_OVERLAPPEDWINDOW, CRect(0, 0, 300, 200)); // Get the size of the client rectangle CRect r; GetClientRect(&r); r.inflaterect(-20, -20); - 91 -

// Create a button button = new CButton(); button->create(_t("push me"), WS_CHILD WS_VISIBLE BS_PUSHBUTTON, r, this, IDC_BUTTON); 위의코드에는이전의코드에다음과같은세가지사항이추가되어있다. CButtonWindow 클래스선언에는새로운멤버함수하나와 DECLARE_MESSAGE_MAP 마크로가포함되어있다. DECLARE_MESSAGE_MAP 마크로는이클래스를위한메시지맵이정의되어있음을표시한다. 멤버함수 HandleButton() 는앞에수식어 afx_msg를갖고있는데, 이함수가메시지처리기 ( 이벤트처리기, 이벤트처리함수 ) 임을나타낸다. 이함수와마크로모두 public으로선언되어야한다. HandleButton() 함수는일반멤버함수와동일한방식으로정의된다. 이함수안에는경고음을만들어내는윈도우 API 함수 MessageBeep() 의호출이들어있다. 이함수의파라미터로 -1( 표준경고음 ), MB_ICONASTERISK, MB_ICONEXCLAMATION, MB_ICONQUESTION, MB_ICONHAND, MB_OK 등을사용할수있다. 메시지맵을정의하는마크로들이들어있다. 메시지맵은 BEGIN_MESSAGE_MAP 마크로로시작하여되는데, END_MESSAGE_MAP 마크로로끝난다. BEGIN_MESSAGE_MAP 마크로는두개의파라미터를취한다. 첫번째파라미터는메시지맵이적용되는클래스이름을나타내는데, 해당메시지는이클래스의인스턴스인객체에게전달될것이며메시지를처리하는처리기함수도이클래스안에정의되어있다. 두번째파라미터는첫번째파라미터가나타내는클래스의부모클래스를나타내며, 현재의클래스에서처리되지않는부분은부모클래스로처리가넘겨진다. 이마크로들사이에 ON_BN_CLICKED 마크로가나타나는데, 이마크로는두개의파라미터를취한다. 첫번째마크로는메시지를발생시키는컨트롤의 ID를나타내며, 두번째파라미터는이메시지에대한처리기함수의이름을나타낸다. Visual Studio 도움말에서위의마크로들에대한형식과설명을찾을수있다. "ON_" 으로시작하는메시지마크로마다파라미터가다르며, 처리기함수의프로토타입이정해져있다. ON_BN_CLICKED 마크로의경우처리기함수는파라미터를취하지않으며, 리턴타입도 void로선언되어있다. 버튼을클릭하면명령 (COMMAND) 메시지가발생하여버튼창의부모창인주실행창에게전달된다. 명령메시지는메시지발생객체의리소스 ID를포함한다. 자식창들에서발생하는 - 92 -

메시지는원래부모창에게전달되도록되어있다. 부모창을나타내는 CButtonWindow 클래스에서는메시지맵을사용하여이메시지를처리할함수가 HandleButton() 임을결정할수있으며, 따라서버튼이클릭될때마다 HandleButton() 함수가실행되어경고음을내게된다. ON_BN_CLICKED 마크로이름중 "BN" 은 Button Notify( 버튼으로부터의통지 ) 를나타내며, CWnd 클래스의 ON_COMMAND 마크로와동등하며, 이에대한별칭으로생각해도좋다. WM_SIZE 메시지 위의예제에서는주실행창안의자식창인버튼에서발생된메시지를주실행창에서받아처리하였다. 창들은또한자신에게보내는메시지들을발생시키는데, 이러한메시지들은 Window Message를의미하는 "WM_" 으로시작한다. 이런메시지의종류는 100개도넘는다. 여기서는 WM_SIZE 메시지에대해알아보고, 다음에 WM_TIMER 메시지에대해알아본다. 프레임윈도우는크기가변경될수있으며, 응용프로그램중에는창의크기변화에따라창안의내용이조정되는것들이있다. 웹브라우저들은창의폭에맞추어텍스트를보여준다. 아이콘모음을담고있는창의경우폭에따라한줄에몇개의아이콘을배치할것인지결정한다. 또메모장에서는창의크기에따라창의우측이나하단에스크롤바가생기거나없어지기도한다. 이러한일이가능하기위해서는창의크기변화라는이벤트를나타내는메시지가필요하며, WM_SIZE가바로이를위한메시지이다. 이메시지는창의크기가변경될때마다발생한다. WM_SIZE 메시지처리를포함하는다음예제코드를살펴보자. 이예제에서는창의크기가변경됨에따라창안의버튼의크기도여백크기를유지하며함께변하고있다. // button3.cpp #include <afxwin.h> #define IDC_BUTTON 100 // Declare the application class class CButtonApp : public CWinApp { virtual BOOL InitInstance(); ; // Create an instance of the application class CButtonApp ButtonApp; // Declare the main window class class CButtonWindow : public CFrameWnd { - 93 -

; CButton *button; CButtonWindow(); afx_msg void HandleButton(); afx_msg void OnSize(UINT, int, int); DECLARE_MESSAGE_MAP() // A message handler function void CButtonWindow::HandleButton() { MessageBeep(-1); // A message handler function void CButtonWindow::OnSize(UINT ntype, int cx, int cy) { CRect r; GetClientRect(&r); r.inflaterect(-20, -20); button->movewindow(r); // The message map BEGIN_MESSAGE_MAP(CButtonWindow, CFrameWnd) ON_BN_CLICKED(IDC_BUTTON, HandleButton) ON_WM_SIZE() END_MESSAGE_MAP() // The InitInstance function is called once // when the application first executes BOOL CButtonApp::InitInstance() { m_pmainwnd = new CButtonWindow(); m_pmainwnd->showwindow(m_ncmdshow); m_pmainwnd->updatewindow(); return TRUE; - 94 -

// The constructor for the window class CButtonWindow::CButtonWindow() { // Create the window itself Create(NULL, _T("CButton Tests"), WS_OVERLAPPEDWINDOW, CRect(0, 0, 300, 200)); // Get the size of the client rectangle CRect r; GetClientRect(&r); r.inflaterect(-20,-20); // Create a button button = new CButton(); button->create(_t("push me"), WS_CHILD WS_VISIBLE BS_PUSHBUTTON, r, this, IDC_BUTTON); 메시지맵안의 ON_WM_SIZE 마크로가주실행창에서발생하는 WM_SIZE 메시지처리를위한마크로이다. 주실행창은다른창의자식창이아니므로메시지를자신에게보낸다. 따라서이메시지는 CButtonWindow 클래스에서처리된다. ON_WM_SIZE 마크로는파라미터를갖지않음을유의하라. 이메시지를받은객체는 ID가주어지지않더라도어떤객체가이메시지를발생시켰는지이미알고있다. 바로자신이발생시켰기때문이다. 또 ON_BN_CLICKED의경우이메시지를발생시키는버튼이여러개있을수있고, 그에따라서로다른작업을하는처리함수이름을필요로한다. 그러나 WM_SIZE 메시지발생객체는하나뿐이므로아예처리함수의이름을 OnSize() 로고정시킴으로써이함수의역할을알아보기쉽게하고있다. CWnd 클래스에는 "On" 으로시작되는많은멤버함수들이있으며 OnSize() 함수와유사한역할을수행한다. 예를들면, WM_MOVE는창의이동시발생하는메시지이며, 이를위한메시지마크로는 ON_WM_MOVE이며, 처리기함수이름은 OnMove() 이다. 또창의일부또는전체가다른창에의해가려졌다가다시나타날경우발생하는메시지는 WM_PAINT, 관련마크로는 ON_WM_PAINT, 처리기함수는 OnPaint() 이다. - 95 -

OnSize() 함수의프로토타입은다음과같다. afx_msg void OnSize(UINT ntype, int cx, int cy); ntype는크기변경유형을나타내며, 이를위해정의된상수들에는 SIZE_MAXIMIZED, SIZE_MINIMIZED, SIZE_RESTORED, SIZE_MAXHIDE, SIZE_MAXSHOW 등이있으며, cx와 cy 는각기클라이언트영역의새로운폭과높이를나타낸다. OnSize(0 함수안에서버튼에적용되는 CWnd::MoveWindow() 함수는창의크기나위치를변경시킨다. WM_TIMER 메시지 이용방법이다소복잡한윈도우메시지들도있다. ON_WM_TIMER 메시지의경우메시지를발생시키기위해먼저 CWnd::SetTimer() 함수를호출해둔다. 이함수의첫번째파라미터는타이머를위한 ID이며, 두번째파라미터는 1/1000초단위로표시된타이머이벤트발생간격이다. 세번째파라미터가 NULL이면, WM_TIMER 메시지처리기함수이름은 OnTimer() 이지만, 별도의처리기함수이름을세번째파라미터를통해지정할수도있다. 아래의예제프로그램에서는 1초마다 WM_TIMER 메시지가발생하도록설정하였으며, 처리기함수 OnTimer() 에서는경고음을낸다. OnTimer() 함수의파라미터는타이머의 ID이다. 이메시지를 10번처리한후에는 OnTimer() 함수안에서 CWnd::KillTimer() 함수를호출하여타이머를종료시킨다. // button4.cpp #include <afxwin.h> #define IDC_BUTTON 100 #define IDT_TIMER1 200 // Declare the application class class CButtonApp : public CWinApp { virtual BOOL InitInstance(); ; // Create an instance of the application class CButtonApp ButtonApp; - 96 -

// Declare the main window class class CButtonWindow : public CFrameWnd { CButton *button; CButtonWindow(); afx_msg void HandleButton(); afx_msg void OnSize(UINT, int, int); afx_msg void OnTimer(UINT); DECLARE_MESSAGE_MAP() ; // A message handler function void CButtonWindow::HandleButton() { MessageBeep(-1); // A message handler function void CButtonWindow::OnSize(UINT ntype, int cx, int cy) { CRect r; GetClientRect(&r); r.inflaterect(-20, -20); button->movewindow(r); // A message handler function void CButtonWindow::OnTimer(UINT id) { static int count = 10; MessageBeep(-1); if (--count == 0) KillTimer(id); // The message map BEGIN_MESSAGE_MAP(CButtonWindow, CFrameWnd) ON_BN_CLICKED(IDC_BUTTON, HandleButton) ON_WM_SIZE() ON_WM_TIMER() END_MESSAGE_MAP() - 97 -

// The InitInstance function is called once // when the application first executes BOOL CButtonApp::InitInstance() { m_pmainwnd = new CButtonWindow(); m_pmainwnd->showwindow(m_ncmdshow); m_pmainwnd->updatewindow(); return TRUE; // The constructor for the window class CButtonWindow::CButtonWindow() { // Create the window itself Create(NULL, _T("CButton Tests"), WS_OVERLAPPEDWINDOW, CRect(0, 0, 300, 200)); // Set up the timer SetTimer(IDT_TIMER1, 1000, NULL); // 1000 ms. // Get the size of the client rectangle CRect r; GetClientRect(&r); r.inflaterect(-20, -20); // Create a button button = new CButton(); button->create(_t("push me"), WS_CHILD WS_VISIBLE BS_PUSHBUTTON, r, this, IDC_BUTTON); 스크롤바컨트롤 윈도우운영체제에서는스크롤바가표준스크롤바와스크롤바컨트롤이라는두가지형태로사용된다. 표준스크롤바는에디트컨트롤이나리스트박스컨트롤등의다른컨트롤이나창에부속되어있는경우를말한다. 다른컨트롤에부속되어있는경우스크롤바를소유하고있는 - 98 -

마스터컨트롤에스크롤바를처리하는기능이포함되어있으며이를위한별도의코딩은필요하지않다. 일반창의경우 WS_HSCROLL이나 WS_VSCROLL 등의스타일파라미터를사용하여스크롤바를만들어줄수있다. 스크롤바컨트롤은독립적으로존재하는스크롤바를말하며, 다른컨트롤들과마찬가지로컨트롤을만들어주고컨트롤에서발생한메시지처리를해주는등을위한코딩이필요하다. 아래예제코드에서는독립형수평스크롤바의생성과메시지맵을보여주고있다. 스크롤바이벤트에대해단지경고음만을내고있으므로스크롤박스 (scroll box 또는 thumb) 가적절히이동하지못한다. #include <afxwin.h> #define IDM_SCROLLBAR 100 const int MIN_RANGE = 0; const int MAX_RANGE = 100; // Declare the application class class CScrollBarApp : public CWinApp { virtual BOOL InitInstance(); ; // Create an instance of the application class CScrollBarApp ScrollBarApp; // Declare the main window class class CScrollBarWindow : public CFrameWnd { CScrollBar *sb; CScrollBarWindow(); afx_msg void OnHScroll(UINT nsbcode, UINT npos, CScrollBar* pscrollbar); DECLARE_MESSAGE_MAP() ; // The message handler function void CScrollBarWindow::OnHScroll(UINT nsbcode, UINT npos, CScrollBar* pscrollbar) { MessageBeep(-1); - 99 -

// The message map BEGIN_MESSAGE_MAP(CScrollBarWindow, CFrameWnd) ON_WM_HSCROLL() END_MESSAGE_MAP() // The InitInstance function is called once // when the application first executes BOOL CScrollBarApp::InitInstance() { m_pmainwnd = new CScrollBarWindow(); m_pmainwnd->showwindow(m_ncmdshow); m_pmainwnd->updatewindow(); return TRUE; // The constructor for the window class CScrollBarWindow::CScrollBarWindow() { // Create the window itself Create(NULL, _T("CScrollBar Tests"), WS_OVERLAPPEDWINDOW, CRect(0, 0, 300, 200)); // Get the size of the client rectangle CRect r; GetClientRect(&r); // Create a scroll bar sb = new CScrollBar(); sb->create(ws_child WS_VISIBLE SBS_HORZ, CRect(10, 10, r.width()-10, 30), this, IDM_SCROLLBAR); sb->setscrollrange(min_range, MAX_RANGE, TRUE); CScrollBar::Create() 함수는 SBS_HORZ 스타일을사용하여수평스크롤바를만든다 ( 수직스크롤바의경우에는 SBS_VERT 사용 ). 그런다음 CScrollBar::SetScrollRange() 함수에서프로그램의서두에정의되어있는상수 MIN_RANGE와 MAX_RANGE를사용하여스크롤바범위를 0에서 100까지로설정한다. 수평 / 수직스크롤바이벤트를나타내는메시지는 WM_HSCROLL/WM_VSCROLL이며, 이에 - 100 -

대한처리기함수는 CWnd::OnHScroll()/CWnd::OnVScroll() 이다. 이함수들은 3개의파라미터를취하는데, 그중첫번째파라미터는사용자의스크롤바에대한동작을나타내는스크롤바코드이다. 스크롤바코드에는아래그림에표시된값들과각기키보드의 HOME, END 키를사용하여얻는 SB_TOP( 또는 SB_LEFT) 과 SB_BOTTOM(SB_RIGHT) 등이있다. 아래그림의스크롤바코드에서 SB_LINEUP, SB_LINEDOWN, SB_PAGEUP, SB_PAGEDOWN은각기 SB_LINELEFT, SB_LINERIGHT, SB_PAGELEFT, SB_PAGERIGHT와같은값을갖는다. 스크롤박스를마우스로끄는동안에는 SB_THUMBTRACK 동작이며, 끄는동작을완료하고마우스버튼에서손을떼는순간은 SB_THUMBPOSITION 동작이된다. 두번째파라미터는스크롤바코드가 SB_THUMBTRACK 또는 SB_THUMBPOSITION일경우스크롤박스의위치를나타낸다. 세번째파라미터는스크롤바컨트롤객체를가리키는포인터인데, 표준스크롤바의경우에는이값은 NULL이다. 아래코드는스크롤바코드에따라스크롤바박스를적절히이동할수있도록 OnHScroll() 함수를고쳐쓴것이다. SB_LINELEFT/RIGHT, SB_PAGELEFT/RIGHT의경우각기 ±1, ±10 만큼이동하게끔프로그램되어있는데, 이값은프로그래머가달리지정할수있다. CScrollBar::SetScrollPos() 함수는파라미터가나타내는위치로스크롤박스를이동시킨다. // The message handling function void CScrollBarWindow::OnHScroll (UINT nsbcode, UINT npos, CScrollBar* pscrollbar) { int pos; pos = sb->getscrollpos(); switch (nsbcode) { case SB_LINELEFT: pos -= 1; break; case SB_LINERIGHT: pos += 1; break; - 101 -

case SB_PAGELEFT: pos -= 10; break; case SB_PAGERIGHT: pos += 10; break; case SB_TOP: pos = MIN_RANGE; break; case SB_BOTTOM: pos = MAX_RANGE; break; case SB_THUMBPOSITION: pos = npos; break; default: return; if (pos < MIN_RANGE) pos = MIN_RANGE; else if (pos > MAX_RANGE) pos = MAX_RANGE; sb->setscrollpos(pos); 헝가리식표기법 (Hungarian Notation) 윈도우 API나 MFC 등에서사용되는함수이름 ( 예 : MessageBeep), 파라미터이름 ( 예 : lpszfacename), 클래스이름 ( 예 : CWinApp), 멤버변수 ( 예 : m_pmainwnd) 등의각종이름에 는헝가리식표기법이라는특별한규칙이적용된다. 이표기법명칭의연원은마이크로소프트 사에서헝가리출신의프로그래머 Charles Simonyi에의해이표기법이창시되었음에따른것 이다. Prefix Variable Type Comment 이름들은표현하고자하는의미 a Array 를나타내는단어들을연결하여만 b Boolean 들어지는데, 각단어의첫글자는 d Double 대문자로표시함으로써단어들을구 h Handle 분한다. 예를들면, Count 또는 i Integer "index into" ClassName 등과같은이름들이사 l Long 용된다. 변수의경우에는이러한의 lp Long pointer to 미전달용이름앞에변수의타입을 lpfn Long pointer to function 나타내는문자들을덧붙인다. 예를 m_ Member variable 들면, ncount 는정수형변수이며, n Integer "number of" bflag는불리언타입변수이다. 특 p Pointer to 히멤버변수의경우에는 m_ 를맨 s String - 102 -

앞에붙인다. 클래스이름앞에는 C sz Zero terminated string 를사용한다. u Unsigned integer 대표적인접두사들을옆의표에 C Class 정리하였지만, 이들외에도많은접두사들이사용되고있다. 지역변수의경우에는특별한규칙이없으며, 오히려멤버변수나파라미터등과구분하기위해 C 언어스타일의소문자와숫자만으로이루어진이름을사용하는것도좋을것이다. 연습문제 1. frame window 와 dialog box 의주요차이점은무엇인가? 2. modal 다이얼로그와 modeless 다이얼로그의차이는무엇인가? 3. MFC library를동적링크라이브러리방식과정적라이브러리방식으로사용하는것의차이는무엇인가? 4. 아래와같은형식의메시지맵에관한질문에답하라. BEGIN_MESSAGE_MAP(class-name-1, class-name-2) ON_... (...); // message handler specifications... END_MESSAGE_MAP() (1) class-name-1 이나타내는클래스의역할은무엇인가? (2) class-name-2 클래스는 class-name-1 클래스가파생되는상위클래스이다. 이상위클래스의역할은무엇인가? - 103 -