002. 윈도우프로그래밍의 기본 -...

31
1 DB & MINING LAB. Korea University 002. 윈도우프로그래밍의 기본 이 종 욱 [email protected] 윈도우 프로그래밍 및 실습 since 2007. 09. 03 updated 2012. 08. 18 last updated 2015. 08. 25

Upload: others

Post on 29-Aug-2019

1 views

Category:

Documents


0 download

TRANSCRIPT

1

DB & MINING LAB.

Korea University

002. 윈도우프로그래밍의 기본

이 종 욱

[email protected]

윈도우 프로그래밍 및 실습

since 2007. 09. 03

updated 2012. 08. 18

last updated 2015. 08. 25

2

Purpose of this chapter

• What is a ‘Window programming’

• How to code the ‘Window programming’

• Simple example

• Meaning of code

윈도우즈 역사

1985년 11월 첫 버전 발표

미국의 마이크로소프트(Microsoft)에서 83년 11월에 개발 시작

그래픽 기반 운영체제(GUI)

1987년 윈도우즈 1.1

1987년 11월 윈도우즈 2.0

윈도우끼리 겹칠 수 있다(Overlapped)

1990년 3월 22일 윈도우 3.0

VISTA 32bit or 64bit

Windows 7, 8 (2012년 8월)

현재: Window 10 발표됨. 2015년 8월

특징 및 장점

1. 그래픽 기반(GUI)의 운영체제이다

2. 멀티 태스킹

3. 메시지 구동 시스템

4. 장치에 독립적

윈도우는 디바이스 드라이버에 의해 다양한 주변 장치들을 제어하고 관리한다.

장치가 바뀌면 디바이스 드라이버를 교체하면 된다

5. 일관성이 있다

사용자가 프로그램에게 명령을 내리는 인터페이스 구성이 표준화

6. 리소스가 분리

코드와 윈도우를 그리기 위한 리소스로 구분됨

개발툴

API (Application Programming Interface)

운영체제가 응용 프로그램을 위해 제공하는 함수의 집합

SDK (Software Development Kit)

API를 사용하여 프로그램을 개발하는 개발툴킷이었으나, 지금은 API와 거의 같은 뜻으로 사용됨

클래스 라이브러리

MFC

OWL

6

First (1/4) : 기본 틀

1. 먼저 First_2015버전.txt 파일을 내용을 본다!

// 윈도우 클래스 선언, 속성 선택, 등록, 생성, 화면출력 그리고 윈도우 메시지 전달 관련 코드 작성

// 강의 자료 8, 9 페이지에 있는 내용을 이 곳에 작성한다!!!

// C 또는 C++을 콘솔에서 작성할 때의 가장 기본적인 틀과 하단을 비교해보자!

// TCHAR에 의미는 부가 강의 자료에서 확인한다.

//윈도우 메시지를 처리하는 WndProc( ) 함수의 원형(선언)

7

First (2/4) : 메시지 처리 전용 함수

// 윈도우 메시지 처리를 위한 WndProc( ) 함수 정의 부분

// 실제 코드에서는 마지막 부분에 위치!

8

First (3/4) : 윈도우 클래스 선언, 속성 선택, 레지스터 등록을 위한 코드

9

First (4/4) : 윈도우 생성, 화면에 보여주기, 메시지 넘기기 코드

10

실습: VS2015에서 앞의 내용 수행

강의 자료 “000_How to use the Visual studio community 2015

-window programming-.pptx” 에 나와 있는 내용을 잘 따라 해본

First 라는 이름의 윈도우 출력됨!

11

변수 명명법 (1/2)

접두사 원래말 의미

cb Count of Bytes 바이트 수

dw double word 부호 없는 long형 정수

h handle 윈도우,비트맵 등의 핸들

sz Null Terminated NULL 종료 문자열

ch Character 문자형

a Array 배열

w Word 부호없는 정수형

i Integer 정수형

p, lp long pointer 포인터형

b Bool 논리형

데이터형 의미

BYTE unsinged char 형

CHAR char 형

WORD unsinged char 형

DWORD unsigned long 형

LONG long과 동일

BOOL 정수형 True/False

식별자 의미

HINSTANCE 인트스턴 핸들

