1. 이벤트 반응형

 

콘솔에서 동작하는 프로그램은 순차적으로 실행을 하지만, GUI 프로그램은 메뉴 선택, 클릭 등의 사용자에 의해 생긴 이벤트에 따라 코드가 실행된다

 

이벤트 반응형

 사용자 조작으로 이벤트가 발생하고 대응되는 처리를 하는 프로그램 형식

 

이벤트의 발생

하드웨어의 장치 드라이버에서 마우스나 키보드 등의 이벤트를 감시하여 이벤트를 이벤트 처리 대기 행렬(시스템 행렬) 추가하여 Window 통지

Windows에서 필요에 따라 애플리케이션에 알림

큐에서 꺼낸 이벤트 정보와 시점의 애플리케이션의 상태를 이용하여 이벤트가 통지될 애플리케이션 결정

 

2.       메시지

 

애플리케이션 윈도우에 이벤트 통지하기 위한 데이터 구조체

typedef struct tagMSG {

                  HWND                      hwnd;                      // 윈도우 핸들

                  UNIT                         message;               // 메시지 ID

                  WPARAM               wParam;                // 메시지 전달인자 1

                  LPARAM                  lParam;                    // 메시지 전달인자 2

                  DWORD time;                       // 이벤트 발생 시각

                  POINT                      pt;                            //이벤트 발생 커서 위치

                  } MSG, *PMSG;   

 

1)      윈도우 핸들

메시지의 행선지가 윈도우를 식별하는 정수

윈도우 핸들 값을 조사하여 조작 대상 윈도우 구별

 

2)      메시지 ID
메시지의 종류를 나타내는 아이디

일반적으로 ‘WM_’으로 시작되는 ID 수백 정의

발생한 이벤트의 종류 알아낼 있음

 

3)      메시지 전달 인자 1 & 메시지 전달 인자 2

메시지의 전달 인자

메시지의 종류에 따라 의미 상이

 

4)      이벤트 발생 시각

5)      이벤트 발생 커서 위치

 

메시지 큐에서 메시지를 꺼내 처리하는 것을 반복한다 (메시지 루프)

3.       윈도우 프로시저

 

메시지의 행선지인 윈도우의 윈도우에 관련된 특별함수(윈도우 프로시저)에서 메시지 처리

 

윈도우 프로시저가 Windows 직접 호출함으로, 정해진 규약이 있음 -> CALLBACK

 

-          인자 4

-          MSG 구조체 멤버와 대응

 

LRESULT CALLBACK WindowProc (

                  HWND hwnd,        // 윈도우 핸들

                  UINT uMSG,          // 메시지 ID

                  WPARAM wParam,              // 메시지 전달 인자1

                  LPARAM lParam   // 메시지 전달 인자2

                  );

 

윈도우 클래스

동일한 기능을 하는 윈도우가 여러 존재 경우, 윈도우 클래스로 그룹화하여 윈도우 프로시저로 여러 윈도우 처리

윈도우 클래스와 윈도우의관계는 클래스와 인스턴스의 관계

같은 윈도우 프로시저 공유

 

윈도우 클래스 등록

애플리케이션의 메인 윈도우로 사용할 있는 윈도우 클래스는 미리 제공되지 않아, 직접 생성하는 윈도우 클래스는 직접 등록

 

4.       WinMain

 



 

#include <Windows.h> //(1)

 

#define MYWNDCLSNAME                  L"MyWindowsClass"

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParma);

 

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) //(2)

{

  WNDCLASS wndcls;

  HWND hWnd;

  MSG msg;

 

  //윈도우 클래스 등록 (3)

  ZeroMemory(&wndcls, sizeof(wndcls));

  wndcls.lpfnWndProc = WndProc;

  wndcls.hInstance = hInst;

  wndcls.hIcon = LoadIcon(0, IDI_APPLICATION);

  wndcls.hCursor = LoadCursor(0, IDC_ARROW);

  wndcls.hbrBackground = (HBRUSH)COLOR_BACKGROUND;

  wndcls.lpszClassName = MYWNDCLSNAME;

  if (RegisterClass(&wndcls) == 0) return -1;

 

  // 메인 윈도우 생성 (4)

  hWnd = CreateWindow(MYWNDCLSNAME, L"My Window",

                   WS_OVERLAPPEDWINDOW,

                   CW_USEDEFAULT, CW_USEDEFAULT,

                   CW_USEDEFAULT, CW_USEDEFAULT,

                   0, 0, hInst, NULL);

  if (hWnd == 0) return -2; //(5)

 

  // 윈도우 초기 출력 상태 지정

  ShowWindow(hWnd, nCmdShow); //(6)

  UpdateWindow(hWnd); //(7)

 

  //메시지 루프(8)

  while(GetMessage(&msg, 0, 0, 0)){

                   DispatchMessage(&msg);

  }

 

  //WM_QUIT 메시지의 wParam 종료 코드로 한다.

  return msg.wParam;

}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) //(9)

