PeekMessage

원형

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

MFC 원형

해당하는 함수 없음

인수

▶lpMsg : 메시지를 받을 구조체이며 다음과 같이 선언되어 있다.

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

▶hWnd : 메시지를 받을 윈도우이며 이 윈도우로 보내지는 메시지를 조사한다. 이 윈도우는 반드시 같은 스레드에 소속된 윈도우여야 하며 다른 스레드로 보내지는 메시지는 조사할 수 없다. 이 인수가 NULL이면 이 함수를 호출한 스레드로 전달된 모든 메시지를 조사한다.

▶wMsgFilterMin : 조사할 메시지의 최소값.

▶wMsgFilterMax : 조사할 메시지의 최대값. 이 두 인수를 사용하면 일정한 범위에 속한 메시지만 조사할 수 있는데 이를 메시지 필터링이라고 한다. 예를 들어 키보드 관련 메시지만 조사하고 싶으면 WM_KEYFIRST, WM_KEYLAST로 범위를 지정할 수 있다. 두 인수가 모두 0이면 메시지 필터링을 하지 않으며 모든 메시지를 조사한다.

▶wRemoveMsg : 조사한 메시지를 처리할 방법을 지정하는 플래그의 조합이다.

플래그 설명

PM_NOREMOVE

메시지를 읽은 후 큐에서 메시지를 제거하지 않는다.

PM_REMOVE 메시지를 읽은 후 큐에서 메시지를 제거한다.
PM_NOYIELD 다른 스레드로 제어를 양보하지 않는다.
PM_QS_INPUT

디폴트로 이 함수는 모든 메시지를 다 처리하는데 이하의 플래그들을 지정하면 특정 메시지들만 처리하도록 할 수 있다. 이 플래그들은 98이상, 2000이상에서만 적용된다.

마우스나 키보드 등의 입력 메시지만 처리한다.

PM_QS_PAINT 그리기 메시지만 처리한다.
PM_QS_POSTMESSAGE 타이머나 핫키 메시지를 포함하여 붙여지는 메시지만 처리한다.
PM_QS_SENDMESSAGE 보내지는 메시지만 처리한다.
리턴

메시지 큐에 메시지가 있으면 0이 아닌 값을 리턴하며 메시지가 없으면 0을 리턴한다.

설명

GetMessage 함수와 마찬가지로 메시지 큐에서 메시지를 읽는다. 메시지의 범위를 줄 수 있는 기능도 GetMessage와 동일하다. 그러나 이 함수는 GetMessage와는 달리 읽은 메시지를 무조건 제거하지 않으며 큐가 비어 있을 경우 대기하지 않고 곧바로 리턴한다는 점이 다르다. 따라서 이 함수는 메시지를 읽지 않고 단순히 메시지가 있는지 확인만 할 수 있으며 이런 특성은 백그라운드 작업에 적절하다.

예제 1

다음 예제는 메시지 루프에 GetMessage를 사용하지 않고 PeekMessage를 사용함으로써 메시지를 처리하지 않는동안 백그라운드 작업을 한다.

	HDC hdc;
	hdc=GetDC(hWnd);
	int count=0;
	char str[255];
	for (;;) {
		if (PeekMessage(&Message,NULL,0,0,PM_REMOVE)) {
			if (Message.message==WM_QUIT)
				break;
			TranslateMessage(&Message);
			DispatchMessage(&Message);
		}
		else {
			count++;
			wsprintf(str,"현재 카운터는 %d입니다",count);
			TextOut(hdc,10,10,str,lstrlen(str));
		}
	}
	ReleaseDC(hWnd,hdc);

GetMessage 함수는 메시지 큐가 비어 있을 경우 무한 대기를 하기 때문에 백그라운드 작업을 할 수 없지만 PeekMessage 함수를 사용하면 즉시 리턴하며 리턴값으로 메시지의 유무를 알려 주므로 0을 리턴할 때 백그라운드 작업을 수행할 수 있다. 예제에서는 카운트를 세는 작업을 백그라운드로 하고 있다. 단 WM_QUIT 메시지에 대해서는 특별한 예외처리를 하여 메시지 루프를 벗어날 수 있도록 해 주어야 프로그램이 종료된다.

예제 2

다음 예제의 SortData 함수는 대량의 데이터를 정렬하는 함수이며 정렬 루틴대신 Sleep 함수로 시간을 끌도록 하였다.

void SortData()
{
	int i;
	char Caption[128];
	MSG Message;

	for (i=0;i<=1000;i++) {
		wsprintf(Caption,"소트중 %d%%",i/10);
		SetWindowText(hWndMain,Caption);
		Sleep(1);
	}
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	switch(iMessage) {
	case WM_LBUTTONDOWN:
		SortData();
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

SortData 함수가 완전히 종료되기 전에는 제어를 리턴하지 않으므로 이 함수가 실행중인동안에 윈도우는 어떠한 메시지도 처리할 수 없다. 이런 시간이 오래 걸리는 작업 루틴에 PeekMessage 루틴을 삽입하면 작업을 하는 동안에도 윈도우가 정상적으로 메시지를 처리할 수 있도록 한다.

void SortData()
{
	int i;
	char Caption[128];
	MSG Message;

	for (i=0;i<=1000;i++) {
		wsprintf(Caption,"소트중 %d%%",i/10);
		SetWindowText(hWndMain,Caption);
		if (PeekMessage(&Message,NULL,0,0,PM_REMOVE)) {
			if (Message.message==WM_QUIT) {
				PostQuitMessage(0);
				break;
			}
			TranslateMessage(&Message);
			DispatchMessage(&Message);
		}
		Sleep(1);
	}
}

데이터를 정렬하는 동안에 메시지 큐를 주기적으로 점검하여 메시지가 들어오면 이 메시지를 윈도우로 보내주어 처리하도록 해 주었으므로 정렬하는 동안에도 다른 작업을 할 수 있다. 단, 이럴 경우 같은 작업을 두번 실행하지 못하도록 하는 장치가 필요할 수도 있다.

참고함수

GetMessage : 메시지 큐에서 메시지를 읽되 무한 대기하며 메시지를 무조건 큐에서 제거한다.

플랫폼

95이상

참조

 


written by http://www.winapi.co.kr