프로그램 자체

HWND 윈도우 핸들

HDC Device Context핸들

• TCHAR에 의미는 부가 강의 자료에서 확인한다.

“null-terminated" and sz means "array of characters, null-terminated"

12

변수 명명법 (2/2)

접두사 상수

CS class style 옵션

CW create window 옵션

DT draw text 옵션

IDI 아이콘(icon) ID

IDC 커서(cursor) ID

MB 메시지 상자 옵션

SND 사운드 옵션

WM window message

WS Window style

접두사 데이터 타입

c char 또는 WCHAR 또는 TCHAR

by BYTE (unsigned char)

n short

i int

x, y int (x,y 좌표로 사용)

cx, cy int (x, y 길이로 사용); c는 count

b or f BOOL(int); f는 ‘flag’의미

w WORD (unsigned short)

l LONG (long)

dw DWORD (unsinged long)

fn function

s string

sz string terminated by 0 character

h handle

br brush

핸들

핸들(handle)이란 구체적인 어떤 대상에 붙여진 번호이며 문법적

으로는 32bit(or 64bit)의 정수값

대상끼리의 구분을 위해서 사용

문자열보다는 정수값이 더 효율적

특징

1. 정수값 (32bit), 구분을 위한 것이므로 중복을 허용하지 않음.

2. 운영체제가 발급하며 사용자는 사용만 한다.

3. 같은 종류의 핸들끼리는 절대로 중복된 값을 가지지 않는다.

4. H로 시작하는 접두어를 가짐. HWND, HPEN, HDC…

14

메시지 처리 함수, 전역 변수

WndProc() : 윈도우에서 발생한 메시지를 처리하기 위한 함수

Window Procedure 윈도우 프로시저, 윈드프록이라고도 읽음

운영체제에 의해 호출되는 응용 프로그램내의 함수를 콜백(CallBack)함수라고 한다

LRESULT : long 타입으로, Wind32환경에서 메시지 처리를 마친 후 O/S에게 어떤 신호를 주기

위해 사용된다. -1, 0, 1, 비트플래그 값을 가짐.

HISNTANCE : 생성된 프로그램 자체를 의미하는 정수값

g_hInst : 인스턴스 핸들 값을 전역변수로 사용하기 위해 선언한 전역변수

LPCTSTR : LP(롱포인터) 16비트 시절, 24비트 메모리를 관리하기 위해 long pointer를 사용.

32bit 시스템에서는 32bit 의미. C constant(상수), TSTR t_char 유니코드+멀티바이트 지원

APIENTRY : 윈도우 표준 호출 규약 _stdcall 를 사용한다고 알려주는 매크로

15

Winmain (1/2)

APIENTRY : 윈도우의 표준 호출 규약인 _stdcall 사용한다는 의미

인수 의미

hInstance 프로그램의 인스턴스 핸들

hPrevInstance

바로 앞에 실행된 현재 프로그램의 인스턴스 핸들.

없을 경우는 NULL이 되며 WIN32에서는 항상 NULL이다.

호환성을 위해서만 존재하는 인수이므로 신경쓰지 않아도 된다.

lpCmdLine 명령행으로 입력된 프로그램 인수이다. 도스의 argv인수에 해당한다.

nCmdShow 프로그램이 실행될 형태이며 최소화, 보통모양 등이 전달된다.

이 중 hInstance 이외에는 실제 코드에서 거의 사용되지 않는다.

16

Winmain (2/2)

많은 API 함수들이 hInstance값을 필요로 하는 경우가 많다.

hInstance: 윈도우에서 실제 생성된 프로그램을 관리하기 위해 정수값을 발급한다.

hInstance는 바로 그 정수값을 의미.

하지만, hInstance는 main문의 인자로, 지역변수가 된다

해결방법 : hInstance 를 저장할 전역변수를 만들어 사용한다.

실제 코드에선 전역변수로 다음과 같은 코드 추가

HINSTANCE g_hInst;

lpszClass라는 전역 문자열 정의.

이 문자열은 윈도우 클래스를 정의하는데 사용된다.

윈도우 타이틀 바에 표시되기도 함

// 지역변수

// 전역변수

// main 문

17

윈도우 클래스 속성 설정 (1/3)

