[Win32] 5. GDI 시스템 이해(1)
GDI를 공부하며 DC에 대해서도 공부해보자.
DC에 연결된 비트맵의 정보얻기
DC에 연결된 비트맵 핸들값 얻기
DC(Device Context)에는 여러가지 GDI Object 가 연결되어있음.
함수 원형
HGDIOBJ GetCurrentObject(HDC hdc, UINT uObjectType);
#include "wingdi.h"
HDC h_dc = ::GetDC(m_hWnd); // DC 얻기. m_hWnd는 윈도우 핸들값
// DC에 연결된 GDI Object 중에서 비트맵 객체핸들값을 얻는다.
HGDIOBJ h_bitmap = ::GetCurrentObject(h_dc, OBJ_BITMAP);
GetCurrentObject()는 OBJ_BITMAP을 통해 HBITMAP을 얻음.
그거외에도
OBJ_BRUH -> HBRUSH,
OBJ_FONT -> HFONT,
OBJ_PAL -> HPALETTE,
OBJ_PEN -> HPEN
을 얻을 수 있음.
비트맵 핸들을 이용하여 비트맵 정보 얻기
위에서 얻어온 비트맵 핸들을 가져와서 GetObject()
를 사용해서 BITMAP구조체 형식을 얻어올 수 있음.
HDC h_dc = ::GetDC(m_hWnd);
HGDIOBJ h_bitmap = ::GetCurrentObject(h_dc, OBJ_BITMAP);
BITMAP bmp_info;
::GetObject(h_bitmap, sizeof(BITMAP), &bmp_info); // 비트맵 정보를 얻어왔다!
// ... 작업생략데수 ...
// h_bitmap은 단순히 참조하기위해 핸들값만 받는 것이여서 해제할 필요X
::ReleaseDC(m_hWnd, h_dc); // 아까 사용하던 DC 반환
- 위와같은 정보가 진짜 얻어짐. 신기하다!!!!
- 참고로 bmBits는 현재 윈도우의 핸들을 사용했다면 NULL이 당연히 나옴. 신경 X
GetObject 함수에 대한 보충설명
wingdi.h에서 GetObject함수를 사용해봤음. 얘는 gdi32.lib을 사용함.
int GetObject(HGDIOBJ hgdobj, int cbBuffer, LPVOID lpvObject);
이 GetObject()함수로 여러 정보를 얻어올수 있다.
- hgdiobj 핸들에 따라 뒤에서 사용하는 값들이 달라진다.
hgdiobj에 HBITMAP
을 사용하는 경우
- 'BITMAP 정보'를 얻어오는 거기 때문에, 2번째 인자는 BITMAP 구조체로 선언한 변수의 주소를 사용해서 받아온다.
hgdiobj에 HAPALETE
를 사용하는 경우
- '팔레트 수'를 얻어올때 사용함.
- 2번째 인자에는 WORD크기를 명시, 그리고 WORD 주소로 받아오면됨
HBJOBJ h_pallete = ::GetCurrentObject(h_dc, OBJ_PAL);
WORD pal_count;
::GetObject(h_pallete, sizeof(WORD), &pal_count);
hgdiobj에 HPEN
을 사용하는 경우
- '펜객체 속성정보'를 얻어올때 사용.
- 2번째인자는 LOGPEN 로..
HGDIOBJ h_pen = ::GetCurrentObject(h_dc, OBJ_PEN);
LOGPEN pen_info;
::GetObject(h_pen, sizeof(LOGPEN), &pen_info);
hgdiobj에 HRUSH
를 사용하는 경우
- '블러시 객체의 속성정보'를 얻을때 사용
- 2번째 인자는 LOGBRUSH 로...
HGDIOBJ h_brush = ::GetCurrentObject(h_dc, OBJ_BRUSH);
LOGBRUSH brush_info;
::GetObject(h_brush, sizeof(LOGBRUSH), &brush_info);
// ... 작업생략데수 ...
hgdiobj에 HFONT
를 사용하는 경우
- '폰트 객체의 속성정보'를 얻을때 사용
- 2번째 인자는 LOGFONT 로...
HGDIOBJ h_font = ::GetCurrentObject(h_dc, OBJ_FONT);
LOGFONT font_info;
::GetObject(h_font, sizeof(LOGFONT), &font_info);
GetBitmapBits, SetBitmapBits
GetBitmapBits()
: 비트맵에 그려진 그림을 다른 형식의 이미지로 변환하거나 가져올때 사용
SetBitmapBits()
: GDI도움없이 그림을 그리거나 패턴을 변겨할때 사용
비트맵의 '비트패턴'에 접근하려면?
비트맵 내부에 비트패턴을 바꾸고싶다..
GetBitmapBits, SetBitmapBits를 사용해서 비트패턴을 가져오고, 설정할수 있다.
비트패턴 크기 계산
폭*높이*색상수
즉,
폭 300, 높이 200, 32비트 색상이면 240,000Bytes 메모리로구성되어있다고 보면됨
아래코드는 폭300, 높이200, 32비트색상을 사용하는 '비트패턴'을 복사해 오거나 새로운 값을 설정하기 위해서 필요한 메모리를 할당하는 코드다.
// 300*200*4 크기로 메모리 할당
unsigned int *p_pattern = new unsigned int[300*200];
delete[] p_pattern; // 사용하던 메모리 해제
GetBitmapBits()
비트맵의 비트패턴을 복사해오는 함수
LONG GetBitmapBits(HBITMAP hbmp, LONG cbBuffer, LPVOID lpvBits);
- hbmp : 비트패턴을 복사할 비트맵의 핸들값
- cbBuffer : 비트패턴이 복사될 메모리주소 명시
- 반환값 : 실제로 복사한 비트패턴의 크기가 반환됨.
HBITMAP h_bitmap = CreateBitmap(300, 200, 1, 32, NULL);
unsigned int *p_pattern = new unsigned int[300*200];
int copy_size = GetBitmapBits(h_bitmap, 300 * 200 * 4, p_pattern);
delete[] p_pattern;
DeleteObject(h_bitmap);
SetBitmapBits()
비트맵에 새로운 '비트패턴'을 설정하는 함수
LONG SetBitmaptBits(HBITMAP hbmp, DWORD cb, const VOID *pvBits);
- hbmp : 비트패턴을 생성할 비트맵의 핸들값
- cb : 설정할 바이트수
- pvBits : 비트패턴에 설정할 새로운 비트패턴이 저장도니 메모리주소
- 반환값 : 실제로 설정한 비트패턴의 크기 반환
HBITMAP h_bitmap = CreateBitmap(300, 200, 1, 32, NULL);
unsigned int *p_pattern - new unsigned int[300 * 200];
for (int i = 0; i < 300 * 200; i++) {
*(p_pattern + i) = 0xFF0000FF;
}
int copy_size = SetBitmapBits(h_bitmap, 300 * 200 * 4, p_pattern);
delete[] p_pattern;
DeleteObject(h_bitmap);
GetSystemMetrics()
컴퓨터 해상도와 같은 특성을 생각하며 프로그래밍해야한다.
해상도와 같은 하드웨어적인 정보를 얻어서 사용할 때 사용하는 함수가
GetSystemMetrics()
함수이다.
GetSystemMetrics()
시스템정보를 반환한다.
Winuser.h 에 선언되어있다.
int GetSystemMetrics(int nIndex);
nIndex
에 사용가능한 상수값들은SM_
으로 시작하는 상수이며, 100가지가 넘김- 필요한 정보가 있다면 그때그때 보면서 사용하면 된다.
SM_CXSCREEN
: 화면의 X축(가로해상도, Pixel단위) 반환SM_CYSCREEN
: 화면의 Y축(세로해상도, Pixel단위) 반환SM_CXFULLSCREEN
: 전체화면 X축 반환SM_CYFULLSCREEN
: 전체화면 Y축 반환SM_CYCAPTION
: 일반 윈도우의 캡션(타이틀)바 높이를 얻는다.- 기본값은 23. 특별히 만져줬다면 다름
SM_CMONITORS
: 현재 시스템의 모니터 개수 반환SM_NETWORK
: 현재시스템 네트워크 상태 반환
- 이런식으로 사용한다.
#include <Winuser.h>
int cx = GetSystemMetrics(SM_CXSCREEN);
int cy = GetSystemMetrics(SM_CYSCREEN);
GetSystemMetrics() 단점
컴퓨터의 단순한 상태 값이나 설정값만 받아올수 있다.
상세한 정보를 얻으려면 다른 함수를 호출해야한다.
- 색상수 를 얻고싶으면
GetDeviceCaps()
와 같은 함수를 호출해야함.
GetDC()와 ReleaseDC()
그림그리기 작업을 하려면 GDI를 사용해하는데, DC핸들러가 필요하다.
Recatangle(h_dc, 50, 50, 100,100);
GetDC() - DC구성하기
화면전체 또는 특정Window에 그림을 그리기 위해 사용할 DC를 만드는 함수
HDC GetDC(HWND hWnd);
- DC의 정보를 얻어서 GDI함수를 사용하면 화면에 그림이 그려짐.
- ※ 주의 ※ : GetDC()로 얻어온 DC핸들러의 Bitmap 객체는 SelectObject()를 이용해서 다른 Bitmap객체로 변경 불가함
hWnd 매개변수
에 NULL을 하면전체화면
으로 그려짐.
화면 전체에 그림그리기
HDC h_screen_dc = ::GetDC(NULL); // 화면 DC를 얻는다.
Reatangle(h_screen_dc, 50, 50, 100, 100); // 사각형을 그린다.
- 이렇게 전체화면의 시작(0,0) 에서 네모가 생성됐다.(신기하다!!)
HDC h_screen_dc = ::GetDC(hWnd); // 현재윈도우의 DC를 얻는다.
Reatangle(h_screen_dc, 50, 50, 100, 100); // 사각형을 그린다.
ReleaseDC() - DC 제거하기
- DC는 사용 개수 제한이 있음. GetDC를 남용하다보면 더이상 사용못함.
- DC를 사용하면 무조건 반환해줘야함
ReleaseDC() 의 원형이다.
int Release(HWND hWnd, HDC nDC);
HDC h_cd = ::GetDC(hWnd); // m_hWnd에 해당하는 윈도우의 DC값을 얻는다.
Rectangle(h_dc, -50, -50, 50,50); // 사각형을 그린다.
::Release(m_hWnd, h_dc); h_dc를 제거한다.
DC를 여러 개 생성하기
HDC h_dc1 = ::GetDC(m_hWnd);
HDC h_dc2 = ::GetDC(m_hWnd);
Rectangle(h_dc1, 50, 50, 100, 100);
Rectangle(h_dc2, 100, 100, 150, 150);
::ReleaseDC(m_hWnd, h_dc1);
::ReleaseDC(m_hWnd, h_dc2);
- 오옹!!!! 된다!!
- 이렇게 하나의 윈도우에 여러 DC를 사용해서 여러 그림을 그릴수 있다.
- ※주의※ : 이렇게 사용하면 그래픽자원에 무리를 줌.
- 일반적으로 보통 윈도우 한개에 DC 하나만 사용함.
점단위 좌표를 기억하는 자료형(DataType)
pixel(점) 단위 조표를 사용하는 대표적인 것중하나가 마우스 좌표다.
점 단위 좌표 저장
int x, y;
: (x,y) 좌표를 다룬다.
short x, y;
: 근데 4K 해상도를 넘기는게 아니면 short형도 ㄱㅊ다.
GetCursorPos() : 커서위치 반환
BOOL GetCurosorPos(LPPOINT lpPoint);
- LPPOINT 형식으로 받아온다.
typedef tagPoINT FAR *LPPOINT;
이런 구조체로 되어있다.- 16비트 시스템 에선 NEAR 키워드를 사용했는데 지금은 그냥 FAR키워드를 사용한다.
struct gatPOIT *PPOINT;
struct tagPOINT{
LONG x;
LONG y;
};
- 이런식으로 되어있음
!!그냥 이렇게 쓰면 된다!!
POINT pos;
GetCursorPos(&pos); // 마우스 커서의 좌표를 얻음(화면좌표)
CPoint - MFC에서 제공되는 C++클래스
CPoint pos;
GetCursorPos(&pos); // 마우스 커서의 좌푤르 얻음 (화면 좌표)
POINT vs CPoint
단순한 점좌표
만 저장사용할거면POINT
- 다른 점과 위치 또는 거리에 대한 개념을 계산하거나 비교하자만
CPoit
Author And Source
이 문제에 관하여([Win32] 5. GDI 시스템 이해(1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@psh4204/Win32-5.-GDI-시스템-이해저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)