자 먼저, CreateWindow의 함수 원형을 살펴보도록 합시다.
HWND CreateWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HANDLE hInstance, LPVOID lpParam);
위 원형을 보면, 첫번째 인수에는 클래스 이름이 옵니다. 전에 RegisterClass 또는 RegisterClassEx 함수로 생성된 ATOM 클래스의 포인터, 혹은 문자열이 이곳에 위치합니다. 두번째 인자로는 윈도우의 타이틀바에 나타나는 제목입니다. 세번째 인자로는 윈도우의 스타일이 들어갑니다. 아래는 dwStyle에 들어갈 수 있는 값들입니다.
코드 | 설명 |
---|---|
WS_OVERLAPPED | 디폴트 윈도우. 타이틀 바와 크기 조절이 안되는 경계선을 가진다. 아무런 스타일도 주지 않으면 이 스타일이 적용된다. |
WS_POPUP | 팝업 윈도우를 만든다. WS_CHILD와 함께 쓸 수 없다. |
WS_CHILD | 차일드 윈도우를 만든다. WS_POPUP과 함께 쓸 수 없다. |
WS_MINIMIZE | 최초 최소화된 상태로 윈도우를 만든다. |
WS_VISIBLE | 윈도우를 만들자 마자 화면에 출력한다. |
WS_DISABLED | 사용금지된 상태, 즉 입력을 받아들일 수 없는 상태로 만든다. |
WS_CLIPSIBLINGS | 차일드끼리 상호 겹친 영역은 그리기 영역에서 제외된다. |
WS_CLIPCHILDREN | 차일드가 위치한 영역은 그리기 영역에서 제외된다. |
WS_MAXIMIZE | 최초 최대화된 상태로 윈도우를 만든다. |
WS_CAPTION | 타이틀 바를 가진 윈도우를 만들며 WS_BORDER 스타일을 포함한다. |
WS_BORDER | 단선으로 된 경계선을 만들며 크기 조정은 할 수 없다. |
WS_DLGFRAME | 두꺼운 경계선을 가지며 타이틀 바를 가질 수 없다. |
WS_VSCROLL | 수직 스크롤 바를 가진 윈도우를 만든다. |
WS_HSCROLL | 수평 스크롤 바를 가진 윈도우를 만든다. |
WS_SYSMENU | 시스템 메뉴를 가진 윈도우를 만든다. |
WS_THICKFRAME | 크기 조정이 가능한 두꺼운 경계선을 가진다. |
WS_GROUP | 라디오 버튼 등 그룹을 이루는 컨트롤의 그룹 지정에 사용된다. |
WS_TABSTOP | Tab키로 포커스를 이동할 수 있도록 한다. |
WS_MINIMIZEBOX | 최소화 버튼을 만든다. |
WS_MAXIMIZEBOX | 최대화 버튼을 만든다. |
WS_OVERLAPPEDWINDOW | 가장 일반적인 윈도우 스타일. WS_OVERLAPPED |WS_CAPTION |WS_SYSMENU |WS_THICKFRAME |WS_MINIMIZEBOX |WS_MAXIMIZEBOX 스타일들이 조합된 스타일이다. |
WS_POPUPWINDOW | 일반적인 팝업 윈도우. WS_POPUP |WS_BORDER |WS_SYSMENU |
WS_CHILDWINDOW | WS_CHILD와 같다. |
이어서 네번째와 다섯번째 인수를 보시면 윈도우의 위치를 나타냅니다. 여섯번째와 일곱번째 인수를 보시면 윈도우의 크기를 나타냅니다. 여덟번째 인수는 부모 윈도우가 존재할경우 이곳에 부모 윈도우의 핸들을 지정합니다. 아홉번째 인수로는 윈도우에서 사용할 메뉴의 핸들을 지정합니다. 열번째 인수에서는 윈도우와 연결될 인스턴스 핸들입니다. 열한번째 인수에는 lParam에 CREATESTRUCT 구조체를 담아 WM_CREATE 메시지로 전달하기 위한 값의 포인터를 의미합니다. 아래 예를 한번 봅시다.
// 함수: InitInstance(HINSTANCE, int) // // 목적: 인스턴스 핸들을 저장하고 주 창을 만듭니다. // // 설명: // // 이 함수를 통해 인스턴스 핸들을 전역 변수에 저장하고 // 주 프로그램 창을 만든 다음 표시합니다. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다. hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE;
위를 보시면 CreateWindow는 윈도우를 생성할 뿐이지, 이를 화면에 표시하려면 ShowWindow 함수에 출력하고자 하는 윈도우의 핸들을 넘겨야 합니다. 이번엔 ShowWindow 함수에 대해서 알아볼까요? 다음은 ShowWindow의 함수 원형입니다.
BOOL ShowWindow(HWND hWnd, int nCmdShow);
첫번째 인수로는, 화면에 표시할 윈도우의 핸들을 의미합니다. 두번째 인수로는 화면 출력 옵션인데, 보통 WinMain로 전달된 인자의 nCmdShow를 그대로 입력하면 됩니다. 지정할수 있는 값은 아래와 같습니다.
코드 | 설명 |
---|---|
SW_FORCEMINIMIZE | 2000 이후에만 쓸 수 있는 플레그이다. 윈도우를 소유한 스레드가 블록된 상태에서도 윈도우를 최소화시킨다. |
SW_HIDE | 윈도우를 숨긴다. |
SW_MAXIMIZE | 윈도우를 최대화시킨다. |
SW_MINIMIZE | 윈도우를 최소화시키며 다음 Z순서를 가지는 윈도우가 활성화된다. |
SW_RESTORE | 최대, 최소화된 윈도우를 이전 위치로 복구한다. |
SW_SHOW | 윈도우를 활성화하며 보인다. |
SW_SHOWDEFAULT | STARTUPINFO 구조체가 지정하는 보이기 상태로 만든다. |
SW_SHOWMAXIMIZED | 윈도우를 최대화된 상태로 활성화한다. |
SW_SHOWMINIMIZED | 윈도우를 최소화한 상태로 활성화한다. |
SW_SHOWMINNOACTIVE | 윈도우를 최소화 상태로 보이며 활성화 상태는 변경되지 않는다. |
SW_SHOWNA | 윈도우를 헌재 상태로 보이며 활성화 상태는 변경되지 않는다. |
SW_SHOWNOACTIVATE | 최근 크기와 위치에 윈도우를 보이며 활성화 상태는 변경되지 않는다. |
SW_SHOWNORMAL | 윈도우를 보이며 활성화한다. 만약 윈도우가 최소화되어 있거나 최대화되어 있다면 윈도우를 원래 크기대로 복구한다. 윈도우를 처음 화면에 보일 때는 이 플래그를 사용해야 한다. |
이번에는 CreateWindow의 전달되는 인수값을 바꿔서 코드를 수정했습니다. 다음 코드는 어떨지 한번 예상해봅시다.
예제보기
// 함수: InitInstance(HINSTANCE, int) // // 목적: 인스턴스 핸들을 저장하고 주 창을 만듭니다. // // 설명: // // 이 함수를 통해 인스턴스 핸들을 전역 변수에 저장하고 // 주 프로그램 창을 만든 다음 표시합니다. // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다. hWnd = CreateWindow(szWindowClass, L"타이틀", WS_BORDER, CW_USEDEFAULT, 0, 500, 500, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; }
결과보기
위와 같이 단선으로 된 경계선을 가지고, 타이틀이란 제목을 가진 가로 500, 세로 500인 창이 화면에 표시됩니다. 윈도우가 만들어지는 과정은 다음과 같습니다. ‘윈도우 클래스 정의 -> 윈도우 클래스 등록 -> 윈도우 생성 -> 윈도우 표시 -> 메세지 루프’와 같이 이루어집니다.