( 본 게시글은 작성자가 메모용으로 사용하는 용도임을 밝힙니다. 정보가 불확실할 수 있으니 참고 부탁드립니다 )
API는 Application Programming Interface의 약어로, 어플리케이션을 만드는 인터페이스라고 할 수 있다.
여기서 인터페이스 ( Interface )란 서로 다른 두개의 시스템이나 장치 사이에서 정보나 신호를 주고 받는 접점이나 경계면을 뜻한다. UI의 예시로는 핸드폰의 핸드폰과 핸드폰 충전기를 이어주는 충전포트를 생각해볼 수 있고, 게임을 플레이할때 게임 화면을 게임과 유저 사이를 이어주는 UI라고 말할 수 있겠다.Windows API에서의 윈도우는 운영체제의 Window가 아닌 응용 프로그램 안에 작동하는 화면을 의미하는 Window이다.
WinAPI의 동작 방식에서 구성요소는 다음 4가지로 이루어져 있다.
메세지 ( Message ) : 윈도우에 발생하는 모든 이벤트 ( 사건 )
메세지 큐 ( Message Queue ) : 운영체제가 만들어낸 메세지를 저장하는 선입선출 구조의 큐로 먼저 들어온 메세지를 순차적으로 처리한다. 메세지들은 매크로 상수로 변환되어 큐에 저장된다.
메세지 루프 ( Message Loop ) : 메세지 루프는 메세지 큐에 들어있는 메세지를 읽어서 처리를 위해 프로시저로 전송하는 반복문
윈도우 프로시저 ( Window Procedure ) : 메세지 루프에서 변환된 메세지를 받고, 전송받은 메세지를 사전에 정의된 내용에 맞게 처리하는 함수
다음은 Windows API에서 제공하는 자료형이다.
WinAPI를 구현할때 사용하는 자료형으로, 잘 숙지해야한다.
특히 여기서 핸들은 API에서 자주 등장하는 개념으로, 리소스를 안전하게 관리하기 위해 직접적으로 주소를 사용하는 포인터 대신 핸들이라는 개념을 사용한다. 핸들이란 운영체제 내부에 있는 어떤 리소스의 주소를 정수로 치환한 값이다.
따라서 핸들은 오브젝트의 주소를 나타내는 자료형이라고 생각할 수 있고, 대상에게 붙여진 정수 번호라고 할 수 있다.
============================================================================================
Windows API의 기본 구조
Windows API를 구현하기 위한 구조로는 기본적으로 Winmain, Wndproc 함수로 구성된다.
WndProc, 윈도우 프로시저 함수의 선언문이다. 위에서 설명했듯이 메세지를 전달받으면 해당 메세지를 처리하는 역할을 하는 함수이다. 윈도우 프로시저는 메세지를 처리하고 반환할때 LRESULT 타입으로 반환하게 된다.
WndProc 함수 선언문 함수명 앞에 보면 LRESULT와 CALLBACK 키워드가 있는데, LRESULT는 단어뜻대로 결과라는 뜻인데 접두사로 long의 의미를 가지는 L이 붙어서 LRESULT가 된다. WinAPI에서 메세지 처리를 마친 후 운영체제에 신호를 주기 위한 값 ( long type )이다. 즉 윈도우 프로시저가 메세지 처리를 끝냈다고 운영체제에게 알려주는 값이다. long타입의 새로운 이름이라고 볼 수 있다.
다음으로 CALLBACK은 Callback function이라는 의미로, 사용자가 호출하는 함수가 아닌, 특정 트리거에 의해 운영체제가 자동으로 실행하는 함수이다. 즉 윈도우 프로시저는 메세지가 발생하면 자동으로 실행되어 메세지를 확인해서 그에 맞는 행동을 취한다.
윈도우 프로시저의 특징
1. WinMain에서 호출하는 것이 아닌, 윈도우에 의해서 호출된다.
2. WinMain내에 존재하는 메세지 루프는 메세지 처리 전용 함수로 전달하는 역할만 한다.
3. 윈도우 프로시저는 메세지가 들어오면 호출되며, 메세지에 맞게 내용을 처리한다.
4. 콜백 함수 ( Callback Function, 사용자가 호출하는 것이 아닌, 윈도우가 호출하는 함수 ) 이다.
선언문에서 WndProc 함수의 인수로는 HWND handle, UINT Message, WPARAM wParam, LPARAM lParam이 있다.
다음은 윈도우 프로시저의 순서도이다.
============================================================================================
WinMain 함수
WinMain 함수는 API프로그램의 진입점을 잡아주는 역할을 하고, 윈도우를 디자인하고, 생성하는 역할을 한다. WinMain 함수는 다음과 같이 5개의 기능을 한다.
1. WndClass 정의
WndClass는 윈도우 클래스를 의미한다. 윈도우의 기반이 되는 클래스를 윈도우 클래스라고 하는데, 윈도우 클래스 정의는 만들고자 하는 윈도우의 속성을 정의하는 것을 의미한다. 윈도우의 배경색이나, 아이콘 등등을 정의할 수 있다.
위의 예시처럼 속성을 정의해줄 수 있다.
2.WndClass 등록
속성 정의 후 해당 윈도우 클래스를 Register, 등록해야한다. 운영체제가 윈도우 클래스를 인지할 수 있도록 등록하는 과정이다.
위 WndClass 정의 부분에서 중간부분에 WORD wHr = RegisterClassEx(&WndClass)로 등록을 해준것으로 볼 수 있다.
3. 윈도우 생성
윈도우 클래스가 등록되면 메모리에 윈도우 클래스를 올릴 수 있다. 메모리에 윈도우를 만드는 것을 윈도우 생성이라고 한다. 생성되면 이에 대한 핸들값을 알 수 있다. 위의 윈도우 정의 예시 그림에서 desc.handle = CreateWindowEx로 윈도우를 생성한것으로 볼 수 있다.
4. 윈도우 출력
메모리에 생성되면 이제 사용자에게 출력되어야 한다. 윈도우가 시각화하는 것도 WinMain 함수의 역할이다.
위에서 ShowWindow로 윈도우를 출력해주고 있다. 여기서 들어가는 2개의 인수는 출력할 윈도우의 핸들과, 윈도우를 화면에 출력하는 방법을 지정하는 역할이다.
5. 메세지 루프
화면 출력 후 사용자가 사용하기 시작하면 여러가지 메세지( 이벤트 )가 발생된다. 메세지가 언제 들어올지 알 수 없기 때문에 컴퓨터는 메세지 루프를 돌면서 메세지가 발생하는 것을 기다린다. WinMain에서 메세지가 발생할 때까지 메세지 루프를 돌다가, 메세지가 발생하면 해당 메세지를 메세지 처리 전용 함수, 즉 윈도우 프로시저로 메세지를 전달한다.
다음은 WinMain 함수의 코드 부분이다.
여기서 WinMain의 함수의 매개변수에 HINSTANCE가 온것을 알 수 있는데, HINSTANCE는 인스턴스의 핸들로, 인스턴스는 프로그램에 대한 정보라고 할 수 있다. 윈도우 프로시저와 같은 다른 함수들에서 프로그램에 대한 정보가 필요할 수가 있다.
WinMain에서 while반복문이 있는것을 볼 수 있는데, 이는 위에서 설명한 메세지 루프 부분으로 메세지 큐에서 메세지를 읽어들여서 첫번째 인수가 지정하는 메세지 구조체에 저장하게 된다. 위에서 MSG라는 구조체의 Message를 선언했다. 종료를 선언하는 메세지 이외에는 true를 반환하면서 메세지 루프를 돌게 된다. 밑의 TranslateMessage는 문자열이 들어오면 문자열 처리를 위한 메세지를 발생시키는 역할이고, DispatchMessage는 들어오는 메세지를 윈도우 프로시저에 전달하는 역할이다.
실행해보면 위 윈도우 프로시저에서 설정해줬던것처럼 출력이 되는 것을 볼 수 있다.
[Windows API] 윈도우 프로젝트 생성과 WIN32 API의 기본 구조-(1)
목표 Window API를 사용하기 위해서 기본 프로젝트를 생성하는 시간을 갖겠습니다. 목차 ..
chanos.tistory.com