관리 메뉴

HeBhy, since 1983.

WIN32API - 윈도우 생성 기초 본문

Dev/Dev basics

WIN32API - 윈도우 생성 기초

HeBhy 2008. 8. 7. 16:57

#include <windows.h>
ATOM RegisterMainWndClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK MainWndProc(HWND hWnd,UINT message,WPARAM wParam, LPARAM lParam);

// WinMain 함수 부분
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
 // WinMain 함수란?
 // - Win32 API 프로그램의 시작과 종료를 담당하는 함수
 // - 하나의 프로그램 당 오직 하나만이 존재
 //
 // WinMain 함수의 특징 및 형태
 // - WinMain 함수의 함수명, 인자, 리턴값, 호출관례는 임의로 바꿀 수 없음.
 // - WinMain 함수의 형태는 다음과 같음.
 // int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
 //
 // WinMain 함수의 호출과 인자
 //  - 프로그램 시작시 Windows 운영체제에 의해 호출됨.( Entry Point )
 //  - WinMain 함수의 인자는 다음과 같음.
 // HINSTANCE hInstance : 프로그램 인스턴스 핸들
 // HINSTANCE hPrevInstance : 동일한 프로그램의 직전 인스턴스 핸들(Win32 Application 에서는 hPrevInstance는 항상 NULL값을 갖음)
 // LPSTR lpCmdLine : 명령행 인자
 // int nCmdShow : 실행 방식
 //
 // WinMain 함수의 구성
 // WNDCLASS 등록 : 실행할 윈도우 프로그램의 프레임 윈도우를 정의해 등록
 // 인스턴스 초기화 : 프레임 윈도우를 생성해 나타냄
 // 메시지 루프 : 메시지를 읽어 들여 윈도우 프로시주어에게 넘겨 주는 역활을 담당.

 // MSG 구조체
 //  - 이 메세지가 전달될 윈도우의 핸들과 메세지 정보를 발생한 메세지를 처라하는데 필요한 모든 정보를 멤버로 갖는 구조체임.
 MSG msg;

 // WNDCLASS 등록
 if(!RegisterMainWndClass(hInstance))
  return -1;

 if(!InitInstance(hInstance,nShowCmd))
  return -1;

 //메세지 루프 부분

 // 메세지 루프
 //  - 윈도우가 정의되어 생성되고 화면에 나타나서 포커스를 받게 되면, 사용자의 행위에 대해 윈도우에서 메세지가 발생하는데, 이렇게 발생하는 메세지를 받고 분해 처리하는 등의 작업을 함.
 //
 // 메세지 루프를 구성하는 주요 함수
 //  - GetMessage() : 메세지 큐로부터 메세지를 가져와 MSG구조체에 보관함.
 //  - TranslateMessage() : 가상키 메세지로부터 문자 메세지를 생성함.
 //  - DispatchMessage() : 메세지를 메세지 핸들러에게 분배함.
 while (GetMessage(&msg,NULL,0,0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }

 return msg.wParam;
}
//WNDCLASS 등록부분
ATOM RegisterMainWndClass(HINSTANCE hInstance)
{
 // 만들고자하는 윈도우의 기본 내용을 정의한다.

 // WNDCLASS 구조체란?
 //  - 프레임 윈도우의 속성을 정의할때 사용되는 구조체
 //
 // WNDCLASS 구조체의 이용
 //  - 프로그램이 실행되었을 때 나타날 프레임 윈도우의 스타일과 아이콘, 커서, 바탕 브러시, 메뉴 등을  지정할 수 있음.
 //  - 프레임 윈도우가 받게 되는 메시지를 처리할 윈도우 프로시쥬어도 등록할 수 있음.
 //  - WNDCLASS 구조체를 이용하여 정의된 설정 내용은 RegisterClass() 함수를 이용하여 등록함.
 WNDCLASS wc;

 // WNDCLASS 구조체의 멤버 style
 //  - 프레임 윈도우의 성격을 결정하는 스타일을 지정함.
 //  - 이 멤버에 지정할 수 있는 스타일에는 다음과 같은 것들이 있음.
 //  CS_BYTEALIGNCLIENT
 //  CS_BYTEALIGNWINDOW
 //  CS_CLASSDC
 //  CS_DBLCLKS
 //  CS_GLOBALCLASS
 //  CS_HREDRAW
 //  CS_NOCLOSE
 //  CS_OWNDC
 //  CS_PARENTDC
 //  CS_PARENTDC
 //  CS_SAVEBITS
 //  CS_VREDRAW
 wc.style = 0;

 //  WNDCLASS 구조체의 멤버 lpfnWndProc
 //  - 윈도우 프로시저를 지정하는데, 이 멤버에 지정하는 함수의 원형은 다음과 같다.
 // LRESULT CALLBACK MainWndProc(HWND hWnd,UINT message,WPARAM wParam, LPARAM lParam)
 //  * MainWndProc 이라는 함수명은 프로그래머가 임의로 정할 수 있는것으로, 위의 WNDCLASS 등록 예에서는 MainWndProc 이라 명명한 경우임.
 wc.lpfnWndProc = MainWndProc; // () 함수 호출 () 없으면 주소 값
 
 // WNDCLASS 구조체의 멤버 cbClsExtra와 cbWndExtra
 //  - 각각 클래스 확장 바이트와 인스턴스 확장 바이트를 지정함.
 //  - MDI 윈도우를 만들거나 특별한 방법으로 다이얼로그를 만드는 경우를 제외하고는 이 멤버는 0으로 지정되어야 함.
 wc.cbClsExtra = 0;
 wc.cbWndExtra = 0;
 
 //  WNDCLASS 구조체의 멤버 hInstance
 //  - 이 클래스의 윈도우 프로시쥬어가 속한 인스턴스를 저정함.
 //  - WndMain 함수 내부 RegisterMainWndClass() 함수의 인자를 통해 넘겨진 hInstance 를 지정함.
 // if(!RegisterMainWndClass(hInstance))
 //  return -1;
 
 //  WNDCLASS 구조체의 멤버 hInstance
 //  - 이 클래스의 윈도우 프로시쥬어가 속한 인스턴스를 저정함.
 //  - WndMain 함수 내부 RegisterMainWndClass() 함수의 인자를 통해 넘겨진 hInstance 를 지정함.
 wc.hInstance = hInstance;
 
 //  WNDCLASS 구조체의 멤버 hIcon
 //  - 이 프로그램의 실행 파일을 나타내는 아이콘이 지정됨.
 //  - 이 멤버에 지정하는 아이콘을 적재할 때는 LoadIcon()함수를 사용함.
 wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
 
 //  WNDCLASS 구조체의 멤버 hInstance
 //  - 이 프로그램이 실행되어 만들어지는 윈도우에서 사용 될 커서를 지정함.
 //  - 이 멤버에 지정하는 커서를 적재할 때는 LoadCursor() 함수가 사용됨.
 wc.hCursor = LoadCursor(NULL,IDC_ARROW);
 
 //  WNDCLASS 구조체의 멤버 hInstance
 //  - 윈도우의 바탕 브러시를 지정함.
 //  - 이 멤버에 지정하는 내장 프러시를 얻을 때는 GetStockObject() 함수가 사용됨.
 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 
 //  WNDCLASS 구조체의 멤버 hInstance
 //  - 메뉴 이름을 지정함.
 //  - 이 멤버에 NULL을 지정하면 윈도우가 기본 메뉴를 갖지 않게 됨.
 wc.lpszMenuName = NULL;
 
 //  WNDCLASS 구조체의 멤버 hInstance
 //  - 클래스 이름을 지정함.
 //  - 이 멤버에 지정하는 이름은 이후 CreateWindow()함수나 CreateWindowEx() 함수에서 사용하게 됨.
 wc.lpszClassName = "Hello World";

 return RegisterClass(&wc);

 // 등록된 클래스의 식별번호를 리턴하는데, 만일 클래스 등록이 실패하였다면 0을 리턴함.
}
// 인스턴스 초기화 하는 부분
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
 // 윈도우를 생성한다. 메모리상에만 생성이 되어 있다.
 HWND hWnd;
 // CreateWindow 함수란?
 //  - 윈도우를 생성하는 함수로, 윈도우 제목, 스타일, 위치와 크기, 메뉴 등을 지정할 수 있음.
 //  - 생성된 윈두우의 핸들값( HWND형 ) 을 리턴하며, 만일 창 생성에 실패하면 NULL을 리턴함.
 //
 // CreateWindow 함수의 원형과 각 인자
 // HWND CreateWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName,
 //     DWORD dwStyle, int X, int Y, int nWidth, int nHeight,
 //     HWND hWndparent, HMENU hMenu,
 //     HINSTANCE hinstance,LPVOID lpParam);
 //
 //
 // LPCTSTR lpClassName : 동륵된 클래스 이름을 지정함. 이 이름은 WNDCLASS의 멤버 lpszClassName에 지정한 문자열이 되어 생성하는 윈도우의 정보를 제공함.
 // LPCTSTR lpWindowName : 윈두우의 이름을 지정함.
 // DWORD dwStyle : 윈두우의 기본 스타일을 지정함.
 // dwStyle종류
 //  WS_BORDER
 //  WS_CAPTION
 //  WS_CHILD
 //  WS_CHILDWINDOW
 //  WS_CLIPCHILDREN
 //  WS_CLIPSIBLINGS
 //  WS_DISABLED
 //  WS_DLGFRAME
 //  WS_GROUP
 //  WS_HSCROLL
 //  WS_ICONIC
 //  WS_MAXIMIZE
 //  WS_MAXIMIZEBOX
 //  WS_MINIMIZE
 //  WS_MINIMIZEBOX
 //  WS_OVERLAPPED
 //  WS_OVERLAPPEDWINDOW
 //  WS_POPUP
 //  WS_POPUPWINDOW
 //  WS_SIZEBOX
 //  WS_SYSMENU
 //  WS_TABSTOP
 //  WS_THICKFRAME
 //  WS_TILED
 //  WS_TILEDWINDOW
 //  WS_VISIBLE
 //  WS_VSCROLL
 // int X, int Y, int nWidth, int nHeight : 윈도우의 가로시작(X), 세로시작(Y), 폭(nWidth), 높이(nHeight)를 지정함.
 //          이 인자들에 CW_USEDEFAULT를 지정하는것은 Windows 운영체제가 윈두우의 좌표와 크기를 결정하도록 한다는 의미임
 // HWND hWndparent : 만들어질 윈도우의 부모 윈도우를 지정함. 이 인자에 NULL을 지정 하는 것은 이 윈두우가 부무 윈두우를 갖지 않는다는 의미임.
 // HMENU hMenu : 동적 메뉴 또는 자식 윈도우의 식별 번호를 지정함. 이 인자에 NULL 을 지정하는 것은 동적 메뉴를 갖지 않는다는 의미임.
 // HINSTANCE hinstance : 만들어질 윈도우에 연결되어 있는 인스턴스를 지정함.
 // LPVOID lpParam : CREATESTRUCT을 통해 전달할 추가 정보를 지정함. 이 인자에 NULL을 지정하는 것은 CREATESTRUCT을 통해 전달할 추가 정보가 없다는 의미임.
 //
 // CreateWindowEx 함수란?
 //  - CreateWindow 함수의 인자와 동일하지만 확장 스타일을 정할 수 있는 dwExStyle 인자가 인자의 제일 앞에 하나 더 존재함.
 // HWND CreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName,
 //     DWORD dwStyle, int X, int Y, int nWidth, int nHeight,
 //     HWND hWndparent, HMENU hMenu,
 //     HINSTANCE hinstance,LPVOID lpParam);
 // CreateWindowEx함수를 통해 지정할수 있는 확장 스타일
 //  WS_EX_ACCEPTFILES
 //  WS_EX_APPWINDOW
 //  WS_EX_CLIENTEDGE
 //  WS_EX_CONTEXTHELP
 //  WS_EX_CONTROLPARENT
 //  WS_EX_DLGMODALFRAME
 //  WS_EX_LEFT
 //  WS_EX_LEFTSCROLLBAR
 //  WS_EX_LTRREADING
 //  WS_EX_MDICHILE
 //  WS_EX_NOPARENTNOTIFY
 //  WS_EX_OVERLAPPEDWINDOW
 //  WS_EX_PALETTENWINDOW
 //  WS_EX_RIGHT
 //  WS_EX_RIGHTSCROLLBAR
 //  WS_EX_RTLREADING
 //  WS_EX_STATICEDGE
 //  WS_EX_TOOLWINDOW
 //  WS_EX_TOPMOST
 //  WS_EX_TRANSPARENT
 //  WS_EX_WINDOWEDGE
 hWnd = CreateWindow("Hello World","Hello World",
  WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT,CW_USEDEFAULT,
  CW_USEDEFAULT,CW_USEDEFAULT,
  NULL,NULL,hInstance,NULL);

 if(!hWnd)
  return FALSE;

 // 화면상에 윈도우를 보여준다.

 // ShowWindow 함수란?
 //  - 윈도우를 표시 방법에 맞게 나타냄.
 //
 // ShowWindow 함수의 두번째 인자.
 //  SW_FORCEMINIMIZE
 //  SW_HIDE
 //  SW_MAXIMIZE
 //  SW_MINIMIZE
 //  SW_RESTORE
 //  SW_SHOW
 //  SW_SHOWDEFAULT
 //  SW_SHOWMAXIMIZED
 //  SW_SHOWMINIMIZED
 //  SW_SHOWNA
 //  SW_SHOWNORMAL
 //  SW_SHOWMINNOACTIVE
 //  SW_SHOWNOACTIVATE
 //
 // ShowWindow 함수의 두번째 인자를 위처럼 인자로 전달 받은 nCmdShow로 지정하면 ..?
 //  - 윈도우의 표시 방법은 이 프로그램에 대한 바로가기의 실행 방식에 의해 다음과 같이 달라짐.
 // 기본윈도우 : SW_SHOWNORMAL
 // 최대화 : SW_SHOWMAXIMIZED
 // 최소화 : SW_SHOWMINNOACTIVE
 ShowWindow(hWnd,nCmdShow);

 // 윈도우를 업데이트를 한다.

 // UpdateWindow 함수
 //  - 나타난 윈도우의 화면을 갱신함.
 //  - 이 함수는 WM_PAINT메시지를 윈도우 프로시저에게 전달함으로써, 윈도우가 갱한되도록 함.
 UpdateWindow(hWnd);

 return TRUE;
}
// 윈도우 프로시져 부분
LRESULT CALLBACK MainWndProc(HWND hWnd,UINT message,WPARAM wParam, LPARAM lParam)
{
 // 윈도우 프로시주어란?
 //  - 프래임 윈도우에서 발생하는 메세지를 처리하는 함수
 //  - WNDCLASS 구조체 멤버 lpfnWndProd에 의해 함수명으로 등록됨.
 //
 // 윈도우 프로시쥬어의 특징
 //  - 윈도우 프로시쥬어의 함수명은 임의로 변경할 수 있음.
 //  - 인자, 리턴값, 호출 관례는 임의로 변경할 수 없음.
 //
 // 윈도우 프로시쥬어가 갖는 인자
 //  - HWND hWnd : 메세지를 받는 윈도우 핸들
 //  - UINT message : 메세지 식별 번호
 //  - WPARAM wParam : 32-비트 추가 정보
 //  - LPARAM lParam : 32-비트 추가 정보
 //
 // 일반적인 윈도우 프로시쥬어의 예
 //  - 전형적으로 윈도우 프로시쥬어는 처리할 메세지에 따라 조건 분기하는 switch문을 가짐.
 //  - 처리하고자 하는 메세지 : case 문에서 처리한 다음 0을 리턴
 //  - 그렇지 않은 메세지 : default 에서 DefWindowProc 함수에 넘겨 표준적인 방법으로 처리되게 한 다음 그 결과를 리턴.
 switch( message )
 {

 case WM_DESTROY:
  PostQuitMessage(0);
  break;
 // 반드시 정의 해줘야 한다.
 // 위에서 정의 하지 않은 메세지들이 정상적으로 작동하지 않을수 있다.
 default:
  return DefWindowProc(hWnd,message,wParam,lParam);
 }
 return 0;
}

Comments