/************************************************************************/
/* 윈도우를 그림 모양으로 자르기 */
/************************************************************************/
void CDmbgDlg::SetShapeBitmap(HBITMAP hBitmap, COLORREF clrTransparent)
{
CRgn rgnBitmap; // 비트맵에서 추출한 영역을 저장하는 변수
if(hBitmap == NULL)
{
return;
}
if(rgnBitmap.m_hObject)
{
rgnBitmap.DeleteObject();
}
rgnBitmap.CreateRectRgn(0, 0, 0, 0);
BITMAP bmpInfo;
::GetObject(hBitmap, sizeof(bmpInfo), &bmpInfo);
BITMAPINFOHEADER Header32Bit;
::memset(&Header32Bit, 0, sizeof(Header32Bit));
Header32Bit.biSize = sizeof(BITMAPINFOHEADER);
Header32Bit.biWidth = bmpInfo.bmWidth;
Header32Bit.biHeight = bmpInfo.bmHeight;
Header32Bit.biPlanes = 1;
Header32Bit.biBitCount = 32;
Header32Bit.biCompression = BI_RGB;
HDC hScreenDC = ::GetDC(NULL);
HDC hMemDC = ::CreateCompatibleDC(hScreenDC);
void *pBmpBits = NULL;
HBITMAP h32BitBmp = CreateDIBSection(hMemDC, (BITMAPINFO*)&Header32Bit,
DIB_RGB_COLORS, &pBmpBits, NULL, 0);
if(h32BitBmp)
{
BITMAP bmpInfo32;
::GetObject(h32BitBmp, sizeof(bmpInfo32), &bmpInfo32);
if(bmpInfo32.bmWidthBytes % 4 > 0)
bmpInfo32.bmWidthBytes += (4 - (bmpInfo32.bmWidthBytes % 4));
HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, h32BitBmp);
HDC hBmpDC = ::CreateCompatibleDC(hMemDC);
HBITMAP hOldBmp2 = (HBITMAP)::SelectObject(hBmpDC, hBitmap);
::BitBlt(hMemDC, 0, 0, bmpInfo32.bmWidth, bmpInfo32.bmHeight,
hBmpDC, 0, 0, SRCCOPY);
::SelectObject(hBmpDC, hOldBmp2);
::DeleteDC(hBmpDC);
DWORD dwMaxRect = 100;
HANDLE hRgnData = ::GlobalAlloc(GHND, sizeof(RGNDATAHEADER) + (sizeof(RECT) * dwMaxRect));
RGNDATA *pRgnData = (RGNDATA*)::GlobalLock(hRgnData);
pRgnData->rdh.dwSize = sizeof(RGNDATAHEADER);
pRgnData->rdh.iType = RDH_RECTANGLES;
pRgnData->rdh.nCount = 0;
pRgnData->rdh.nRgnSize = 0;
::SetRect(&pRgnData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
BYTE *pPixel = (BYTE*)bmpInfo32.bmBits + ((bmpInfo32.bmHeight - 1) * bmpInfo32.bmWidthBytes);
int x, y, nStartX;
long *pRGB;
RECT *pRect;
for(y = 0; y < bmpInfo32.bmHeight; y++)
{
for(x = 0; x < bmpInfo32.bmWidth; x++)
{
nStartX = x;
pRGB = (long*)pPixel + x;
for(;x < bmpInfo32.bmWidth; x++, pRGB++)
{
if(::memcmp((char*)pRGB + 1, (char*)&clrTransparent + 1, 3) == 0) break;
}
if(x > nStartX)
{
if(pRgnData->rdh.nCount >= dwMaxRect)
{
::GlobalUnlock(hRgnData);
dwMaxRect += 100;
hRgnData = ::GlobalReAlloc(hRgnData, sizeof(RGNDATAHEADER)
+ (sizeof(RECT) * dwMaxRect), GMEM_MOVEABLE);
pRgnData = (RGNDATA*)::GlobalLock(hRgnData);
}
pRect = (RECT*)&pRgnData->Buffer;
::SetRect(pRect + pRgnData->rdh.nCount, nStartX, y, x, y + 1);
if(nStartX < pRgnData->rdh.rcBound.left)
pRgnData->rdh.rcBound.left = nStartX;
if(y < pRgnData->rdh.rcBound.top)
pRgnData->rdh.rcBound.top = y;
if(x > pRgnData->rdh.rcBound.right)
pRgnData->rdh.rcBound.right = x;
if(y + 1 > pRgnData->rdh.rcBound.bottom)
pRgnData->rdh.rcBound.bottom = y + 1;
pRgnData->rdh.nCount++;
if(pRgnData->rdh.nCount == 2000)
{
CRgn NewRgn;
if(NewRgn.CreateFromData(NULL, sizeof(RGNDATAHEADER)
+ (sizeof(RECT) * dwMaxRect), pRgnData))
{
rgnBitmap.CombineRgn(&rgnBitmap, &NewRgn, RGN_OR);
NewRgn.DeleteObject();
}
pRgnData->rdh.nCount=0;
SetRect(&pRgnData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
pPixel -= bmpInfo32.bmWidthBytes;
}
CRgn NewRgn;
if(NewRgn.CreateFromData(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * dwMaxRect), pRgnData))
{
rgnBitmap.CombineRgn(&rgnBitmap, &NewRgn, RGN_OR);
NewRgn.DeleteObject();
}
::GlobalUnlock(hRgnData);
::GlobalFree(hRgnData);
::SelectObject(hMemDC, hOldBmp);
::DeleteObject(h32BitBmp);
}
::DeleteDC(hMemDC);
::ReleaseDC(NULL, hScreenDC);
SetWindowPos(NULL, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, SWP_NOZORDER | SWP_NOMOVE);
SetWindowRgn(rgnBitmap, ::IsWindowVisible(m_hWnd));
}
BOOL CDmbgDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// 다이얼로그 그림 모양으로 자르기
CBitmap m_bmpWindow;
m_bmpWindow.LoadBitmap(IDB_BACKIMG); // 리소스에서 불러운 이미지 ID 입력
SetShapeBitmap(m_bmpWindow, RGB(255,0,255));
return TRUE; // return TRUE unless you set the focus to a control
}
댓글 없음:
댓글 쓰기