WM_GETDLGCODE

인수

wParam : 사용되지 않음

lParam : 전달된 메시지인 MSG 구조체의 포인터이며 컨트롤은 전달된 메시지에 따라 다른 결과를 리턴할 수도 있다. 시스템이 단순한 질문을 하는 중에는 NULL이 전달된다.

설명

이 메시지는 대화상자내의 컨트롤들에게 어떤 종류의 입력을 원하는지 질문하기 위해 보내진다. 대화상자에서 사용자의 모든 키 입력은 대화상자가 먼저 받으며 포커스를 가진 컨트롤이 원할 경우만 컨트롤에게 전달된다. 만약 컨트롤이 별다른 입력을 처리하지 않겠다고 응답하면 대화상자는 Tab, Enter, Esc, 커서 이동키 등에 대해 디폴트 처리를 한다. Tab키는 컨트롤간의 포커스 이동을 하며 Enter키는 디폴트 버턴을 누르는 것과 같아진다.

컨트롤들은 자신의 필요에 따라 이 메시지에 응답하여 어떤 입력을 원한다는 것을 대화상자에게 알려 주어야 한다. 예를 들어 ES_WANTRETURN 스타일을 가지는 에디트 컨트롤은 Enter 키 입력을 받아들여 개행해야 하며 이 경우 Enter키는 디폴트 버튼을 누르지 않게 된다. 컨트롤은 자신의 동작과 스타일, 그리고 lParam으로 전달된 메시지를 보고 원하는 키 입력에 대해 응답해야 한다. DefWindowProc은 이 메시지에 대해 항상 0을 리턴하도록 되어 있으므로 커스텀 컨트롤이 이 메시지를 처리하지 않으면 대화상자가 처리하는 키 입력은 받을 수 없다. 대화상자에서 사용될 컨트롤 또는 표준 컨트롤을 서브 클래싱할 때는 이 메시지에 대해 적절히 응답해야 한다.

리턴

어떤 종류의 입력을 원하는지를 다음 값들의 조합으로 리턴해 준다.

실제값(16진수)

설명

DLGC_BUTTON

200

버튼이다.

DLGC_DEFPUSHBUTTON

10

디폴트 버튼이다.

DLGC_HASSETSEL

8

EM_SETSEL 메시지를 원한다.

DLGC_RADIOBUTTON

40

라디오 버튼이다.

DLGC_STATIC 100 스태틱 컨트롤이다.
DLGC_UNDEFPUSHBUTTON 20 디폴트 푸쉬 버튼이 아니다.
DLGC_WANTALLKEYS 4 모든 키 입력을 원한다.
DLGC_WANTARROWS 1 커서 이동키를 원한다.
DLGC_WANTCHARS 80 WM_CHAR 메시지를 원한다.
DLGC_WANTMESSAGE 4 모든 키 입력을 원한다.
DLGC_WANTTAB 2 탭 키 입력을 원한다.
예제

예제 1

다음 예제는 대화상자에 표준 컨트롤들을 배치한 후 이 컨트롤들이 WM_GETDLGCODE 메시지에 대해 어떻게 반응하는지를 테스트한다.

#include 
#include "resource.h"

BOOL CALLBACK MainDlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam);
HINSTANCE g_hInst;
HWND hDlgMain;

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
	,LPSTR lpszCmdParam,int nCmdShow)
{
	g_hInst=hInstance;
	
	DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), HWND_DESKTOP, MainDlgProc);
	
	return 0;
}