typedef struct tagWNDCLASS

{

UINT style; // ①

WNDPROC lpfnWndProc; // ②

int cbClsExtra; // ③

int cbWndExtra; // ④

HINSTANCE hInstance; // ⑤

HICON hIcon; // ⑥

HCURSOR hCursor; // ⑦

HBRUSH hbrBackground; // ⑧

LPCSTR lpszMenuName; // ⑨

LPCSTR lpszClassName; // ⑩

} WNDCLASS;

18

윈도우 클래스 속성 설정 (2/3)

① style

윈도우가 어떤 형태를 가질 것인지를 지정한다.

CS_HREDRAW 와 CS_VREDRAW 를 | (or)로 연결하여 사용.

수직, 수평 크기가 변할 경우 윈도우를 다시 그린다는 뜻. 이외에도 많음

② lpfnWndProc

윈도우 메시지 처리 함수를 지정

메시지가 발생할 때마다 이 멤버가 지정하는 함수가 호출되며 이 함수가 모든 메시지를

처리한다

First 예제에서는 WndProc 함수를 대입, 이 윈도우 클래스로부터 만들어지는 윈도우 메

시지는 WndProc 함수가 처리

cbClsExtra

cbWndExtra 특수한 목적으로 사용하는 윈도우 예약 영역. 사용하지 않을 때 0으로 지정

⑤ hInstance

현재 생성한 윈도우 클래스를 등록하는 프로그램의 번호이며 WinMain의 인수로 전달된

hInstance값을 그대로 대입. 운영체제는 이 윈도우 클래스를 누가 등록했는지 기억해 두

었다가 프로그램이 종료될 때 등록 취소.

⑦ hIcon/hCursor

윈도우가 사용할 마우스 아이콘과 커서를 지정.

LoadIcon 함수와 LoadCursor함수를 사용하여 아이콘, 커서를 읽어와 이 멤버에 대입

윈도우 디폴트로 제공하며 사용자가 직접 만들 수 있다.

19

윈도우 클래스 속성 설정 (3/3)

⑧ hbrBackground

윈도우 배경 색상 지정.

윈도우 배경 색상을 채색할 브러시를 지정하는 멤버.

GetStockObject 함수를 사용하여 윈도우에서 제공하는 기본값 사용 하거나

COLOR_WINDOW 같은 시스템 색상을 지정할 수도 있다.

⑨ lpszMenuName

만들어질 프로그램이 사용할 메뉴를 지정.

메뉴는 프로그램 코드에서 만드는 것이 아니라 리소스 에디터에 의해 별도로 만들어진

후 링크시에 합쳐진다

메뉴를 사용하지 않을 경우 NULL 대입

⑩ lpszClassName

윈도우 클래스 이름 정의.

여기서 지정한 이름은 CreateWindow 함수에 전달되며 CreateWindow 함수는 윈도우

클래스에서 정의한 특성값을 참조하여 윈도우를 만듦.

윈도우 클래스의 이름은 보통 실행 파일 이름과 일치 lpszClass = TEXT(“First”);

- RegisterClass(&

WndClass)

윈도우 클래스를 정의한 후 RegisterClass 함수를 호출하여 윈도우 클래스를 등록

ATOM RegisterClass( CONST WNDCLASS *lpWndClass);

RegisterClass(&WndClass)

생성한 WndClass 구조체 번지를 넘겨준다. 앞으로 지금 등록한 윈도우를 사용하겠다는

등록.

20

윈도우 실제 생성(CreateWindow) (1/2)

윈도우 클래스를 등록한 후, 윈도우 클래스를 정의된 내용에 맞게 윈도우를 실제 생성한다.

HWND CreateWindow(① lpszClassName, ② lpszWindowName, ③ dwStyle, ④ x, ⑤ y, ⑥ nWidth,

⑦ nHeight, ⑧ hwndParent, ⑨ hmenu, ⑩ hinst, ⑪ lpvParam)

① lpszClassName

생성하고자 하는 윈도우 클래스를 지정하는 문자열이다.

앞에서 등록한 WNDCLASS 구조체의 lpszClassName 멤버의 이름을 여기에 넣는다.

