GDI(Graphics Device Interface)

:: 운영체제의 한 부분으로 출력을 담당한다(Gdi.dll)

:: GDI는 하드웨어에 관련된 사항들을 통제한다.

DC(Device Context)

:: 출력하기 위한 장치(화면, 프린터)의 특성을 저장하는 구조체

:: 명령 흐름 : Application → DC → GDI → 출력 

 

- DC를 사용하는 그래픽 오브젝트

비트맵, 브러쉬, 펜, 팔레트, 폰트, Region, Path 등

 

- DC의 데이터 형 = 핸들

HDC

typedef HANDLE HDC;
typedef PVOID HANDLE;
typedef void * PVOID;

결국 HDC는 주소값을 저장하긴 하지만 데이터 타입이 지정되지 않은 것이다.

따라서 이를 양의 정수(아이디)로서 이해하는 것이 좋다.

 

 

※ 화면 DC에 관련된 함수

BeginPaint(), EndPaint(), GetDC(), ReleaseDC() 등

 

 

<BeginPaint, EndPaint>

이 함수들은 WM_PAINT 메시지 처리에서만 사용가능하다

(WM_PAINT : 클라이언트 영역이 지워지거나 새로이 출력하고자 할 때, 윈도우끼리 겹쳐있다가 활성화되었을 때, 최소화되었다가 다시 최대화될 때 등 클라이언트 영역을 다시 실행할 때 나타나는 메세지)

HDC BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
BOOL EndPaint(HWND hWnd, const PAINTSTRUCT *lpPaint);

프로젝트명.cpp에서 확인

실제로 프로젝트 생성시 자동생성되는 코드에서 기본적으로 잘 세팅되어 있다.

 

 

<GetDC, ReleaseDC>

GetDC()로 DC를 얻은 후에는 ReleaseDC()를 통해 반드시 운영체제에 반납해줘야 한다.

getdc, releasedc 같은 경우 지정된 장소가 없어서 아무곳에서나 선언 가능하다.

HDC GetDC(HWND hWnd);
int ReleaseDC(HWND hWnd, HDC hDC);

일반적인 WM_PAINT 메세지 외에선 GetDC, ReleaseDC를 통해 출력할 수 있다.


※ 문자 출력

문자 출력을 위한 함수 = Textout

BOOL TextOut(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString);

<필요한 것>

- hcd

- x와 y 좌표(0,0)~(299,299)

- 출력하고자 하는 문자열을 담고 있는 문자열 포인터

  sprintf (메모리의 char형 배열에 출력) 사용

- 출력하고자 하는 문자열의 길이

  strlen (문자열의 길이 측정) 사용

 

기존 WM_PAINT 처리 부분에 이를 추가해준다
(0,0) 부분에 해당 문자열이 출력됨을 확인할 수 있다.

 

GetDC(), ReleaseDC()를 이용해서도 화면에 출력할 수 있다.

기존에 만들어 뒀던 Test() 함수에 출력 내용에 대한 코드를 작성해준다.

Test() 함수
WndProc 에 LBUTTONDOWN 추가

WM_LBUTTONDOWN은 마우스 버튼을 클릭했을 때 실행되는 메시지이다. 

이 메세지 발생시 Test 함수가 작동되도록 코드를 작성한다.

 

(100,100) 에 해당 문자열이 출력됨을 확인할 수 있다.


※ 출력 색상 설정

:: 삼원색(R,G,B) 이용

:: 색상 범위 : 0 ~ 255, DWORD(unsigned long)로 다룬다.

 

→ 색상 관련 매크로 함수 = RGB(), GetRValue(DWORD rgb), GetGValue(DWORD rgb), GetBValue(DWORD rgb)

COLORREF RGB(
	BYTE byRed,
	BYTE byGreen,
	BYTE byBlue
);

COLORREF는 DWORD를 재정의한 데이터 형이다(똑같다)

 

 

기존 WM_PAINT 코드에 추가

 

(200,200)에 색상값이 잘 출력되었다.

 

 

+ 점(dot) 출력 함수 = SetPixel()

SetPixel(
	HDC hdc,
	int X, int Y,
	COLORREF crColor
);

 

 

+ 점(dot) 출력 함수 = GetPixel()

화면 DC에 출력된 색상값을 구하는 함수

