WM_QUERYENDSESSION

인수

wParam : 사용되지 않는다.

lParam : 로그오프를 하는 것인지 시스템 셧다운을 하는 것인지를 나타낸다. 이 값이 0이면 시스템을 완전히 종료하는 것이며 ENDSESSION_LOGOFF 플래그가 설정되어 있으면 로그오프만 하는 것이다. 이 값은 비트 필드이므로 반드시 & 연산자로 플래그의 존재 유무를 점검해야 한다.

if (lParam & ENDSESSION_LOGOFF) {
    // 로그오프 처리
} else {
    // 셧다운 처리
}

설명

사용자가 운영체제를 종료 또는 로그 오프하고자 할 때, 또는 응용 프로그램이 ExitWindows 함수로 운영체제를 종료하고자 할 때(단, EXW_FORCE 플래그가 없어야 한다)모든 응용 프로그램으로 이 메시지가 보내진다. 이 메시지는 실행중인 각 프로그램에게 "지금 셧다운할건데 해도 괜찮습니까?" 라고 질문하는 것과 같다. 응용 프로그램은 이 메시지를 받았을 때 자신의 내부 상태를 보고 운영체제의 종료를 허가하거나 거부할 수 있다. 만약 한 프로그램이라도 0을 리턴하면 운영체제의 종료는 취소된다.

미저장 문서가 있다거나 또는 네트웍 연결을 함부로 끊을 수 없는 상황이거나 아니면 절대로 종료해서는 안되는 중요한 서버 프로그램인 경우는 이 메시지를 받았을 때 셧다운을 거부하는 것이 가능하다. 만약 TRUE를 리턴하여 종료를 허가하게 되면 운영체제를 종료한다는 WM_ENDSESSION 메시지가 전달된다. DefWindowProc은 이 메시지를 받았을 때 TRUE를 리턴하도록 되어 있으므로 이 메시지를 특별히 처리하지 않으면 운영체제의 종료를 항상 허가하는 것이 된다.

운영체제는 셧다운전에 실행중인 모든 프로그램에게 이 메시지를 보내 셧다운 허가를 받은 후 모든 프로그램이 허가할 때만 개별 프로그램을 종료시킨 후 셧다운한다. 이때 개별 프로그램의 종료 시점은 운영체제 버전에 따라 다르다. 95/98 계열은 모든 프로그램에게 셧다운 허가를 받은 후 각 프로그램을 종료하지만 NT/2000 계열은 개별 윈도우에게 허가를 받은 후 각각의 프로그램을 순서대로 종료시킨다. 그래서 만약 A,B,C 세개의 프로그램이 있고 B가 허가를 거부할 때 95/98계열은 모든 프로그램이 종료되지 않지만 NT/2000 계열은 일단 A가 먼저 종료되고 B의 거부를 받았을 때 셧다운을 중지한다.

리턴

운영체제 종료를 허가하려면 TRUE를 리턴하며 그렇지 않을 경우는 FALSE(=0)를 리턴한다.

예제

예제 1

다음 예제는 WM_QUERYENDSESSION 메시지를 받았을 때 무조건 FALSE를 리턴하도록 함으로써 운영체제 종료를 거부한다.

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	static TCHAR Mes[256]="이 프로그램이 실행중인 동안에는 운영체제 종료를 못한다";

	switch(iMessage) {
	case WM_QUERYENDSESSION:
		wsprintf(Mes,"안돼! 나는 절대로 죽을 수 없어");
		InvalidateRect(hWnd,NULL,TRUE);
		return FALSE;
	case WM_PAINT:
		hdc=BeginPaint(hWnd, &ps);
		TextOut(hdc,10,10,Mes,lstrlen(Mes));
		EndPaint(hWnd, &ps);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

이 프로그램을 종료해야만 운영체제를 종료할 수 있다.

예제 2

다음 예제는 운영체제 종료시 미저장 문서에 대해 사용자에게 질문하고 사용자의 응답에 따라 문서를 저장하거나 또는 버린다. 취소를 선택하면 운영체제 종료를 취소한다.

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	int Result;
	TCHAR Mes[]="시스템 종료시에 미저장 문서를 저장하는 예제";

	switch(iMessage) {
	case WM_QUERYENDSESSION:
		if (TRUE/*미저장 문서가 있다 치고*/) {
			Result=MessageBox(hWnd,"이 문서를 저장할래?","질문",MB_YESNOCANCEL);
			if (Result==IDCANCEL) {
				return FALSE;
			}
			if (Result==IDYES) {
				// 저장했다 치고
			}
		}
		return TRUE;
	case WM_PAINT:
		hdc=BeginPaint(hWnd, &ps);
		TextOut(hdc,10,10,Mes,lstrlen(Mes));
		EndPaint(hWnd, &ps);
		return 0;
	case WM_CLOSE:
		MessageBox(hWnd,"나 지금 닫혀요","아이고",MB_OK);
		break;
	case WM_DESTROY:
		MessageBox(hWnd,"나 지금 죽어요","아이고",MB_OK);
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

이 예제를 실행해 보면 시스템 종료시에는 WM_CLOSE, WM_DESTROY 등의 메시지가 전달되지 않음을 알 수 있다. 왜냐하면 운영체제 종료는 곧 전원이 꺼진다는 특수한 상황이기 때문에 메인 윈도우가 파괴되지 않기 때문이다. WM_CLOSE에서 미저장 문서에 대한 처리를 하고 있더라도 시스템 종료시에는 이 처리가 생략됨으로 별도의 처리가 있어야 한다.

플랫폼

95이상

참조

WM_ENDSESSION : 운영체제 종료가 결정된 후에 보내지는 메시지이다.


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