15,978
社区成员
发帖
与我相关
我的任务
分享
#define BR_WHITE RGB(255,255,255)
#define BR_BLACK RGB(0,0,0)
#define CENTER_X 195
#define CENTER_Y 195
#define R1 15
#define R2 90
#define R3 100
void CxxxxDlg::OnXXX()
{
// TODO: Add your control notification handler code here
CClientDC dc(this);
// 2 brush
CBrush bkBrush;
bkBrush.CreateSolidBrush(BR_BLACK);
CBrush wtBrush;
wtBrush.CreateSolidBrush(BR_WHITE);
//
HBRUSH orgBrush = NULL;
// draw background
orgBrush=(HBRUSH)SelectObject(dc,bkBrush);
dc.Rectangle(0,0,500,500);
// restore
dc.SelectObject(orgBrush);
// draw a small ball in white color
CRgn rgnSmBall;
rgnSmBall.CreateEllipticRgn(CENTER_X-R1,CENTER_Y-R1,CENTER_X+R1,CENTER_Y+R1);
dc.FillRgn(&rgnSmBall,&wtBrush);
// draw a big ball covers small ball
CRgn rgnBgBall;
rgnBgBall.CreateEllipticRgn(CENTER_X-R3,CENTER_Y-R3,CENTER_X+R3,CENTER_Y+R3);
rgnBgBall.CombineRgn(&rgnBgBall,&rgnSmBall,RGN_XOR);
dc.FillRgn(&rgnBgBall,&wtBrush);
// draw a mid ball also covers small ball
CRgn rgnMdBall;
rgnMdBall.CreateEllipticRgn(CENTER_X-R2,CENTER_Y-R2,CENTER_X+R2,CENTER_Y+R2);
rgnMdBall.CombineRgn(&rgnMdBall,&rgnSmBall,RGN_XOR);
dc.FillRgn(&rgnMdBall,&bkBrush);
}
void CCBlistDlg::OnButton1()
{
////////// Using CreateDIBSection is too slow !
#if 0
ShowWindow(SW_HIDE);
Sleep(0);// compare with Sleep(100)
HDC hScrDC = ::GetDC(NULL);
HDC hMemDC = NULL;
int nWidth = GetSystemMetrics(SM_CXSCREEN);
int nHeight = GetSystemMetrics(SM_CYSCREEN);
hMemDC = ::CreateCompatibleDC(hScrDC);
BITMAPINFO bi;
ZeroMemory(&bi, sizeof(BITMAPINFO));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = nWidth;
bi.bmiHeader.biHeight = nHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 24;
HCURSOR hCursor = GetCursor();
POINT ptCursor;
GetCursorPos(&ptCursor);
ICONINFO IconInfo = {0};
if(GetIconInfo(hCursor, &IconInfo))
{
ptCursor.x -= IconInfo.xHotspot;
ptCursor.y -= IconInfo.yHotspot;
if(NULL != IconInfo.hbmMask)
DeleteObject(IconInfo.hbmMask);
if(NULL != IconInfo.hbmColor)
DeleteObject(IconInfo.hbmColor);
}
BYTE *lpBitmapBits = NULL;
HBITMAP bitmap = ::CreateDIBSection(hMemDC, &bi, DIB_RGB_COLORS, (LPVOID*)&lpBitmapBits, NULL, 0);
HGDIOBJ oldbmp = ::SelectObject(hMemDC, bitmap);
::BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, 0, 0, SRCCOPY);
DrawIconEx(hMemDC, ptCursor.x, ptCursor.y, hCursor, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
int rest = nWidth*3 %4 ;
BITMAPFILEHEADER bh;
ZeroMemory(&bh, sizeof(BITMAPFILEHEADER));
bh.bfType = 0x4d42; //bitmap
bh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bh.bfSize = bh.bfOffBits + (nWidth*3+rest)*nHeight;
CFile file;
if(file.Open("2.bmp", CFile::modeCreate | CFile::modeWrite))
{
file.Write(&bh, sizeof(BITMAPFILEHEADER));
file.Write(&(bi.bmiHeader), sizeof(BITMAPINFOHEADER));
// file.Write(lpBitmapBits, 3 * nWidth * nHeight);
file.Write(lpBitmapBits, (nWidth*3+rest)*nHeight);
file.Close();
}
::SelectObject(hMemDC, oldbmp);
#ifndef TEST// error ! bitmap seperated with lpBitmapBits ?
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,bitmap);
CloseClipboard();
#endif
::DeleteObject(bitmap);
::DeleteObject(hMemDC);
::ReleaseDC(NULL, hScrDC);
ShowWindow(SW_SHOW);
////////// Using CreateCompatibleBitmap is more fast !
#else
ShowWindow(SW_HIDE);
Sleep(100);
CDC *pDC;
pDC = GetDesktopWindow()->GetDC();
if(pDC == NULL) return;
int BitPerPixel = pDC->GetDeviceCaps(BITSPIXEL);
int Width = pDC->GetDeviceCaps(HORZRES);
int Height = pDC->GetDeviceCaps(VERTRES);
CDC memDC;
if(memDC.CreateCompatibleDC(pDC) == 0) return;
CBitmap memBitmap, *oldmemBitmap;
if(memBitmap.CreateCompatibleBitmap(pDC, Width, Height) == NULL) return;
#ifndef TEST// OK
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,memBitmap);
CloseClipboard();
#endif
oldmemBitmap = memDC.SelectObject(&memBitmap);
if(memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY) == 0) return;
BITMAP bmp;
memBitmap.GetBitmap(&bmp);
//计算24位图像每行的字节数
int BytesPerLine = 3 * bmp.bmWidth;
while(BytesPerLine % 4 != 0)
BytesPerLine ++;
BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = 24;//每个像素字节大小
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = BytesPerLine * bmp.bmHeight;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度
BITMAPFILEHEADER bfh = {0};//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;//文件总的大小
bfh.bfType = (WORD)0x4d42;
FILE *fp = fopen("xxxx.bmp", "w+b");
fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头
fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头
byte *p = new byte[bih.biSizeImage];
//获取当前32位图像数据
GetDIBits(memDC.m_hDC,
(HBITMAP) memBitmap.m_hObject,
0,
Height,
p,
(LPBITMAPINFO) &bih,
DIB_RGB_COLORS);
//只取rgb值,存入文件
byte b = 0;//用于填充
for(int i = 0 ; i < bmp.bmWidth * bmp.bmHeight ; i ++)
{
//32位位图图像的格式为:Blue, Green, Red, Alpha
fwrite(&(p[i * 3]), 1, 3, fp);
if(i % bmp.bmWidth == bmp.bmWidth - 1)//填充字节
{
for(int k = 0 ; k < (BytesPerLine - bmp.bmWidth * 3) ; k ++)
fwrite(&b, sizeof(byte), 1, fp);
}
}
delete [] p;
fclose(fp);
memDC.SelectObject(oldmemBitmap);
//
ShowWindow(SW_SHOW);
#endif
AfxMessageBox("xxxx.bmp Created!");
// ShowWindow(SW_MINIMIZE);
}