MFC 프로그래밍에 관한 팁 / Keyboard / Timer Department of Digital Contents Sang Il Park
Useful tips for programming
Debuging? 프로그램 시 드는 의문: 해결법: 프로그램이 제대로 동작하고 있는 걸까? OR 지금 현재 변수 값이 얼마일까? 해결법: DEBUG 모드를 활용하자! Debug 모드가 주는 장점들 문장 출력 (printf와 비슷) : TRACE 이용 프로그램 일시 중단 : 중단점 활용 변수 값 조사 : 조사식/호출스택 이용 값의 유효성 상시 검사: ASSERT 이용
Different modes for compiling Debug Mode : 프로그램 개발 모드 여러가지 편리한 기능 제공 수행 속도가 떨어짐 (대규모 메모리 생성 시) Release Mode : 프로그램 배포 모드 프로그램 용량 최적화 수행 속도 최적화 활성 구성 설정 바꾸기: 빌드 구성관리자
Debug Mode 활용하기 먼저 활성구성을 Debug Mode로 바꿈 F5를 누르거나 “디버깅시작” 실행 디버깅 기능들이 모두 사용 가능 하게 됨 TRACE, 중단점, 조사식 등의 기능 사용 Ctrl + F5를 누르거나 “디버깅하지 않고 시작” 실행 디버깅 기능이 사용 안됨 빠르게 테스트 할 때 활용
TRACE 원하는 문장을 출력창에 표시한다. 사용법 (printf와 동일) 출력결과: TRACE( “Now Running! /n”); // 문장 출력 TRACE( “i= %d /n”, i); // 변수값 출력
중단점 프로그램의 실행을 일시 멈추고 싶은 곳에 설정 중단점 지정 행의 바로 앞에서 멈춘다. 중단점 설정: F9 키 함수 일 경우는 하나씩 함수가 실행됨 함수 속으로 들어가 실행: F11 키 함수 코드 내로 들어감
변수 값 조사 (실행 중단 시) 변수들의 현재 값을 표시함 자동: 전역 또는 지역 변수 값 표시 지역: 현재 함수 내에서 사용되는 지역 변수 값 표시 조사식: 사용자가 원하는 변수 또는 수식 값 표시 배열이나, pointer값도 조회 가능 <창 표시법: 디버그 창 조사식/자동/지역 >
호출 스택 (실행 중단 시) 현재 중단 된 시점의 함수 호출 스택을 표시 함수의 실행 경로 확인 가능 함수 간을 이동하면 변수값을 조사하는데 활용 <창 표시법: 디버그 창 호출 스택 >
ASSERT 활용 값의 유효성을 확인하기 위해 활용 사용법: 조사식의 값이 false 이면 프로그램 실행 중단 시킴 사용 예: ASSERT ( i==0 ); // i가 0인지 확인 ASSERT ( i<0 ); // i가 0보다 작은지 확인 ASSERT ( func1() ); // func1을 수행하고 // 반환값이 true인지 확인
Keyboard Input
키보드 기초 (1/2) 키보드 처리 윈도우 운영체제는 키보드와 관련된 모든 변화를 메시지 형태로 프로그램에게 전달한다. 키보드 장치 드라이버 시스템 메시지 대기열 응용 프로그램 핸들러 루프 스캔 코드
키보드 기초 (2/2) 키보드 메시지 전달 키보드 포커스 키보드 메시지는 키보드 포커스를 가진 윈도우가 받는다. 활성 윈도우 또는 활성 윈도우의 자식 윈도우가 가지는 일종의 속성
키보드 포커스 (1/2) 키보드 포커스 유형 캐럿
키보드 포커스 (2/2) 키보드 포커스 변화 WM_SETFOCUS WM_KILLFOCUS WM_SETFOCUS
캐럿 (1/2) 관련 함수 함수 이름 역할 CreateCaret() 비트맵을 이용하여 캐럿을 생성한다. CreateGrayCaret() 회색 사각형 모양의 캐럿을 생성한다. CreateSolidCaret() 검정색 사각형 모양의 캐럿을 생성한다. ShowCaret() 캐럿이 보이도록 한다. HideCaret() 캐럿을 숨긴다. GetCaretPos() 캐럿의 위치(클라이언트 좌표)를 얻는다. SetCaretPos() 캐럿의 위치(클라이언트 좌표)를 변경한다. ::DestroyCaret() 캐럿을 파괴한다. ::GetCaretBlinkTime() 캐럿이 깜박이는 간격을 얻는다. ::SetCaretBlinkTime() 캐럿이 깜박이는 간격을 설정한다.
캐럿 (2/2) void CChildView::OnSetFocus(CWnd* pOldWnd) { CWnd ::OnSetFocus(pOldWnd); CreateSolidCaret(20, 20); SetCaretPos(CPoint(50, 50)); ShowCaret(); } void CChildView::OnKillFocus(CWnd* pNewWnd) CWnd ::OnKillFocus(pNewWnd); HideCaret(); ::DestroyCaret();
키 누름 메시지 (1/3) 키 누름 메시지(Keystroke Message) 키 누름 메시지 종류 키보드를 누르거나 떼는 동작에 의해 발생하는 메시지 키 누름 메시지 종류 메시지 의미 WM_KEYDOWN F10, Alt 이외의 키를 누를 때 WM_KEYUP F10, Alt를 이외의 키를 뗄 때 WM_SYSKEYDOWN F10, Alt, Alt + 키 조합을 누를 때 WM_SYSKEYUP F10, Alt, Alt + 키 조합을 뗄 때
키 누름 메시지 (2/3) 메시지 핸들러 형태 nChar nRepCnt nFlags 키에 할당된 가상 키 코드값 다음 페이지 표 참조 nRepCnt 키를 계속 누르고 있을 경우 1보다 큰 값을 가진다. nFlags 키와 관련된 다양한 정보를 담고 있다(MSDN 참조). afx_msg void On#### (UINT nChar, UINT nRepCnt, UINT nFlags) ;
키 누름 메시지 (3/3) 가상 키코드 (Virtual Key Code) 가상 키 코드 VK_CANCEL VK_BACK VK_TAB VK_RETURN VK_SHIFT VK_CONTROL VK_MENU VK_PAUSE VK_CAPITAL VK_ESCAPE VK_SPACE VK_PRIOR VK_NEXT VK_END 해당 키 Ctrl-Break Backspace Tab Enter Shift Ctrl Alt Pause Caps Lock Esc Spacebar PgUp PgDn End VK_HOME VK_LEFT VK_UP VK_RIGHT VK_DOWN VK_SNAPSHOT VK_INSERT VK_DELETE VK_0 - VK_9 VK_A - VK_Z VK_F1 - VK_F12 VK_NUMLOCK VK_SCROLL Home ← ↑ → ↓ Print Screen Insert Delete 0 – 9 A – Z F1 - F12 Num Lock Scroll Lock
문자 메시지 (1/3) 문자 메시지 필요성 - VK_R 키를 누른 경우 ? 문자 가상 키 코드 조합 r 영문 입력 모드에서 VK_R 또는 VK_R + Caps Lock + Shift 키를 누른 경우 R 영문 입력 모드에서 VK_R + Caps Lock 또는 VK_R + Shift 키를 ㄱ 한글 입력 모드에서 VK_R 키를 누른 경우 ㄲ 한글 입력 모드에서 VK_R + Shift 키를 누른 경우
문자 메시지 (2/3) 문자 메시지 - VK_R 키를 누른 경우 문자 메시지 - Alt + VK_R 키를 누른 경우 WM_KEYDOWN WM_CHAR WM_KEYUP WM_SYSKEYDOWN WM_SYSCHAR WM_SYSKEYUP WM_KEYUP
문자 메시지 (3/3) 메시지 핸들러 형태 nChar nRepCnt nFlags 키에 해당하는 문자 코드(Character Code) 값을 가진다. nRepCnt 키를 계속 누르고 있을 경우 1보다 큰 값을 가진다. nFlags 키와 관련된 다양한 정보를 담고 있다(MSDN 참조). afx_msg void OnChar (UINT nChar, UINT nRepCnt, UINT nFlags) ; afx_msg void OnSysChar (UINT nChar, UINT nRepCnt, UINT nFlags) ;
코딩 연습 사각형 움직이기 1. 위치 저장 변수 선언 CPoint m_pt; 2. 위치에 사각형그리기 (OnPaint) void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) ; VK_UP 1. 위치 저장 변수 선언 CPoint m_pt; 2. 위치에 사각형그리기 (OnPaint) dc.Rectangle(m_pt.x, …); 3. OnKeyDown 핸들러 추가 4. nChar 값 검사하여 위치변경 if(nChar == VK_RIGHT) m_pt.x += 10; VK_LEFT VK_RIGHT VK_DOWN
TIMER 주기적인 작업을 지정하기
SetTimer 함수 void SetTimer (int id, int time, void * fp) ; 매 설정된 시간 마다 WM_TIMER 메시지 발생 id timer의 id (예: 0, 1, 2, … ) timer가 여러 개 있을 경우 구분하기 위해 사용 time: 알람을 울릴 주기 (=millisec) 1000 = 1 초 반드시 윈도우가 만들어 진 후 설정한다. 주로 WM_CREATE의 핸들러인 OnCreate 내부에 설정 예) SetTimer(0, 100, NULL);
WM_TIMER 핸들러 nIDEvent 코딩 예) 현재 WM_TIMER를 발생시킨 타이머의 id afx_msg void OnTimer (int nIDEvent) void CChildView::OnTimer(int nIDEvent) { if(nIDEvent == 0) // 주기 마다 해 줘야 할 일 }
코딩 연습 사각형이 죽~ 움직이는 장면 만들기 1. 위치 저장 변수 선언 CPoint m_pt; 2. 위치에 사각형그리기 (OnPaint) dc.Rectangle(m_pt.x, …); 3. WM_CREATE 핸들러 추가 (OnCreate) 4. OnCreate함수에 Timer세팅 SetTimer(0,30,NULL); 5. WM_TIMER 핸들러 추가 (OnTimer) if(nIDEvent == 0) …..