GetPixel(
	HDC hdc,
	int nXPos, int nYPos
);

 

WM_PAINT 코드에 추가

 

아주 자세히 보면 (300,300)에 빨간색 점이 찍혀있다. (400,400)에선 GetPixel을 통한 색상값이 표현되어 있다.


※ 문자열 출력 관련 함수

SetTextColor() :: 출력할 문자열의 색상 설정

COLORREF SetTextColor (
	HDC hdc.
	COLORREF crColor
);

SetBkColor() :: 글자의 배경 색상 설정

COLORREF SetBkColor (
	HDC hdc,
	COLORREF crColor
);

 

WM_PAINT 코드에 추가
결과

 

InvalidateRect()

:: 화면의 일부(RECT 구조체 사용) 또는 전체(NULL, 0)를 다시 출력할 때 사용

-> WM_PAINT 메시지 발생(BeginPaint ~ EndPaint 영역 실행)

-> 무효화 영역 또는 업그레이드 영역 (다시 그리고자 하는 영역) 지정 가능

 

BOOL InvalidateRect(HWND hWnd, const RECT *lPRect, BOOL bErase);

typedef struct_RECT{ //구조체 원형
	LONG left;
	LONG top;
	LONG right;
	LONG bottom;
} RECT *PRECT;

+ BOOL bErase

: true면 그리고자 하는 일부 영역(클라이언트 영역)을 싹 다 지우고 다시 그림

false면 그 영역에 지우지 않고 계속해서 그림

 

WndProc 앞 부분에 선언

 

WM_LBUTTONDOWN case에 InvalidateRect 추가

&rect 자리에 0이 들어간다면 전체영역을 다시 그릴 것이고

FALSE 자리에 TRUE가 온다면 선택된 영역에 겹쳐서 그려지는게 아니라 새롭게(안 겹치게) 그려질 것이다.

 

WM_PAINT 메세지 발생하므로 이 곳에 원하는 행위 작성

 

제일 처음에 WM_PAINT 메시지 발생

 

false : 마우스 왼쪽 버튼을 누를수록 정했던 영역(0,0,150,150)에만 점이 겹치면서 찍힌다.

'Project > WIN32 API' 카테고리의 다른 글

키보드, 마우스  (0) 2021.07.13
그래픽 오브젝트  (0) 2021.07.12
리소스  (0) 2021.07.07
WndProc  (0) 2021.06.26
윈도우 창 생성 과정  (0) 2021.06.25

리소스

:: 메뉴, 다이얼로그, 비트맵, 커서, 아이콘, 엑셀레이터(단축키), 문자열

→ 리소스는 아이디(중복되지 않는 양의 정수 값)로 다룬다.

 

① 아이콘 리소스

:: 왼쪽 상단과 최소화 때 하단 제목 표시줄에 나타나는 작은 이미지

→ *.ico 파일 확장자

 

크기 : 16x16, 32x32, 48 x48, 색상비트 : 4/8/32비트

※ 기본 : 4비트(16색), 32x32

 

→ 아이콘 아이디

접두사 IDI_

 

파일 - 새로 만들기 - 파일 - 아이콘 파일 - 기본이 32x32, 4비트 아이콘이므로 이곳을 편집

- 청록색 부분은 '투명색'으로 출력에서 제외되는 색상

- 저장하면 아이콘에 대한 아이디가 다르게 설정되어 별도로 사용할 수 있다.

실제 Resource.h 파일에 가보면 다른 아이디가 설정되어 있음을 알 수 있다

 

해당 프로젝트 리소스 폴더의 아이콘 폴더에 추가

 

- 아이콘 로딩 함수는 아래와 같다.

HICON LoadIcon(
	__in HINSTANCE hInstance,
	__in LPCTSTR IpIconName
);

이때 IpIconName에는 아이콘 아이디 정수값을 문자열 형식으로 지정할 수 있는데, 여기에 사용되는 함수가 MAKEINTRESOURCE() 이다.

LPTSTR MAKEINTRESOURCE(
	WORD wInteger
);

자동 생성 코드의 아이콘 부분 수정

 

디버깅 시

- 좌측 상단에 ICON2의 내용이, 화면 표시 줄에는 ICON1의 내용이 출력됨을 확인할 수 있다.

 

 


② 커서 리소스

:: 커서 설정은 아이콘과 유사하며, 접두사는 IDC_ 이고 *.cur로 표현된다.

 

