2015-11-16
*WinAPI (3)
#TranslateMessage
while(GetMessage(&Message,0,0,0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
GetMessage는 메세지 큐에서 메세지를 꺼내온 후 이 메세지를 TranslateMessage함수로 넘겨준다.
TanslateMessage함수는 전달된 메세지가 WM_KEYDOWN인지와 눌려진 키가 문자키인지 검사해 보고 조건이 맞을 경우 WM_CHAR 메세지를 만들어 메세지 큐에 덧붙이는 역할을 한다.
물론 문자 입력이 아닐 경우는 아무 일도 하지 않으며 이 메세지는 DispatchMessage함수에 의해 WndProc으로 보내진다. 만약 메세지 루프에서 TranslateMessage 함수를 빼 버리면 WM_CHAR메세지는 절대로 WndProc으로 전달되지 않을 것이다.
#Mouse
마우스 입력에 관한 메세지
마우스 메세지는 lParam의 상위 워드에서 y좌표, 하위 워드에서 x좌표를 매크로 함수(HIWORD, LOWORD)를 통해서 검출해 낼 수 있다.
그리고 wParam에 조합키(Shift, Ctrl) 상태가 전달 된다.
TextOut을 통해서 현재 마우스 좌표를 출력해 보자.
- WM_MOUSEMOVE 메세지를 받으면 현재 좌표를 추출해 낸 후 버퍼에 직접 값을 넣는다. 그리고 무효화 영역을 실행한 후 종료하고 WM_PAINT에서는 TextOut함수를 통해 버퍼를 출력한다.
결과
#더블클릭
더블클릭을 하기 위해서는 WinMain에서 WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;를 선언해주고 메세지는 WM_LBUTTONDBLCLK를 사용한다는 것을 유념 한다면 쉽게 코딩을 할 수 가 있다.
결과
#타이머
타이머를 위해서 사용해주는 변수는 기본적으로 2개가 있다.
시간값을 저장할 time_t형 변수와 타이머 핸들인 hTimer가 있다.
타이머를 사용하는 순서는 윈도우가 만들어지자마자 타이머를 SetTimer함수를 통해서 등록을 한다.
UNIT SetTimer(HWND hWnd, UINT nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc) ;
SetTimer(윈도우, 타이머번호, 타이머발생빈도, 타이머동작시 실행함수주소);
이렇게 등록된 타이머는 uElapse가 되면 WM_TIMER메세지를 생성하게 된다. 그리고 WndProc는 이 메세지를 받아서 동작을 수행하게 된다.
종료는 KillTimer(윈도우, 타이머번호)를 통해서 해주면 된다.
우리는 현재 시간을 출력하는 코드를 만들어 보자.
SetTimer로 등록된 타이머는 1초마다 한번씩 WM_TIMER메세지를 전송하게 된다. WM_TIMER메세지를 받은 윈도우는 time함수를 실행해서 현재시간을 저장하게 되고, ctime함수를 통해서 문자열로 바꾸어 준다. 그리고 이것을 윈도우에 적절히 출력해 준다.
결과
다듬기
SendMessage는 프로그래머가 강제로 메세지큐에 메세지를 넣는 함수이다. 윈도우, 메세지, lParam, wParam을 차례로 넣어주면 메세지 큐는 메세지가 온 것으로 인식한다.
InvalidateRect는 무효화 함수이다. 두번때 인자에 NULL은 넣으면 윈도우 전체가 새로 그려지지만 RECT구조체를 사용하여 좌표와 크기를 설정해 주면 원하는 부분만 무효화 시킬 수 있다.
#2개의 타이머 사용하기
여러개의 타이머를 사용하기 위해서는 타이머 등록시 주는 번호를 저장해 두었다가, WM_TIMER메세지 동작 시 번호를 보고 해당 타이머의 동작을 수행 해 주면 된다.
1초짜리 현재 시간을 알려주는 기능을 하기 위한 타이머와, 5초짜리 비프음을 내는 타이머가 있다. WM_TIMER메세지에서 해당 타이머의 번호를 보고 그 타이머에 대한 동작을 수행하게 되는 것이다.
결과
#콜백 함수
한 프로그램이 제어권을 독점하고 있어서는 안되며 다른 프로그램도 실행 시간을 가져야 하기 때문에 수시로 작업을 전환이 가능해야 한다. 그래서 CPU를 독점하는 무한루프를 작성해서는 안되며 반드시 다른 메세지가 전달 되었을 때에 한해 필요한 작업을 하도록 해야한다. 이러한 문제점을 해결하기위한 "콜백함수"를 알아보자.
콜백함수는 응용 프로그램이 제공하며 운영체제가 필요할 때 호출하는 함수이다. 호출되는 방향이 거꾸로 되었기 때문에 콜백이라고 부른다.
콜백함수 예제
결과
#작업영역
작업영역과 비작업영역의 구분은 윈도우를 이해하는데 중요한 비중을 차지한다. 비작업영역은 프로그래밍 대상이 아니며 프로그래밍 대상은 작업 영역에 한정이 된다.
원하는 위치에 정확히 무언가를 출력하려면 윈도우가 차지하고 있는 영역의 좌표를 조사하는 것이 아니라 작업 영역의 좌표를 조사하여야 한다. 이때 GetClientRect함수를 사용한다.
BOOL GetClientRect(HWND hWnd, LPRECT lpRect);
작업영역의 중심좌표 구하기
결과
#리소스 파일 관리하기
리소스 란? 코드의 논리와 무관한 데이터들을 리소스라 하며 메뉴, 비트맵, 액셀레이터, 문자열, 아이콘, 커서 등등이 여기에 속한다. 이러한 리소스들은 별도의 편집기로 만들어져 컴파일시에 실행파일에 결합된다.
윈도우즈 프로그래밍이 도스와 구별되는 큰 차이점은 리소스가 코드와 분리되어 있다는 점이다.
메뉴 만들기
이런식으로 리소스를 만들어 준 뒤 코딩을 한다.
1. 먼저 리소스의 아이디가 디파인 되어있는 resource.h를 include 해준다.
2. WinMain에서 lpszMenuName에 MAKEINTRESOURCE 매크로 함수를 사용하여 등록을 한다.
3. WndProc에서는 동작을 기술한다.
- 메뉴와 관련된 메세지는 전부 WM_COMMAND로 오게 되어있다. 그중에서 우리는 해당 메뉴의 동작만 실행하기를 원하는데 이를 wParam에 실려오는 메뉴들의 아이디로 식별하게 된다. 즉, 메뉴를 클릭하면WM_COMMAND 메세지가 날라오고 wParam에 있는 메뉴의 아이디를 보고 그 메뉴의 동작을 실행하게 되는 것이다.
결과
#리소스 커서 만들기
결과
'코스웨어 > 15년 스마트컨트롤러' 카테고리의 다른 글
20151116 윤재희 #3. 입력 (5) | 2015.11.16 |
---|---|
2015.11.16_개인업무일지_[Win32API #3]_이량경 (3) | 2015.11.16 |
20151116 강동조 개인업무일지API 3일차 (4) | 2015.11.16 |
20151116 - 홍준모 Win32API - 3일차 (4) | 2015.11.16 |
20151116 업무일지 -여지윤- (3) | 2015.11.16 |
20151116-주재민-win32API_3일차 (3) | 2015.11.16 |
2015-11-16 Win32 API 개인업무일지 - 천정호 (3) | 2015.11.16 |
20151116 API_3/ 남수진 (4) | 2015.11.16 |