② lpszWindowName 윈도우 타이틀 바에 나타날 문자열이다. lpszClass 를 쓰면 “First” 출력

③ dwStyle

만들고자 하는 윈도우 형태를 지정. 비트 필드값으로 수십 개를 헤아리는 매크로 상수들을

OR연산자로 연결하여 윈도우의 다양한 형태를 지원.

WS_OVERLAPPEDWINDOW 스타일이 가장 무난한 윈도우 = 메모장과 유사한 모습

① ② ③

④ ⑤ ⑥ ⑦

⑧ ⑨ ⑩ ⑪

21

윈도우 실제 생성 (2/2)

~

X, Y,

nWidth, nHeight

윈도우의 크기와 위치를 지정하며 픽셀 단위를 사용.

X, Y 좌표는 메인 윈도우의 경우는 전체 화면을 기준, 차일드 윈도우는 부모 윈도우의

좌상단을 기준. 정수값을 사용해도 되며 CW_USEDEFAULT를 사용하면 윈도우가 알아서

적당한 크기와 위치를 설정. 예제에서는 모두 디폴트 사용.

⑧ hWndParent

부모 윈도우가 있을 경우 부모 윈도우의 핸들을 지정해 준다.

M야 프로그램이나 팝업 윈도우는 윈도우끼리 수직적인 상하관계를 가져 부자(parent-

child)관계가 성립되는데 이 관계를 지정해주는 인수이다.

부모 윈도우가 없을 경우는 이 값을 NULL로 지정.

⑨ hmenu

윈도우에서 사용할 메뉴의 핸들을 지정한다.

WndClass에도 메뉴를 지정하는 멤버가 있는데 윈도우 클래스의 메뉴는 그 윈도우 클래

스를 기반으로 하는 모든 윈도우에서 사용. 이 인수로 지정된 메뉴는 현재

CreateWindow 함수로 만들어지는 윈도우에서만 사용된다. 만약 WndClass에서 지정

한 메뉴를 사용하려면 이 인수를 NULL. 다른 메뉴를 사용하려면 이 인수에 원하는 메뉴

핸들을 주면 된다. First 예제의 경우 WndClass에도 메뉴가 지정되어 있지 않고

CreateWindow 함수에서도 메뉴를 지정하지 않았으므로 메뉴없는 프로그램이 만들어

진다.

⑩ hinst 윈도우를 만드는 주체, 즉 프로그램의 핸들을 지정. WinMain의 인수로 전달된

hInstance를 대입해 주면 된다.

⑪ lpvParam CREATESTRUCT라는 구조체의 번지이며 특수한 목적에 사용된다. 보통은 NULL값을 사

용한다.

22

윈도우 화면 출력

BOOL ShowWindow(hWnd, nCmdShow);

hWnd 인수는 화면으로 출력하고자 하는 윈도우의 핸들이며 CreateWindow 함

수가 리턴한 핸들을 그대로 넘겨주면 된다. nCmdShow는 윈도우를 화면에 출력

하는 방법을 지정하며 다음과 같은 매크로 상수들이 정의되어 있다

매크로 상수 의미

SW_HIDE 윈도우를 숨긴다.

SW_MINIMIZE 윈도우를 최소화하고 활성화시키지

않는다

SW_RESTORE 윈도우를 활성화시킨다

SW_SHOW 윈도우를 활성화하여 보여준다

SW_SHOWNORMAL 윈도우를 활성화하여 보여준다

23

메시지 루프 (1/2): 메시지를 꺼내고, 살짝 변경하여 WndProc에 전달

윈도우 : 메시지 구동 시스템(Message Driven System)

• 도스는 미리 입력된 일련의 명령들을 순서대로 실행하는 순차적 실행방법

• 윈도우는 프로그램의 실행이 상황(event OR message)에 따라 실행

메시지

• 사용자나 시스템 내부적인 동작에 의해 발생된 일체의 변화에 대한 정보

BOOL GetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);

메시지 큐에서 메시지를 읽어들여 첫번째 인수가 지정하는 MSG 구조체에 저장.

함수는 읽어들인 메시지가 WM_QUIT(프로그램종료)일 경우 False 리턴, 그외는 True.

나머지 세개의 인수는 잘 사용되지 않는다.

