본문 바로가기
프로그래밍/API

API-ChildWnd

by 리뷰하는 (게임)프로그래머_리프TV 2010. 4. 24.


프로그램이 간단하다면 괜찮지만, 그렇지 않다면, 하나의 메인 윈도우 만으로는 한계가 있을 것이다.
그때 차일드 윈도우를 생성하여 사용 할 수 있다.

일단 예제를 보고 설명을 하나씩 하도록 하겠다.

#include <windows.h>

LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
LRESULT CALLBACK ChildProc( HWND, UINT, WPARAM, LPARAM );
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass = TEXT("ChildWnd");
BOOL bEllipse = TRUE;

int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
					 LPSTR lpszCmdParam, int nCmdShow )
{
	HWND hWnd;
	MSG Message;
	WNDCLASS WndClass;
	g_hInst = hInstance;

	WndClass.cbClsExtra = 0;
	WndClass.cbWndExtra = 0;
	WndClass.hbrBackground = (HBRUSH)GetStockObject( COLOR_WINDOW+1 );
	WndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
	WndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
	WndClass.hInstance = hInstance;
	WndClass.lpfnWndProc = WndProc;
	WndClass.lpszClassName = lpszClass;
	WndClass.lpszMenuName = NULL;
	WndClass.style = CS_HREDRAW | CS_VREDRAW;
	RegisterClass( &WndClass ); // 메인 윈도우에 대한 레지스터를 등록하고

	WndClass.hCursor = LoadCursor( NULL, IDC_CROSS );
	WndClass.lpfnWndProc = ChildProc;
	WndClass.lpszClassName = TEXT("ChildCls");
	WndClass.hbrBackground = (HBRUSH)GetStockObject( LTGRAY_BRUSH );
	RegisterClass( &WndClass ); // 필요한 부분을 변경하여 ChildCls를 또 등록하였다.

	hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, (HMENU)NULL, hInstance, NULL ); // 처음엔 메인 윈도우를 생성, 화면에 보여주고
	ShowWindow( hWnd, nCmdShow );

	while( GetMessage( &Message, NULL, 0, 0 ) )
	{
		TranslateMessage( &Message );
		DispatchMessage( &Message );
	}
	return (int)Message.wParam;
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam )
{
	switch( iMessage )
	{
	case WM_CREATE: // 메인 윈도우가 생성되는 순간 ChildCls 윈도우를 또 등장시키고 있다. 부모 윈도우에서 뭔가 일을 해주고 있지는 않다.
		//CreateWindow( TEXT("ChildCls"), NULL, WS_CHILD | WS_VISIBLE, 
		//	100, 100, 100, 100, hWnd, (HMENU)NULL, g_hInst, NULL );
		CreateWindow( TEXT("ChildCls"), TEXT("PopUp"), WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE, 
			100, 100, 100, 150, hWnd, (HMENU)NULL, g_hInst, NULL );
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return( DefWindowProc( hWnd, iMessage, wParam, lParam));
}
// 차일드 클래스의 함수
LRESULT CALLBACK ChildProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam )
{
	HDC hdc;
	PAINTSTRUCT ps;
	switch( iMessage )
	{
	case WM_LBUTTONDOWN: // 마우스 왼쪽 버튼을 누를때 마다 단순히 그림의 이미지를 바꾸어 준다.
		bEllipse = !bEllipse;
		InvalidateRect( hWnd, NULL, TRUE );
		return 0;
	case WM_PAINT:
		hdc = BeginPaint( hWnd, &ps );
		if( bEllipse ) // 동그라미
		{
			Ellipse( hdc, 10, 10, 90, 90 );
		}
		else // X 표시
		{
			MoveToEx( hdc, 10, 10, NULL );
			LineTo( hdc, 90, 90 );
			MoveToEx( hdc, 10, 90, NULL );
			LineTo( hdc, 90, 10 );
		}
		EndPaint( hWnd, &ps );
		return 0;
	}
	return( DefWindowProc( hWnd, iMessage, wParam, lParam));
}​


예제에 달린 주석을 보면 크게 무리 없이 이해가 갈듯 하다,
RegisterClass를 사용해서 각각 설정을 다르게( 예제에서는 커서와, 호출함수명, 클래스네임, 배경화면)을 바꿔준것을 알 수 있다)
최초에는 WinMain에서는 메인 윈도우만 생성해 주고,
생성 후 WM_CREATE: 에서 또 다른 윈도우를 생성하고 있다.
생성 시에 옵션을 주석 부분처럼 해주게 되면,
새로운 창이지만 크게 티가 나질 않는다(마치 그냥 네모를 그린 느낌?)
그래서 일브로 설정을 약간 바꿔서 팝업으로 띄우게 하였다.

// 실행 화면

'프로그래밍 > API' 카테고리의 다른 글

API-PlaySound  (0) 2010.05.10
API-더블 버퍼링  (0) 2010.05.10
API-WindowLong  (0) 2010.04.24
API-WNDCLASSEX  (0) 2010.04.24
API-대화상자  (0) 2010.04.24