본문 바로가기
프로그래밍/MFC (C++)

Win32 API ] 메시지 루프

by eteo 2023. 11. 13.

 

 

 

C언어를 처음 배우고 콘솔환경에서 프로그래밍을 하다가 윈도우 프로그래밍을 시작하면 어디가 프로그램의 시작점이고 어디서부터 순차적으로 명령이 실행되는 것인지 알지 못해 당황하는 경우가 적지 않다. 콘솔과 달리 윈도우 환경에서는 사용자가 발생시키는 이벤트에 대한 메시지를 처리하는 방식으로 프로그램이 수행되고 이를 메시지 기반(또는 이벤트 기반) 프로그래밍이라고 한다. 

 

메시지란? 사용자나 시스템에 의해 발생된 일체의 변화에 대한 정보를 말한다.

ex. 마우스 왼쪽 버튼 클릭, 키보드 누름, 윈도우 최소화 등

 

이런 이벤트가 발생하면 윈도우 시스템에 존재하는 메시지큐에 메시지가 쌓이고, 애플리케이션에서는 윈도우시스템 메시지큐에서 메시지를 가져와서 특정 메시지 발생시 어떠한 일을 수행할 것인가에 대한 처리 루틴을 정의하는 방식으로 프로그램을 작성하게 된다.

 

https://flylib.com/books/en/4.453.1.76/1/

 

각 애플리케이션에는 메시지를 처리하는 함수인 윈도우 프로시저가 존재하는데, 시스템 메시지큐로부터 메시지를 가져와 윈도우 프로시저로 전달하는 부분을 메시지 루프라고 하며 WinMain 함수의 끝에 다음과 같은 형식으로 존재한다.

 

while(GetMessage(&Message,0,0,0)) {
	TranslateMessage(&Message);
	DispatchMessage(&Message);
}

 

 

BOOL GetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);

 

시스템 메시지 큐에서 메시지를 읽어서 스레드 메시지 큐로 가져온다.

읽은 메시지가 WM_QUIT일 경우 False를 리턴하고 그 외에 메시지인 경우 true를 리턴하므로 프로그램 종료 전까지 while 루프가 계속 실행된다.

또한 이 함수는 시스템 메시지 큐에 메시지가 존재하지 않으면 메시지가 들어올 때까지 대기하며 유휴상태로 돌입한다.

 

 

BOOL TranslateMessage( CONST MSG *lpMsg);

 

전달된 메시지가 WM_KEYDOWN인 경우 눌려진 키가 문자키인지 확인해 문자키인 경우 추가적으로 WM_CHAR 메시지를 만들어내 스레드 메시지큐에 덧붙이는 역할을 한다. 문자 입력이 아닐 경우는 아무 일도 하지 않는다.

 

 

 

 

LONG DispatchMessage( CONST MSG *lpmsg);

 

애플리케이션의 메시지 처리함수(WndProc)가 스레드 메시지큐에 쌓인 메시지를 처리할 수 있도록 호출한다.

 

 

 

 

MSG 구조체

 

typedef struct tagMSG
{
    HWND        hwnd;		// 메시지를 받을 윈도우 핸들
    UINT        message;	// 어떤 종류의 메시지인지 나타내는 정수 값
    WPARAM      wParam;		// 전달된 메시지에 대한 부가적인 정보, 32비트 자료형으로 메시지마다 다르다.
    LPARAM      lParam;		// 전달된 메시지에 대한 부가적인 정보, 32비트 자료형으로 메시지마다 다르다.
    DWORD       time;		// 메시지가 발생한 시간
    POINT       pt;			// 메시지가 발생했을 때 마우스의 위치
} MSG;

 

 

 

 

Reference : http://www.soen.kr/lecture/win32api/lec2/lec2-2-3.htm