WM_INITDIALOG

인수

wParam : 키보드 포커스를 받을 컨트롤의 핸들. 통상 이 컨트롤은 탭 순서가 가장 빠르고 보이며 사용 금지 상태가 아니고 WS_TABSTOP 스타일을 가진 첫번째 컨트롤이다. 이 메시지에서 TRUE를 리턴하면 wParam으로 전달된 컨트롤에 포커스가 맞추어진다.

lParam : 대화상자 초기화 정보가 전달된다. DialogBox 함수로 대화상자를 호출한 경우는 0이 전달되며 DialogBoxParam, CreateDialogParam 등의 함수로 대화상자를 호출했을 때만 전달된다. 대화상자로 전달되는 인수값에 해당하며 이 인수에 따라 대화상자의 모양이나 동작을 다르게 정의할 수 있다. 프로퍼티 시트의 경우 lParam은 PROPSHEETPAGE 구조체의 포인터가 전달된다.

설명

이 메시지는 대화상자가 메모리에 만들어지고 화면에 보이기 직전에 보내진다. 그래서 대화상자내의 모든 컨트롤을 참조할 수 있으며 아직 대화상자가 보이기 전이므로 컨트롤의 재배치, 생성, 삭제, 속성 변경 등을 자유롭게 할 수 있다. 오버랩드 윈도우의 WM_CREATE에 해당하는 함수이며 대화상자가 가장 먼저 받는 메시지이므로 주로 대화상자 초기화에 이 메시지가 사용된다.

대화상자에 속한 컨트롤을 초기화하는 것이 일반적이며 기타 대화상자 동작에 필요한 환경 설정, 메모리 할당, 대화상자 위치 및 속성 변경 등의 작업을 할 수 있다. 만약 초기화중에 실패를 하게 되면 이 메시지를 처리하는 동안에도 EndDialog를 호출하여 대화상자를 즉시 종료하는 것이 가능하다. WM_CREATE와는 달리 리턴값으로 에러 여부를 리턴할 수 없으며 EndDialog 함수로 에러 코드를 리턴해야 한다.

리턴

TRUE를 리턴하면 wParam으로 전달된 첫번째 컨트롤에 포커스가 설정된다. FALSE를 리턴하면 첫번째 컨트롤로 포커스를 옮기지 않으므로 이 메시지를 처리하는 동안 처음 포커스를 받을 컨트롤을 지정할 수 있다. SetFocus 함수로 포커스를 강제로 이동시킨 경우는 FALSE를 리턴해야 한다. 일반적으로 대화상자의 메시지는 처리되었으면 TRUE를 리턴하고 그렇지 않으면 FALSE를 리턴하는데 이 메시지만은 예외이다.

예제

예제 1

다음 예제는 대화상자 초기화동안 각종 컨트롤들을 초기화한다.

#include <windows.h>
#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;
}

BOOL CALLBACK MainDlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	switch(iMessage) {
	case WM_INITDIALOG:
		hDlgMain = hDlg;
		CheckRadioButton(hDlg,IDC_RADIO1,IDC_RADIO3,IDC_RADIO2);
		SendDlgItemMessage(hDlg,IDC_LIST1,LB_ADDSTRING,0,(LPARAM)"경희대");
		SendDlgItemMessage(hDlg,IDC_LIST1,LB_ADDSTRING,0,(LPARAM)"연세대");
		SendDlgItemMessage(hDlg,IDC_LIST1,LB_ADDSTRING,0,(LPARAM)"고려대");
		SendDlgItemMessage(hDlg,IDC_LIST1,LB_ADDSTRING,0,(LPARAM)"한강대");
		SendDlgItemMessage(hDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)"경제학과");
		SendDlgItemMessage(hDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)"퐁당과");
		SendDlgItemMessage(hDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)"떡볶이과");
		SendDlgItemMessage(hDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)"땡땡이과");
		SendDlgItemMessage(hDlg,IDC_COMBO1,CB_SETCURSEL,1,0);
		SetDlgItemText(hDlg,IDC_EDIT1,"WinApi");
		SetFocus(GetDlgItem(hDlg,IDC_EDIT1));
		return FALSE;
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDOK:
			EndDialog(hDlg,IDOK);
			return TRUE;
		case IDCANCEL:
			EndDialog(hDlg,IDCANCEL);
			return TRUE;
		}
		return FALSE;
	}
	return FALSE;
}

