GetMessage(), PeekMessage()

A Code AM·2020년 4월 20일
0

수업(20200212~)

목록 보기
8/12

메시지 루프

윈도우즈 = 메시지 구동 시스템(Message Driven System)

: 메시지가 발생하면 프로그램에서는 메시지가 어떤 정보를 담고있는가 분석해서 어떤 루틴 호출할 것인가 결정. 즉, 순서를 따르지 않고 주어진 메시지에 대한 반응을 정의하는 방식
-> 도스와 가장 뚜렷한 대비를 이루는 윈도우즈의 특징

도스 : 프로그래머에 의해 미리 입력된 일련의 명령들을 순서대로 실행하는 순차적 실행방법 사용
윈도우즈 : 프로그램의 실행 순서가 명확하게 정해져 있지 않고 상황(어떤 메시지가 주어졌는가)에 따라 순서가 달라짐
메시지 : 사용자나 시스템 내부적인 동작에 의해 발생된 일체의 변화에 대한 정보
ex) 마우스 버튼 눌리거나 키보드 눌리거나 윈도우 최소화 되었을때의 변화에 대한 정보들

MSG 구조체

typedef struct tagMSG{
	HWND hWnd;
    UINT message;
    WPARAM wParam;
    LPARAM lParam;
    DWORD time;
	POINT pt;
} MSG;

hWnd : 메시지 받을 윈도우 핸들
message : 어떤 종류의 메시지인가 (가장 중요한 값)
wParam : 전달된 메시지에 대한 부가적인 정보. 어떤 의미를 가지는가는 메시지별로 다름. 32bit값

  • wParam의 상위 16비트(HIWORD)는 통지 코드 / 하위 16비트(LOWORD)는 컨트롤의 ID
  • 컨트롤 ID는 CreateWindow의 9번째 인수에서 정한 정수값. 어떤 컨트롤이 통지 메시지를 보냈는지 알려줌. 통지 코드는 컨트롤이 왜 메시지를 보냈는가를 나타내는 값. (통지 코트가 여러 개인 컨트롤은 이 값을 검사해 봐야함)

lParam : 전달된 메시지에 대한 부가적인 정보. 어떤 의미를 가지는가는 메시지별로 다름. 32bit값

  • lParam의 상위 16비트(HIWORD)는 x 좌표 / 하위 16비트(LOWORD)는 y 좌표

time : 메시지가 발생한 시간
pt : 메시지가 발생했을 때의 마우스 위치

GetMessage()

: 새 메시지가 올 때까지 제어가 필요하지 않음, 새 메시지가 올 때까지 블록되므로 CPU 사용하지 않음 -> CPU를 다른 어플리케이션이 사용할 수 있게 양보한다.

BOOL GetMessage{
	LPMSG lpMsg;
    HWND hWnd;
	UINT wMsgFilterMin;
    UINT wMsgFilterMax;
}

lpMsg : 메시지 받을 구조체(MSG 구조체) -> WM_QUIT이면 false 리턴해서 종료됨, 그 외에는 true 리턴
hWnd : 메시지 받을 윈도우. 이 윈도우로 보내지는 메시지를 조사 (같은 스레드여야 함).
NULL이면 이 함수를 호출한 스레드로 전달된 모든 메시지를 조사함.
wMsgFilterMin : 조사할 메시지의 최소값.
wMsgFilterMax : 조사할 메시지의 최대값. 두 인수를 사용하면 일정한 범위에 속한 메시지만 조사할 수 있다(메시지 필터링). 두 인수가 모두 0이면 메시지 필터링을 사용하지 않고 모든 메시지를 조사한다.

PeekMessage()

: 메시지를 얻어오고, 계속 제어를 원함. CPU 시간을 낭비하며, 운영체제가 idle time(유휴시간에 할 일도 막아버리므로, 범용 메시지 루프에서는 사용할 수 없음. 메시지 큐에서 메시지를 가져오지 않고도 메시지가 있는지 없는지 확인 가능하므로, 작업 스레드를 사용하지 않고 배경 작업을 하고자 할 때 유용함.

BOOL PeekMessage{
	LPMSG lpMsg;
	HWND hWnd;
	UINT wMsgFilterMin;
    UINT wMsgFilterMax;
    UINT wRemoveMsg;
};

GetMessage와 다른 것은 동일.
wRemoveMsg : 제거 플래그
종류에는 PM_NOREMOVE, PM_REMOVE가 있는데 PM_NOREMOVE는 메시지 큐에서 메시지를 제거하지 않고 PM_REMOVE는 메시지 큐에서 메시지를 제거한다. 대부분의 경우 PM_REMOVE 사용

PM_NOREMOVE : 메시지를 읽은 후 큐에서 메시지를 제거하지 않는다
PM_REMOVE : 메시지를 읽은 후 큐에서 메시지를 제거한다.
PM_NOYIELD : 다른 스레드로 제어를 양보하지 않는다.
PM_QS_INPUT : 디폴트로 이 함수는 모든 메시지를 다 처리하는데 이하의 플래그들을 지정하면 특정 메시지들만 처리하도록 할 수 있다. 이 플래그들은 98이상, 2000이상에서만 적용된다. 마우스나 키보드 등의 입력 메시지만 처리한다.
PM_QS_PAINT : 그리기 메시지만 처리한다.
PM_QS_POSTMESSAGE : 타이머나 핫키 메시지를 포함하여 붙여지는 메시지만 처리한다.
PM_QS_SENDMESSAGE : 보내지는 메시지만 처리한다.

TranslateMessage()

BOOL TranslateMessage(CONST MSG *lpMsg);

키보드 입력 메시지를 받아 가공해서 프로그램에서 쉽게 쓸 수 있도록 한다. 어떤 키가 눌러졌다거나 떨어졌을때 키보드 메시지를 발생시킨다. 키보드 눌림(WM_KEYDOWN)과 떨어짐(WM_KEYUP)이 연속적으로 발생할 때 문자가 입력되었다는 메시지(WM_CHAR)을 만드는 역할을 한다.

DispatchMessage()

BOOL DispatchMessage(CONST MSG *lpMsg);

시스템 메시지 큐에서 꺼낸 메시지를 프로그램의 메시지 처리 함수(WndProc)으로 전달한다.
이 함수에 의해 메시지가 프로그램으로 전달되고 프로그램에서는 받은 메시지를 점검해서 다음 동작을 결정한다

profile
배움기록

0개의 댓글