본문 바로가기

Study/Windows System Programming

[Win32API] 2. Win32API 프로그래밍 구조

이 글은 아래 동영상 강의를 참조하여 공부한 내용을 정리한 글 입니다.
https://www.youtube.com/playlist?list=PLOKPEzlY4JKTFx1udqQRdYb1ydob9V5u3

 

1. Win32API 프로그래밍 구조

WinMain()

- 윈도우 구조체 등록, 생성 

   ( 윈도우 구조체를 왜 사용하는가? -> 여러개의 변수를 처리해야 하기 때문에 )

- 메시지 루프 (반복적으로 메시지 체크 후 전달)

 

 

WinMain() 구조

{

윈도우 구조체 설정 및 등록

윈도우 생성과 출력

메시지 루프

}

윈도우 구조체 설정 및 등록, 윈도우 생성과 출력 부분은 한 번만 실행해도 되지만, 메시지 루프는 (사용자의 프로그램 종료 입력 전까지) 프로그램이 꺼지면 안되기 때문에 대기상태에서 반복해서 실행된다.


 

WndProc() 윈도우 프로시져

- 메시지 처리

  (메시지의 실체는 모두 양의 값이다.)

 

WndProc() 구조

{

switch (message)

  case 1 :

  case 2 :

  ...

default : (case에 맞는 상황이 없을 때 실행)

}


 

메시지 전달과 처리 과정

메시지 루프 : 메시지 전달

WndProc() : 메시지 처리

 

// 기본 메시지 루프 <WinMain() 함수 안에 있다.>

// OS의 메시지 큐를 계속 검사하면서 &msg로 메시지를 가져온다.
while (GetMessage(&msg, nullptr, 0, 0))
{
    // 키보드 입력의 정보를 받는 함수
    TranslateMessage(&msg);
    // 메시지를 WndProc()에게 보내주는 함수 <<아주 중요>>
    DispatchMessage(&msg);
}

 

 

 

2. 프로젝트 생성과 문자집합

프로젝트를 만들때 프로젝트 속성에서 멀티바이트 문자 집합을 선택해야 한다. (vs 2013 기준)

멀티바이트 문자집합 : 1~2Byte 크기의 문자집합

유니코드 문자집합 : 2Byte로 전세계 언어를 표현하는 문자집합. ASCll코드 값의 일보는 유니코드와 같다.

 

문자집합에 따라서 변수형에 차이가 있다. (CHAR과 WCHAR, LPSTR과 LPWSTR등..)

또한 멀티바이트에서 유니코드로 변환할 경우도 생기는데, 이 때 유니코드 변환 매크로 함수를 사용한다. (TEXT)

 

 

3. 윈도우 프로그래밍 기본 함수

int WINAPI WinMain() 함수의 원형

#define WINAPI __stdcall (__stdcall : 매개변수를 스택에 넣는 것..? 찾아보니 좀 어렵다.)

 

int APIENTRY _tWinMain()

문자집합 사용에 따라 달라진다. (유니코드 사용시 : wWinMain())

 

WinMain()의 변수들

- hInstance : 실행되고있는 프로그램을 구분하기 위해서 사용. 같은 프로그램은 동일한 값을 갖지만 띄어진 창들은 핸들로 관리한다. (같은 프로그램이라도 여러 개를 띄어놓을 수 있다.)

- hPrevlnstance : 이전 인스턴스 가리키는 값. 지금은 사용하지 않아서 항상 0으로 둔다.

- lpCmdLine : 프로그램 외부에서 내부로 값 결정 (?)

- nCmdShow : 윈도우 출력 형태에 관한 값

 

LRESULT CALLBACK WndProc() 함수의 원형

#define CALLBACK __stdcall

 

WndProc()의 변수들은 WinDef.h에 정의되어있다.

 

 

4. WinMain() 작성 순서

1단계 : 윈도우 구조체 설정

WNDCLASSEX wcex;
wcex.lpfnWndProc = WndProc; // WndProc와 연결
wcex.lpszClassName = "basic"; // OS 구조체를 등록했을때 지정되는 이름
// 이 외에도 마우스 커서 등 다양한 설정값을 줄 수 있다.

 

 

2단계 : 구조체 등록

RegisterClassEx(&wcex)

 

3단계 : 윈도우 생성

HWND hWnd = CreateWindow ()

매개변수로 구조체명, 타이틀 바, 윈도우 스타일 등을 입력하여 윈도우를 생성한다.

 

4단계 : 윈도우 출력

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd)

 

5단계 : 메시지 루프

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

BOOL GetMessage () // 메시지 큐에 메시지를 가져오는 역할
BOOL TranslateMessage () // 문자 키 또는 키 입력에 대한 메시지 변환
LRESULT DispatchMessage () // 메시지가 발생했을 때 프로시저에게 전달하고 반환값이 올때까지 대기

 

 

 

5. WndProc() 작성 순서

WM_PAINT : Updatewindow()함수에 의해 발생하며 윈도우의 일부 영역을 새로 출력할 떄 발생 (OS에서 발생)

WM_DESTORY : 윈도우가 화면에서 사라진 후에 보내지는 메시지, 메모리가 제거되기 직전에 보내진다.

 

1단계 : WM_PAINT 화면 출력

PAOMTSTRUCT ps;
HDC hdc;

switch(message)
{
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps); // 화면 그리기 준비
        
        EndPaint(hWnd, &ps); // 화면 그리기 종료
        break;
}

 

2단계 WM_DESTROY 메시지 처리

switch(message)
{
    case WM_DESTROY:
        // 여기에 메모리 해제 관련 코드
    PostQuitMessage(0); // WM_QUIT 발생
    break;
}

 

 

6. 자동생성 코드 생성과 분석

tWinMain() : 윈도우 프로그램 진입점

MyRegisterClass() : 윈도우 구조체 설정 및 등록

InitInstance() : 등록된 윈도우 구조체를 이용하여 윈도우를 생성, 출력