Hacking Arts
WinMain - 4.메시지 루프 돌리기 본문
-WinMain의 마지막 메시지 루프돌리기 입니다.
윈도우를 나타내는 것까지는 다 완성했습니다. 그 다음 이젠 윈도우에 명령이 들어왔을 때 처리해주는 부분을 완성 시켜야 됩니다. 그 부분이 WndProc윈도우 프로시져 부분입니다.
1.이벤트 처리 방식 : 임의의 이벤트가 발생하면 즉시 처리되는 방식이며 이벤트는 키보드나 마우스의 입력을 말합니다.
메세지 내용
1) 이벤트가 발생한 윈도우 핸들 2) 이벤트의 종류 3)이벤트가 접수된 시간 4) 이벤트가 발생한 위치(좌표) |
2.메시지 루프
일단 메세지를 받으면 윈도우 프로시저로 보내줘야되는데 이때 메시지 루프가 그 역할을 하게 됩니다.
[그림 1 이벤트 발생시 처리 과정]
1)어떤 이벤트가 발생하면 가장 먼저 운영체제가 가지고 있는 시스템 큐에 저장
2)시스템 큐에 저장된 메시지는 순서대로 해당하는 애플리케이션 큐로 옮겨진다.
-------------------OS가 자동으로 처리하는 일----------------------
3)애플리케이션 큐에 있는 메시지를 메시지 루프가 가져온다
4)메시지 루프는 가져온 메시지를 윈도우 프로시저 함수로 보낸다.
위와 같은 과정으로 메시지가 처리된다.
LPWSTR lpszClass = L"ApiBase"; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) { HWND hWnd; MSG Message; WNDCLASS WndClass; g_hInst = hInstance; WndClass.cbClsExtra = 0; //클래스 여분 바이트수 WndClass.cbWndExtra = 0; //윈도우 여분 바이트수 WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //윈도우의 배경색 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); //프로그램에서 사용할 커서 WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //프로그램에서 사용할 아이콘 WndClass.hInstance = hInstance; //프로그램의 인스턴스 핸들 WndClass.lpfnWndProc = (WNDPROC)WndProc; //프로시져 함수명 WndClass.lpszClassName = lpszClass; //구조체로 만들어질 클래스명 WndClass.lpszMenuName = NULL; //프로그램에서 사용할 메뉴 WndClass.style = CS_HREDRAW | CS_VREDRAW; //윈도우 스타일 RegisterClass(&WndClass); hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); while (GetMessage(&Message, 0, 0, 0)){ TranslateMessage(&Message); DispatchMessage(&Message); } }위 와 같은 코드로 구현이 된다. 아래쪽에 GetMessage라는 함수의 반환값이 거짓일 때 까지 계속 루프를 반복해서 돈다. 이 함수가 애플리케이션 큐에 저장된 메시지를 인수 Message에 담아 온다. Message 구조체의 내부는 아래와 같다.
typedef struct tagMSG { HWND hwnd; //이벤트가 발생한 윈도우 핸들 UINT message; //이벤트 메시지 종류 WPARAM wParam; //부가 정보 LPARAM lParam; //부가 정보 DWORD time; //이벤트가 접수된 시각 POINT pt; //이벤트가 발생한 위치(좌표) } MSG;
GetMessage 함수는 에플리케이션 큐에서 메시지를 인수 Message에 담아오면 Message.message는 메시지의 종류를 구분할 수 있는 값이 들어 있다. 이때 값이 WM_QUIT일 경우는 거짓을 반환 하고 나머지는 참 값을 반환한다. 참일 경우 TranslateMessage함수와 DispatchMessage 함수를 수행하며 계속 루프를 돌게 된다.
-TranslateMessage 함수 : 키보드 입력 이벤트 중 문자 입력을 처리하는 함수이다. 사용자가 A라는 키를 누르면WM_KEYDOWN,WM_CHAR,WM_KEYUP 세 가지 메시지가 발생한다. WM_CHAR 메시지는 사용자에 의해서 생긴 메시지가 아닌 메시지 루프에서 인위적으로 생긴 메시지이며 GetMessage 함수로 읽은 메시지는 TranslateMessage 함수로 넘겨지고, 메시지가 WM_KEYDOWN 키가 눌려졌는지 문자 키가 눌려졌는지 검사한 후에 문자 키가 눌려졌다면 WM_CHAR 메시지를 발생시킨다. 문자가 아니라면 DispatchMessage 함수로 바로 넘어간다. Translate는 즉 문자키가 눌려졌는지 확인후 눌려지면 WM_CHAR 메시지를 발생시키는 기능을 한다.
'Programing > API Programing' 카테고리의 다른 글
LoadLibrary() 와 GetProcAddress() (1) | 2014.09.26 |
---|---|
WndProc - 메시지 처리하기 (0) | 2014.09.20 |
WinMain - 3.윈도우 객체 화면에 띄우기 (0) | 2014.09.19 |
WinMain - 2.윈도우 객체 생성하기 (0) | 2014.09.19 |
WinMain - 1.윈도우 클래스 만들기 (0) | 2014.09.19 |