1) 커서 로딩 방법

 

※ 운영체제에서 제공하는 기본 커서 아이디

IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, IDC_IBEAM, IDC_ICON, IDC_NO, IDC_SIZE, IDC_WAIT 등,,

 

- 기본 커서 로딩 함수는 아래와 같다.

HCURSOR LoadCursor(
	__in HINSTANCE hInstance,
	__in LPCTSTR IpCursorName
);

운영체제의 기본 커서 사용시 hInstance는 NULL 값, IpCursorName은 커서 기본 아이디를 넣으면 된다.

 

아이콘 설정 시 봤던 cpp 코드에서 커서 부분 코드를 수정

임의의 커서를 적용하기 위해선 인스턴스를 지정해줘야 한다.

 

편집한 후 핫 스폿 설정까지 한다.

(핫 스폿 설정이란 이 커서가 화면 내에 위치한다는 기준이 되는 지점)

 

 

이 커서는 클라이언트 영역에서만 적용된다.

 

 

2) 메세지를 통한 커서 설정 방법 --> 전체 윈도우 영역 안에서의 커서를 통제

 

- 마우스 이동 시 발생하는 메세지

WM_MOUSEMOVE, WM_SETCURSOR

HCURSOR SetCursor(
	__in HCURSOR hCursor
);

메세지를 로딩한 후 핸들을 통해 커서를 지정해준다

 

WndProc 에 위와 같은 새로운 case문을 추가

.

전체 윈도우 창에서 커서가 동작


③ 메뉴 리소스

:: 응용 프로그램의 부가적인 기능을 선택하여 실행

:: 사용자에 의해 선택되는 사용자 인터페이스

 

메뉴를 만들고 아이디도 확인할 수 있다.
Resource.h 에서 아이디 추가된 것 확인

 

프로젝트명.cpp 수정

 

생성한 메뉴 확인

그러나 이를 클릭하면 아무 일도 일어나지 않는다. 

따라서 메뉴를 실행시키려면 WndProc에 이와 관련된 메세지와 정보를 전달하는 코드가 필요하다.

 

※ 메뉴 관련 메시지

WM_COMMAND : 메뉴 선택

 

 

※ 메뉴 항목 구분

- 메뉴 아이디 

메뉴 아이디는 wParam에 LOWORD를 통해 그 값이 들어오게 된다.

LOWORD(wParam)

wParam은 unsigned int로 4 Byte 크기를 가진다.

 

 

※ 메뉴 항목 호출 확인

메뉴 항목 호출을 확인하기 위해 '메시지 박스'를 이용할 것이다.

int WINAPI MessageBox(
	_In_opt_ HWND hWnd, //핸들
	_In_opt_ LPCTSTR IpText, //출력하고자 하는 문자열
	_In_opt_ LPCTSTR IpCaption, //타이틀 바
	_In_ UINT uType //메세지 형태
);

→ uType에 해당하는 아이디

MB_OK, MB_OKCANCEL, MB_RETRYCANCEL, MB_YESNO, MB_YESNOCANCEL 등

 

WndProc에 위와 같은 case 문을 추가

 

각각의 메뉴를 누르면 메시지 박스가 뜬다.

 


④ 문자열 리소스

 

리소스 뷰의 스트링 테이블을 가서 원하는 문자열을 추가

캡션이 실제로 출력되는 내용이다.

 

※ 타이틀 명 수정해보기

코드 초반에 제목에 대한 배열이 선언되어 있음을 확인할 수 있다.

 

코드 수정

 

제목이 수정되었다

하지만 이런 과정이 굉장히 번거롭다. 

따라서 문자열은 이런 방법보단 코드에 바로 넣어주는 경우가 많다.

 


☆ 정리

- 리소스 편집기를 활용하여 리소스를 설정할 수 있다.

- 리소스 아이디는 중복되지 않게 알아서 저장된다.

- 기본 설정일 때 인스턴스는 NULL로 설정된다.

'Project > WIN32 API' 카테고리의 다른 글

그래픽 오브젝트  (0) 2021.07.12
그래픽  (0) 2021.07.08
WndProc  (0) 2021.06.26
윈도우 창 생성 과정  (0) 2021.06.25
윈도우즈 프로그래밍  (0) 2021.06.25

+ Recent posts