BOOL TranslateMessage( CONST MSG *lpMsg);

입력된 메시지를 상황에 맞게 가공한다.

WM_KEYDOWN과 WM_KEYUP이 연속적으로 발생할 때 문자가 입력되었다는 WM_CHAR 만드는 역할

LONG DispatchMessage( CONST MSG *lpmsg);

시스템 메시지 큐에서 꺼낸 메시지를 WndProc로 전달

24

메시지 루프 (2/2)

메시지는 정수값으로 표현되나, 종류가 많으므로 window.h에 메시지별로 매

크로 상수를 정의 접두어 WM_으로 시작한다

멤 버 의 미

hwnd 메시지를 받을 윈도우 핸들이다.

message 어떤 종류의 메시지인가를 나타낸다. 가장 중요한 값이다.

wParam 전달된 메시지에 대한 부가적인 정보를 가진다. 어떤 의미

를 가지는가는 메시지별로 다르다. 32비트값이다.

lParam 전달된 메시지에 대한 부가적인 정보를 가진다. 어떤 의미

를 가지는가는 메시지별로 다르다. 32비트값이다.

time 메시지가 발생한 시간이다.

pt 메시지가 발생했을 때의 마우스 위치이다.

멤 버 의 미

WM_QUIT 프로그램을 끝낼 때 발생하는 메시지이다.

WM_LBUTTONDOWN 마우스의 좌측 버튼을 누를 경우 발생한다.

WM_CHAR 키보드로부터 문자가 입력될 때 발생한다

WM_PAINT 화면을 다시 그려야 할 필요가 있을 때 발생한다.

WM_DESTROY 윈도우가 메모리에서 파괴될 때 발생한다

WM_CREATE 윈도우가 처음 만들어질 때 발생한다.

typedef struct tagMSG

{

HWND hwnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

DWORD time;

POINT pt;

} MSG;

25

윈도우 프로시저 (1/2)

메시지 처리 함수

메시지가 발생할 때 프로그램의 반응을 처리하는 일을 하며 WinMain 함수와는 별도로

WndProc 함수가 존재한다.

WndProc은 WinMain에서 호출하는 것이 아니라 윈도우에 의해 호출

WinMain내의 메시지 루프는 메시지를 메시지 처리 함수로 보내기만 한다

WndProc는 메시지가 들어오면 호출되어, 그 메시지에 맞는 내용을 처리, 만약 메시지

처리 문장이 없으면 처리하지 않는다.

콜백(CallBack)함수 : 운영체제에 의해 호출되는 함수

WndProc의 인수는 모두 4개이며 MSG 구조체의 멤버 4개가 동일

③ ④

1) 메시지를 받을 윈도우의 핸들

2) 어떤 종류의 메시지인가?

3) 메시지에 따른 부가 정보

4) 메시지에 따른 부가 정보

26

윈도우 프로시저 (2/2)

27

코드 반복 이해 First (1/4) : 기본 틀

// 윈도우 클래스 선언, 속성 선택, 등록, 생성, 화면출력 그리고 윈도우 메시지 전달 관련 코드 작성

// 강의 자료 29, 30 페이지에 있는 내용을 이 곳에 작성한다!!!

28

First (2/4) : 메시지 처리 전용 함수

29

First (3/4) : 윈도우 클래스 선언, 속성 선택, 레지스터 등록을 위한 코드

30

First (4/4) : 윈도우 생성, 화면에 보여주기, 메시지 넘기기 코드

2-3. 다양한 변형

31

P.49~53 직접 수업 중에 해본다.

배경색 바꾸기: WndClass.hbrBackground

커서 바꾸기: WndClass.hCursor

윈도우의 타이틀 바꾸기: CreatWindow( ) 2번째 인자

윈도우 스타일: CreatWindow( ) 3번째 인자 WS_OVERLAPPEDWINDOW

위 코드에서 WS_OVERLAPPEDWINDOW 는 다음과 같이 정의된 매크로 상수

#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME

| WS_MINIMIZEBOX | WS_MAXIMIZEBOX )

3번째 인자를 WS_CAPTION | WS_SYSMENU 또는 WS_OVERLAPPEDWINDOW |

WS_VSCROLL

실습 제출!!!