WinAPI 핸들, DC, 이벤트 (2)

CJB_ny·2022년 8월 23일
0

WinAPI

목록 보기
4/79
post-thumbnail

HPEN - CreatePen()

인자를 뭘 주어야할지 잘 모르겠다.

=> 바로 구글링

아 뭐 첫번째 인자값으로 이런거~

두번째는 int 두깨

세번째는

RGB메크로? (그냥 함수? 말하는듯)

그래서 이렇게 되는데

이게 뭘 뜻하냐??

BYTE는 unsigned char를 나타냄 0~255.

그림은 왼쪽처럼 그렸지만 실제 메모리 구조는 오른쪽처럼

B G R 순이다.

지금 (WORD)((BYTE)(g)) << 8 인데

g값을 8번 왼쪽으로 밀고

픽셀은 하나에 8 8 8 바이트 이다.

그래서 8칸 밀어서 G에 라는 픽셀 메모리에 값이 들어갈 수 있도록 하는 것이다.

BYTE(r) | BYTE(g)랑 비트 연산을 한다.

B의 경우에는 16비트를 밀어서 B의 자리에 들어가게 하는 것이다.

이렇게 비트를 밀어주는것을 매번쓰기가 귀찮으니까

메크로로 만들어 준 것이다.

이제 우리가 펜을 만들었으니까

이제 다시 설정을 해야함.

다시 윈도우 함수를 사용한다.

SelectObject(hdc한테 무엇을?, hRedPen)을.

이렇게하면 되기는 하는데 기존의 검은색 펜은?

=> 받아 주어야한다.

반환형이 Void* 이기 때문에 HPEN이 아니라

HGDIOBJ이다. 그래스 캐스팅 해주어야한다.


이렇게 하면되는데 왜 이렇게 까지 하냐?

SelectObject는 되게 범용적인 함수이다.

이렇게 빨간색 사각형 그려준다.

그리고 다 사용하고 나면 다시 원래 검은색펜을 넣어준다.

그러면 이제 빨간펜이 붕 뜨는데

DeleteObject로 커널 오브젝트를 삭제 해달라고 요청한다.

커널오브젝트는 OS가 관리를 하고있기 때문에 우리가 직접 delete할 수 없고

ID를 주고 요청을 하는 것이다.

HBRUSH

pen을 가져올때 처럼 CreateBrush해주어도되지만

자주사용하는 펜이나 브러쉬 미리 저정해둠.

이거 가져오는 함수가 GetStockObject라는 함수가 있다.

GetStockObject 목록을 보면 이렇게있는데

HOLLOW BRUSH는 할루시네이션 == 투명하게 한다.

가져오는 경우 == GetStockObject는 DeleteObject안해도 되자만

Create한 경우에는 DeleteObject 해주어야한다.

이렇게 하면 된다.

게임을 만들기에 문제

이런식으로 게임을 만들기에는 문제가있다.

방향키로 너 네모를 움직이게 하고싶다면 만약에

이런 케이스로 입력받았을 경우 들어올 수 있는데

'어떤' 키가 눌렸는지 알아야한다.

그래서 메세지가 발생했을 때

wParam, lParam이 바로 해당 메세지의 부가 인자값(부연설명)

마우스를 누른 경우 추가 정보가 lParam에 들어오고

키보드 입력시 추가 정보가 wParam에 들어온다.

그래서 키보드로 움직일 시

이런식으로 wParam에 따라서 또 case 해주면된다.

윈도우에서는 각 '키'에 해당하는 고유한 ID값을 define으로 다 정의 해놨다.

VK_Up이 화살표 업방향 키말하는 것이다.

막 이렇게 많은데 검색하면 나옴.

키보드 문자일 경우

아스키 코드 값으로 판별을 한다.

대문자 기준이다! 대문자랑 소문자 아스키 완전히 다르기 때문에.

lParam

LPARAM lParam의 LPARAM은 4바이트 long이다 (돌고돌아서)

미래에는 픽셀이 6만 x 5만 될수도있지만 현재로는 ㄱㅊ음.

그래서 long이라는 자료형 2바이트씩 쪼개서

마우스 입력의 추가정보 x, y 좌표를 2바이트씩 쪼갠거에다가 담는 것이다.

WM_LBUTTONDOWN으로 마우스 좌표를 알아낼 수 있는데

2바이트씩 비트연산을 해서 가져와야됨.

마찬가지로 메크로 다 준비가 되어있다.

LOWORD, HIWORD

이거 분석은 니가 스스로 ㄱㄱ.

HIWORD가 y좌표인갑네 이것을 0xffff랑 비트 & 연산해주네

이렇게하면 마우스 좌표알아낼 수 있다.

g_x, g_y 전역변수임.

해당 윈도우 기준으로 처리해줌.

'작업영역'부분에서 처리를 해줌.

그려보기

POINT는 x, y를 가지는 그냥 구조체이다.

내 캐릭터 (사각형)을 그린다고 할때

이거 위치 잘 생각해봐라

ㅇㅇ.

이부분에서 이렇게 y좌표가 올라가도록 설정해주고

실행해서 up키 누르면 안올라감..

그런데

창을 최소화한다음에 다시 키면 올라가있음

왜?? => WM_PAINT가 발생하지 않아서 이다.

발생을 해야 바뀐 좌표를 기준으로 그릴텐데 WM_PAINT가 발생안함.

Invalidate

이 함수 직접 호출한다.

무효화영역을 잡아서 직접 호출함.

윈도우는 특정 창에 동작이 발생할 때 그것을 OS가 감지를 해서

"어? 너 무효화 영역 발생했네?" 우리한테 WM_PAINT메세지를 넣어준 것이다.

지금은 지금 창이 그대로 계속 켜져있어서 무효화 영역이 발생을 안해서 WM_PAINT 메세지가 발생이 안한 것이다.

그러면 WM_PAINT영역이 발생하도록

InvalidateRect로 집어주는 것이다.

현재 윈도우 ID hWnd가 알고있고 nullptr로 넣어주면 전체로 인식하고 erase는 false로 넣겠다.

이렇게. => 실행

그려주기는 함. 이전꺼 남아았음.

'픽셀'은 '메모리 덩어리' 라고했다.

이렇게 올라가면서 그려지기는 하겠지만 이전에 있던 부분의

픽셀의 메모리 데이터가 '소실' 된 것은 아니기 때문에 그대로 출력하면 색상이 나오는것이다.

그래서 무효화 영역이 발생했을 때 모든 픽셀을 싹다 clear하고

해야한다.

이렇게 무효화 영역이 발생했을 때 싹 지우겠다라는 의미로

true를 넣어준다.

그러면 잘 동작하는데

꾹 눌렀을 경우 한템포 느리다.

이거 윈도우에서 키를

WM_KEYDOWN이라는거 자체가 처음 눌렸을때 발생을하고

꾹누른다면 1초뒤에 계속 누른거라고 인식을 한다.

메세지 기반으로 한다면 개선을 해야한다.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글