BitBlt

원형 BOOL BitBlt(HDC hDC,int X,int Y,int nWidth,int nHeignt, HDC hSrcDC,int XSrc,int ySrc,DWORD dwROP);
MFC 원형 BOOL CDC::BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );
인수

▶hDC:비트맵이 복사될 DC

▶X,Y,nWidth,nHeight:비트맵이 복사될 위치의 좌상단 좌표와 폭, 넓이, 이 값은 논리적 좌표값이다.

▶HSrcDC:복사될 비트맵을 가지고 있는 DC. 만약 dwROP가 소스가 필요없는 값이라면 NULL이 될 수도 있다.

▶XSrc,YSrc:복사될 비트맵의 좌측 상단 좌표이며 복사처와 마찬가지로 논리적 좌표값이다. 이 값이 0일 경우 전체 비트맵을 복사한다. 복사원의 폭과 높이는 복사처의 nWidth, nHeight가 적용된다.

▶dwROP:ROP코드, 즉 브러쉬와 복사원, 복사처의 비트맵 색상이 논리 연산될 방법을 지정한다. 모두 256개의 가능한 값이 있지만 실제로 의미를 갖는 없은 다음 15개이며 매크로 상수가 정의되어 있다. 이 외의 ROP코드가 필요할 경우에는 상수를 직접 사용해야 한다. 아래 표에서 S는 복사원 (Source), D는 복사처(Destination), P는 패턴(Pattern, 즉 브러쉬)를 의미한다.

매크로 상수 상수 연산식
BLACKNESS 0x00000042 0
DSTINVERT 0x00550009 ~D
MERGECOPY 0x00C000CA D&S
MERGEPAINT 0x00BB0226 ~S|D
NOTSRCCOPY 0x00330008 ~S
NOTSRCERASE 0x001100A6 ~(S|D)
PATCOPY 0x00F00021 P
PATINVERT 0x005A0049 P^D
PATPAINT 0x00FB0A09 P|~(S|D)
SRCAND 0x008800C6 S&D
SRCCOPY 0x00CC0020 S
SRCERASE 0x00440328 S&~D
SRCINVERT 0x00660046 S^D
SRCPAINT 0x00EE0086 S|D
WHITENESS 0x00FF0062 1

리턴 이상없이 수행했으면 0이 아닌 값을 리턴하고 에러가 발생했을 경우 0을 리턴한다.
설명

하나의 DC에 있는 비트맵을 다른 DC로 복사하는 비트맵 전송함수이다. 이때 두 DC는 호환되어야 하나 만약 색상 포맷이 호환되지 않을 경우 BitBlt는 복사원의 색상 포맷을 복사처의 포멧에 맞게 변경한다. 비트맵을 화면에 출력하기 위해서는 우선 CreateCompatibleDC함수를 사용하여 메모리 DC를 만들어야 하며 SelectObject 함수를 사용하여 메모리 DC에 출력하고자 하는 비트맵을 선택한 후 BitBlt로 실제 화면 DC에 전송한다. 이때 비트맵은 원본 그대로 복사가 되지만 ROP코드에 따라 배경과 함께 논리 연산되어 변형될 수는 있다. 복사원의 비트맵은 복사처의 맴핑모드에 따라 크기가 커지거나 작아지기도 한다. 모든 장치가 BitBlt를 지원하는 것은 아니므로 GetDeviceCaps를 사용하여 BitBlt를 쓸 수 있는 장치인가를 확인해 보아야 한다.

예제 1

이 예제는 리소스에 정의된 IDB_BITMAP 비트맵을 화면의 0,0에 출력한다.

#include "resource.h"
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc,MemDC;
	PAINTSTRUCT ps;
	HBITMAP MyBitmap, OldBitmap;
	int bx,by;
	BITMAP bit;
	
	switch(iMessage) {
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		MemDC=CreateCompatibleDC(hdc);
		MyBitmap=LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1));
		OldBitmap=(HBITMAP)SelectObject(MemDC, MyBitmap);
		GetObject(MyBitmap,sizeof(BITMAP),&bit);
		bx=bit.bmWidth;
		by=bit.bmHeight;
		
		BitBlt(hdc, 0,0,bx,by,MemDC,0,0,SRCCOPY);
		SelectObject(MemDC,OldBitmap);
		DeleteObject(MyBitmap);
		DeleteDC(MemDC);
		EndPaint(hWnd, &ps);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
MemDC 메모리 DC에 IDB_BITMAP1을 선택해 놓고 hdc로 비트맵을 전송하였다. 비트맵의 크기는 GetObject 함수로 구할 수 있다. 실행 결과는 다음과 같다.

비트맵을 출력하는 과정이 번거롭다면 다음 함수를 호출함으로써 비트맵을 곧바로 화면으로 전송할 수도 있다.

void DrawBitmap(HDC hdc,int x,int y,HBITMAP hBit)
{
	HDC MemDC;
	HBITMAP OldBitmap;
	int bx,by;
	BITMAP bit;

	MemDC=CreateCompatibleDC(hdc);
	OldBitmap=(HBITMAP)SelectObject(MemDC, hBit);

	GetObject(hBit,sizeof(BITMAP),&bit);
	bx=bit.bmWidth;
	by=bit.bmHeight;

	BitBlt(hdc,0,0,bx,by,MemDC,0,0,SRCCOPY);

	SelectObject(MemDC,OldBitmap);
	DeleteDC(MemDC);
}

hdc의 (x,y)좌표에 hBit 전체를 출력한다.

예제 2

BitBlt는 같은 DC간의 비트맵 전송에만 사용되는 것은 아니며 같은 DC끼리도 비트맵 전송에 사용할 수 있다. 다음 예제는 화면에 그려진 도형을 마우스 버튼을 누른 위치에 복사한다.

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;

	switch(iMessage) {
	case WM_PAINT:
		hdc=BeginPaint(hWnd, &ps);
		SelectObject(hdc,GetStockObject(LTGRAY_BRUSH));
		Ellipse(hdc,10,10,100,100);
		SelectObject(hdc,GetStockObject(GRAY_BRUSH));
		Rectangle(hdc,50,50,200,150);
		EndPaint(hWnd, &ps);
		return 0;
	case WM_LBUTTONDOWN:
		hdc=GetDC(hWnd);
		BitBlt(hdc,LOWORD(lParam),HIWORD(lParam),100,100,hdc,40,40,SRCCOPY);
		ReleaseDC(hWnd,hdc);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

WM_PAINT에서 도형을 출력해 놓았으면 마우스 왼쪽 버튼을 누르면 BitBlt로 이 도형을 클릭한 위치에 복사한다. 이때 복사처와 복사원은 둘 다 hdc이다. 복사원은 hdc의 작업 영역 (40,40)에 있는 높이 100, 넓이 100의 비트맵이며 복사처는 같은 화면의 마우스로 클릭된 위치이다.

참고함수

PatBlt,LoadBitMap,StretchBlt

플렛폼 95이상
참조 6장 참조

written by http://www.winapi.co.kr