void DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap, LONG xStart, LONG yStart, COLORREF cTransparentColor)  
{  
BITMAP bm;  
COLORREF cColor;  
HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;  
HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;  
HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;  
POINT ptSize;  
/* 초기화 작업 */
hdcTemp = CreateCompatibleDC(hdc);  
SelectObject(hdcTemp, hBitmap); // 비트맵 선택

GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);  
ptSize.x = bm.bmWidth; // 비트맵 가로 크기 
ptSize.y = bm.bmHeight; // 비트맵 세로 크기
DPtoLP(hdcTemp, &ptSize, 1); // 디바이스를 논리적 위치로 변경

// 작업용 DC 생성
hdcBack = CreateCompatibleDC(hdc);  
hdcObject = CreateCompatibleDC(hdc);  
hdcMem = CreateCompatibleDC(hdc);  
hdcSave = CreateCompatibleDC(hdc);  

// 흑백 연산 (and,or연산)에 필요한 비트맵 생성 
bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);  
bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);  
// 작업용 비트맵들 생성 
bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);  
bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);  

// 각 비트맵 삭제 위한 old 비트맵 생성 
bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack);  
bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);  
bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem);  
bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave);  

//그려질 DC와 생성된 임시DC의 맵핑 모드 일치화 
SetMapMode(hdcTemp, GetMapMode(hdc));  

// 원본 보전 작업
BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);  

// 투명화 시킬 색을 Tempdc의 배경색으로 설정,
// 이때 SetBkColor의 리턴 값으로 원본 색 저장
cColor = SetBkColor(hdcTemp, cTransparentColor);  

/* 주어진 비트맵의 투명색(BkColor로 지정된)은 힌색으로,
나머지는 검은색으로하여 BlackWhitedc_1에 저장 */
BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,   
SRCCOPY);  

// 배경 색을 원본 색상 DC를 가져오기
SetBkColor(hdcTemp, cColor);  

// BlackWhitedc_1를 이용 투명 영역(검은색), 비투명 영역(힌색)으로 된 DC생성 
BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,   NOTSRCCOPY);  

// 그려질 hdc에서 비트맵이 위치할 곳의 배경을 작업용 DC로 이동 
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, SRCCOPY);  
//BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, 0, 0, SRCCOPY);  

// 그려질 배경과 and 연산을 통해 배경투명구현(힌색 소멸), 비투명 영역은 검은 색으로
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);  

// 주어진 비트맵과 and 연산을 통해 투명부분(검은색으로), 비투명은 그대로
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);  

// 위에서 만든 2개의 DC(Workdc, Tempdc)의 or 연산을 통해 두 DC결합 
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);  

//  결과를 표시
BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY);  

//  원본을 임시 DC에 복구
BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);  

// 메모리에 있는 각 비트맵 삭제
DeleteObject(SelectObject(hdcBack, bmAndBack));  
DeleteObject(SelectObject(hdcObject,bmAndObject));  
DeleteObject(SelectObject(hdcMem, bmAndMem));  
DeleteObject(SelectObject(hdcSave, bmSave));  
DeleteObject(SelectObject(hdcBack, bmBackOld));  
DeleteObject(SelectObject(hdcObject,bmObjectOld));  
DeleteObject(SelectObject(hdcMem, bmMemOld));  
DeleteObject(SelectObject(hdcSave, bmSaveOld));  

// 각 DC삭제 
DeleteDC(hdcBack);  
DeleteDC(hdcObject);
DeleteDC(hdcMem);    
DeleteDC(hdcSave);  
DeleteDC(hdcTemp);  
DeleteDC(hdc); // 자신의 DC를 삭제하지 않으면 GDI 객체는 계속 늘어나게 된다..
 }  


/// 사용 예시..
DrawTransparentBitmap(::GetDC(((CStatic*)GetDlgItem(컨트롤))->GetSafeHwnd()), (BMP), 0, 0, 색상);

// 미리 정의해 놓고 사용하면 좀더 편리함...
#define TRANS_BITMAP(CTRL, BMP); DrawTransparentBitmap(::GetDC(((CStatic*)GetDlgItem(CTRL))->GetSafeHwnd()), (BMP), 0, 0, BLACK);

+ Recent posts