void DlgCodeTest(HWND hDlg)
{
	LRESULT code;
	TCHAR str[256];
	TCHAR Mes[1024]={0,};

	code=SendDlgItemMessage(hDlg,IDC_EDIT1,WM_GETDLGCODE,0,NULL);
	wsprintf(str, "에디트1 = %x\r\n", code);
	lstrcat(Mes,str);
	code=SendDlgItemMessage(hDlg,IDC_EDIT2,WM_GETDLGCODE,0,NULL);
	wsprintf(str, "에디트2 = %x\r\n", code);
	lstrcat(Mes,str);
	code=SendDlgItemMessage(hDlg,IDC_EDIT3,WM_GETDLGCODE,0,NULL);
	wsprintf(str, "에디트3 = %x\r\n", code);
	lstrcat(Mes,str);
	code=SendDlgItemMessage(hDlg,IDC_COMBO1,WM_GETDLGCODE,0,NULL);
	wsprintf(str, "콤보 박스 = %x\r\n", code);
	lstrcat(Mes,str);
	code=SendDlgItemMessage(hDlg,IDC_LIST1,WM_GETDLGCODE,0,NULL);
	wsprintf(str, "리스트 박스 = %x\r\n", code);
	lstrcat(Mes,str);
	code=SendDlgItemMessage(hDlg,IDC_CHECK1,WM_GETDLGCODE,0,NULL);
	wsprintf(str, "체크 박스 = %x\r\n", code);
	lstrcat(Mes,str);
	code=SendDlgItemMessage(hDlg,IDC_RADIO1,WM_GETDLGCODE,0,NULL);
	wsprintf(str, "라디오 버튼 = %x\r\n", code);
	lstrcat(Mes,str);
	code=SendDlgItemMessage(hDlg,IDOK,WM_GETDLGCODE,0,NULL);
	wsprintf(str, "OK 버튼 = %x\r\n", code);
	lstrcat(Mes,str);
	MessageBox(hDlg,Mes,"결과",MB_OK);
}

BOOL CALLBACK MainDlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	switch(iMessage) {
	case WM_INITDIALOG:
		hDlgMain = hDlg;
		return TRUE;
	case WM_LBUTTONDOWN:
		DlgCodeTest(hDlg);
		return TRUE;
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDOK:
			EndDialog(hDlg,IDOK);
			return TRUE;
		case IDCANCEL:
			EndDialog(hDlg,IDCANCEL);
			return TRUE;
		}
		return FALSE;
	}
	return FALSE;
}

마우스 왼쪽 버튼을 누르면 DlgCodeTest 함수를 호출하며 이 함수에서 각 컨트롤에게 WM_GETDLGCODE 메시지를 보내 어떤 종류의 입력을 원하는지 질문하였다. 실행 결과는 다음과 같다.

에디트 박스는 WANTCHARS, HASSETSEL, WANTARROWS 입력을 처리한다. 즉 문자 입력을 받으며 EM_SETSEL 메시지에 반응하고 커서 이동키로 앞뒤로 이동한다. 멀티라인 에디트는 여기에 WANTALLKEYS 입력을 추가로 처리하여 Enter키로 개행한다. 좀 더 정확한 코드값은 각 컨트롤이 실제 메시지를 받았을 때에 따라 달라진다. ES_WANTRETURN 스타일이 지정되어 있는 경우와 그렇지 않은 경우 실제 Enter 입력에 대해 다르게 반응할 것이다.

예제 2

다음 예제는 에디트 컨트롤을 서브 클래싱하여 탭 키를 입력받도록 하였다.

#include 
#include "resource.h"

BOOL CALLBACK MainDlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam);
HINSTANCE g_hInst;
HWND hDlgMain;

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
	,LPSTR lpszCmdParam,int nCmdShow)
{
	g_hInst=hInstance;
	
	DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), HWND_DESKTOP, MainDlgProc);
	
	return 0;
}

WNDPROC OldEditProc;
LRESULT CALLBACK EditSubProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	switch (iMessage) {
	case WM_GETDLGCODE:
		return 0x8f;
	}
	return CallWindowProc(OldEditProc,hWnd,iMessage,wParam,lParam);
}

BOOL CALLBACK MainDlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	switch(iMessage) {
	case WM_INITDIALOG:
		hDlgMain = hDlg;
		OldEditProc=(WNDPROC)SetWindowLong(GetDlgItem(hDlg,IDC_EDIT1),
			GWL_WNDPROC,(LONG)EditSubProc);
		return TRUE;
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDOK:
		case IDCANCEL:
			EndDialog(hDlg,IDOK);
			SetWindowLong(GetDlgItem(hDlg,IDC_EDIT1),
				GWL_WNDPROC,(LONG)OldEditProc);
			return TRUE;
		}
		return FALSE;
	}
	return FALSE;
}

탭 키는 원래 대화상자에서 다음 컨트롤로 포커스를 옮기는 키이므로 에디트가 탭 키 입력을 받지 못한다. 하지만 서브클래싱하여 WM_GETDLGCODE 메시지를 받았을 때 DLGC_WANTTAB을 리턴하면 탭 키를 처리할 수 있다. 실행 결과는 다음과 같다.

플랫폼

95이상

참조

 


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