실행 결과는 다음과 같다.

라디오 버튼중 Radio2 컨트롤을 선택했으며 에디트 컨트롤에 문자열을 대입하고 콤보 박스와 리스트 박스에 초기 항목을 추가하였다. 콤보 박스는 1번째 항목을 미리 선택하도록 했다. 에디트 컨트롤에 강제로 포커스를 설정하고 위해 SetFocus 함수를 호출하였으며 FALSE를 리턴하였다. 만약 이 메시지에서 TRUE를 리턴하면 SetFocus 호출에 상관없이 첫번째 컨트롤인 확인 버튼이 포커스를 받게 된다.

예제 2

다음 대화상자는 초기화중에 부모 윈도우의 작업 영역 중앙으로 스스로 자리를 옮긴다. 대화상자의 Center 속성은 화면 중앙으로 이동하는 속성이므로 이 속성을 설정해서는 부모의 중앙으로 옮길 수 없다.

#include "resource.h"
BOOL CALLBACK DlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	RECT wrt,crt;

	switch(iMessage) {
	case WM_INITDIALOG:
		GetWindowRect(GetParent(hDlg),&wrt);
		GetWindowRect(hDlg,&crt);
		SetWindowPos(hDlg,HWND_NOTOPMOST,wrt.left+(wrt.right-wrt.left)/2-(crt.right-crt.left)/2,
			wrt.top+(wrt.bottom-wrt.top)/2-(crt.bottom-crt.top)/2,0,0,SWP_NOSIZE);
		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;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;

	switch(iMessage) {
	case WM_LBUTTONDOWN:
		DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);
	case WM_PAINT:
		hdc=BeginPaint(hWnd, &ps);
		EndPaint(hWnd, &ps);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

실행 결과는 다음과 같다.

예제 3

다음 예제는 WM_INITDIALOG의 lParam으로 전달되는 문자열에 따라 다른 메시지를 보여준다.

#include "resource.h"
BOOL CALLBACK DlgProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	switch(iMessage) {
	case WM_INITDIALOG:
		SetDlgItemText(hDlg,IDC_MES,(TCHAR *)lParam);
		return TRUE;
	case WM_COMMAND:
		switch (wParam) {
		case IDOK:
			EndDialog(hDlg,1);
			return TRUE;
		case IDCANCEL:
			EndDialog(hDlg,0);
			return TRUE;
		}
		break;
	}
	return FALSE;
}


LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	TCHAR Mes[128]="마우스 왼쪽 버튼을 누르면 대화상자가 호출됩니다";

	switch(iMessage) {
	case WM_LBUTTONDOWN:
		DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1),
			hWnd,DlgProc,(LPARAM)"너 이름이 뭐야?");
		return TRUE;
	case WM_RBUTTONDOWN:
		DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1),
			hWnd,DlgProc,(LPARAM)"몇살이니?");
		return TRUE;
	case WM_PAINT:
		hdc=BeginPaint(hWnd, &ps);
		TextOut(hdc,50,50,Mes,lstrlen(Mes));
		EndPaint(hWnd, &ps);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

마우스 왼쪽, 오른쪽 버튼을 누르면 다음과 같은 대화상자가 나타난다.

좀 더 복잡한 정보를 전달하려면 구조체를 선언한 후 구조체의 포인터를 넘겨 주면 된다. 대화상자는 lParam으로 전달된 값에 따라 대화상자 초기화를 다르게 할 수 있으며 대화상자 실행중에 이 정보를 계속 사용하려면 전역 또는 정적 변수에 이 정보를 저장해 두어야 한다. 또한 lParam으로 구조체의 포인터를 전달했을 경우 대화상자의 실행 결과를 이 구조체로 다시 리턴할 수도 있다.

플랫폼

95이상

참조

 


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