Mafa Dev

[API] 윈도우 프로그램의 구조 본문

개발/API 프로그램

[API] 윈도우 프로그램의 구조

마파_ 2013. 2. 23. 04:55

콘솔 기반의 C언어 프로그램은 메인 함수를 기본으로 , 필요에 따라 다른 함수를 추가합니다.

반면 , 윈도우 프로그램은 크게 메인 부분과 메시지 처리 부분으로 나눕니다.

 

메인 부분에서는 윈도우를 만들고 화면에 윈도우를 띄우며 윈도우에서 발생하거나 응용 프로그램과 관련해 발생하는 모든 메시지를 전송하는 역할을 합니다. 엄밀히 말하면 메시지는 이벤트가 발생하면 오는 신호이고 , 신호는 윈도우 커널이 보냅니다. 메인 부분은 이를 하나씩 받아서 메시지 처리 부분으로 보냅니다.

 

메시지 처리 부분은 메시지를 받아 메시지에 약속된 반응을 보입니다. 메시지에는 마우스의 움직임이나 버튼 클릭에 따른 메시지, 키보드 눌림에 따른 메시지, 다양한 컨트롤에서 발생하는 메시지 , 메뉴에서 발생한느 메시지 등이 있습니다.

 

콘솔 모드 C언어 프로그램에서는 메인 함수가 main() 이지만 , 윈도우 프로그램의 메인 함수는 Winmain()입니다. 이 함수의 반환 타입이 프로그램의 정상 종료와 비정상 종료를 정수로 알려줍니다. 그리고 WINAPI는 프로그램이 윈도우 응용 프로그램임을 알립니다.

 

 

윈도우 프로그램에서는 WinMain()에서 보내온 메시지를 처리하기 위해 메시지 처리 함수가 필요합니다. 앞의 윈도우 프로그램 함수 구성에서는 함수 이름을 WndProc()라고 하였습니다. WndProc라는 함수 이름은 WinMain()에서 윈도우 클래스를 등록할 때 같이 등록되어야 합니다. CALLBACK은 WndProc() 함수가 콜백 함수임을 알려줍니다. 콜백 함수는 누군가가 직접 호출하지 않고 신호에 의해 자동호출되는 함수입니다. WndProc() 함수는 LRESULT 타입의 값을 반환하는데 이는 32비트의 값을 반환함을 뜻합니다.

 

WinMain() 함수 

 int WINAPI WinMain  (  HINSTANCE hInstance , HINSTANCE hPrevInstance ,

                                  PSTR szCmdLine , int iCmdShow )

 

   첫 번째 HINSTANCE 타입 : 프로그램에 커널이 부여해주는 ID로써 메모리에 적재된 많은 응용 프로그램으로부터 프로그램을 구분하려고 사용한다. 프로그램이 수행될 때 부여받는다.

 

   두 번째 HINSTACE 타입 : 이전에 부여받은 값으로 , 지금은 사용하지 않으므로 신경쓰지 않습니다.

 

   PSTR 타입 : 엄밀하게 말하면 다르지만 간단하게 char * 와 같다고 보면 됩니다. 즉 문자열이 넘어온다는 것입니다.

 

   int 타입 : 정수값으로 윈도우가 화면에 출력될 때 형태를 정의합니다. 이 값은 커널에 의해 넘어 옵니다.

 

 

 

메세지 처리

1. 키보드 , 마우스 등에 의해 이벤트가 발생한다.

2. 발생한 이벤트를 윈도우 시스템이 감지한다.

3. 이벤트 발생을 알린다. 이벤트 발생을 알리는 방식 중 정수값인 메시지를 보내는 방식을 택한다. 보내온 메시지가 메시지 큐에 차례로 쌓힌다.

4. WinMain()은 메시지 큐에서 맨 앞에 대기 중인 메시지를 꺼낸다.

5. 꺼낸 메시지를 해석해 메시지 처리 함수에 보낸다. 메시지를 꺼내고 해석해 보내는 과정은 while문이다. GetMessage() 함수가 메시지 큐에서 메시지를 꺼낸다. 꺼낸 메시지는 msg변수에 저장하고 TranslateMessage() 함수로 변형합니다. TranslateMessage() 함수는 두 메시지를 하나로 변형할 때 사용됩니다. 만약 Shift + A를 누르면 키보드를 두 번 누른 것으로 처리하는 것이 아니고 A를 한 번 누른 것으로 처리해야 합니다. 이와 같이 메시지를 변환할 때 TranslateMessage() 함수를 이용합니다. 마지막으로 DispatchMessage() 함수는 메시지를 처리하는 함수에 메시지를 보냅니다.

6. 메시지 처리 함수가 WndProc()이라면 WndProc() 함수는 메시지를 받아서 반응을 보입니다. 반응은 주로 화면에 출력으로 나타납니다.

 

 

메세지 처리함수 : WndProc()

 

WndProc() 함수 

 LRESULT WndProc(

           HWND         hWnd ,

           UINT           iMsg,

           WPARAM    wParam,

           LPARAM     LParam

);

 

WndProc()에 넘어오는 매개변수 값을 살펴보면 다음과 같습니다.

   hWnd : 생성된 윈도우의 핸들 값. WinMain()에서  CreateWindow() 함수를 이용해서 생성합니다.

   imsg : 양의 정수인 UNIT 타입의 메시지 번호. 메시지 번호 값은 양의 정수이지만 프로그래머가 각 이벤트에 따른 숫자를 기억하기 어렵기 때문에 매크로를 이용해 기억하기 쉽게 정의하였습니다. 예를 들면 키보드가 눌러졌을때 메시지는 WM_KEYDOWN으로 표현해 사용된 단어만 봐도 어떤 이벤트에 대한 메시지 인지 알 수 있습니다.

   wParam , lParam : 32비트 값으로 메시지의 종류에 따라 값을 해석하는 방법이 다릅니다. 키보드에서 눌러진 문자의 코드 값이 들어 있을 때도 있고 마우스의 위치가 들어 있을 때도 있습니다. 해석 방법은 두 번째 매개변수의 값에 따라 달라집니다.

 

메시지 종류에 따라서 처리를 다르게 해야 하므로 WndProc() 함수에는 switch 문이 필요합니다. 모든 메시지에 대해 case 문을 만들 필요는 없고 프로그램에서 처리를 원하는 메시지만 case문을 만듭니다. 나머지 메시지는 커널이 처리할 수도 있기 때문에 넘겨받은 모든값을 DefWindowProc() 함수를 호출해 넘겨줍니다. DefWindowProc()은 윈도우에서 발생하는 메시지 중 윈도우 메시지 처리 함수에서 처리하지 않은 것을 기본 메시지 처리 함수에서 담당합니다. 기본 메시지 처리 함수 덕분에 윈도우에서 발생하는 모든 메시지를 처리할 수 있습니다. DefWindowProc() 함수는 윈도우 메시지 처리 함수와 동일한 매개변수로 호출합니다.

 

'개발 > API 프로그램' 카테고리의 다른 글

[API] 출력 영역 얻기  (0) 2013.02.23
윈도우 창 생성하기 소스( 주석 포함 )  (0) 2013.02.23