{

  switch (uMsg){

  case WM_DESTROY :

                                     PostQuitMessage(0);

                                     return 0;

  }

  // 직접 처리하지 않은 메시지는 Windows 맡긴다

  return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

 

(1)    Windows.h

Win32 API C언어 함수에서 호출할 필요한 프로토타입 선언이 들어 있음

(2)    WinMain

Windows GUI 애플리케이션이 실행될 제일 먼저 실행되는 함수

hInst

실행중인 애플리케이션을 식별하는 정수값(인스턴스 핸들)

Win32에서는 값으로 애플리케이션 식별 불가능

애플리케이션 자체를 참조하기 위해 인자로 사용하는 경우 필요한 경우가 있어 전역 변수로 보존

hPrevInst

16비트 Windows에서 동일한 애플리케이션이 이미 실행중일 먼저 실행된 애플리케이션의 인스턴스 핸들이 저장됨

Win32에서는 항상 0

호환성을 위해 유지

lpCmdLine

명령행 문자열의 포인터로, main argv 달리 스스로 문자열 해석해야함

nCmdShow

메인 윈도우의 최초 출력 상태를 지정

 

(3)    윈도우 클래스

(4)    윈도우 클래스 등록

RegisterClass API 윈도우 클래스를 등록

등록하려는 윈도우 클래스 정보를 WNDCLASS 구조체에 저장하여 RegisterClass WNDCLASS 주소를 인자로 넘김

 

 

typedef struct _WNDCLASS{

  UINT                         style;                        // 윈도우 클래스 스타일

  WNDPROC                               lpfnWndProc;       // 윈도우 프로시저의 주소

  int                              cbClsExtra;             // 윈도우 클래스의 추가 데이터 크기

  int                              cbWndExtra;         // 윈도우의 추가 데이터 크기

  HINSTANCE            hInstance;              // 윈도우 프로시저를 소유한 프로그램의

                                                                        // 인스턴스 핸들(대부분 자기자신)

  HICON                      hIcon;                       // 애플리케이션 아이콘

  HCURSOR                                 hCursor;                  // 마우스 커서

  HBRUSH                  hbrBackground;   // 윈도우 배경색

  LPCTSTR                  lpszMenuName;  // 메뉴 리소스명

  LPCTSTR                  lpszClassName;    // 윈도우의 클래스 등록명

                  } WNDCLASS, *PWNDCLASS;

 

(5)    윈도우 생성

 

CreateWindow API 윈도우 클래스의 이름, 윈도우의 이름, 윈도우 속성을 인자로 넘김

WS_OVERLAPPEDWINDOW  - 메인 윈도우에서 주로 사용되는 윈도우 속성의 상수

 

CW_USEDEFAULT

윈도우를 출력하는 위치와 윈도우 크기를 Windows 맡김

부모윈도우와 메뉴핸들은 0 넘김

 

CreateWindow

윈도우 생성에 성공하면 윈도우 핸들 반환

반환값이 0 경우 윈도우 생성이 실패했음을 의미하므로 애플리케이션 종료

 

ShowWindow

생성한 윈도우의 출력 상태를 설정하는 API

 

UpdateWindow

실제로 윈도우를 그리는 API

 

(6)    메시지 루프

 

GetMessage

메시지 큐에서 메시지를 꺼냄

MSG 구조체의 주소에 꺼내온 메시지 정보를 저장

BOOL 형태의 반환값을 가지며, 애플리케이션 종료를 의미하는 WM_QUIT 메시지를 꺼냈을 때만 FALSE 메시지 반환

 

DispatchMessage

MSG hWnd 멤버를 참조하여 윈도우 프로시저를 윈도우에 호출 요청

 

(7)    DefWindowProc

 

메시지의 종류가 매우 많으므로 애플리케이션 고유의 처리를 원하는 메시지를 제외하고 DefWindowProc API에서 기본 처리

 

 

PostQuitMessage

WM_DESTROY 메시지를 DefWindowProc 호출하여 처리할 경우, 윈도우만 종료되고 애플리케이션을 종료하지 않기 때문에 따로 처리

WM_QUIT 메시지를 메시지큐에 추가하는 API

 

   

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

  switch (uMsg){

  case WM_LBUTTONDOWN:

                   MessageBox(hWnd, L"Hello, World", L"Message",

                                     MB_OK | MB_ICONINFORMATION);

  case WM_DESTROY :

                                     PostQuitMessage(0);

                                     return 0;

  }

  // 직접 처리하지 않은 메시지는 Windows 맡긴다

  return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

 

'Operating Systems > Windows' 카테고리의 다른 글

윈도우  (0) 2015.04.23
API로 배우는 커널 - 1.운영체제 구조  (0) 2015.04.12

+ Recent posts