如下的代码是一个ATL项目里的代码,本意是想通过Bitmap实现双缓冲,可是没有显示出任何东西,直接使用原来的di.hdcDraw就可以显示出来。经调试确信代码是执行了的,为什么? HRESULT OnDrawAdvanced(ATL_DRAWINFO& di)
{
RECT& rc = *(RECT*)di.prcBounds;
HDC memDc;
HBITMAP bitmap;
memDc=CreateCompatibleDC(di.hdcDraw);
if (memDc!=NULL)
{
bitmap=CreateCompatibleBitmap(di.hdcDraw,rc.right-rc.left,rc.bottom-rc.top);
SelectObject(memDc, &bitmap);
Ellipse(memDc, rc.left, rc.top, rc.right, rc.bottom);
SetTextAlign(memDc, TA_CENTER|TA_BASELINE);
LPCTSTR pszText = _T("测试");
#ifndef _WIN32_WCE
TextOut(memDc,
(rc.left + rc.right) / 2,
(rc.top + rc.bottom) / 2,
pszText,
lstrlen(pszText));
#else
ExtTextOut(memDc,
(rc.left + rc.right) / 2,
(rc.top + rc.bottom) / 2,
ETO_OPAQUE,
NULL,
pszText,
ATL::lstrlen(pszText),
NULL);
#endif
//__debugbreak();
//SelectStockFont(&memDc);
BOOL b=BitBlt(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom,memDc,0,0,SRCCOPY);
DeleteObject(bitmap);
DeleteDC(memDc);
}
return S_OK;
}
{
RECT& rc = *(RECT*)di.prcBounds;
HDC memDc;
HBITMAP bitmap;
memDc=CreateCompatibleDC(di.hdcDraw);
if (memDc!=NULL)
{
bitmap=CreateCompatibleBitmap(di.hdcDraw,rc.right-rc.left,rc.bottom-rc.top);
SelectObject(memDc, &bitmap);
Ellipse(memDc, rc.left, rc.top, rc.right, rc.bottom);
SetTextAlign(memDc, TA_CENTER|TA_BASELINE);
LPCTSTR pszText = _T("测试");
#ifndef _WIN32_WCE
TextOut(memDc,
(rc.left + rc.right) / 2,
(rc.top + rc.bottom) / 2,
pszText,
lstrlen(pszText));
#else
ExtTextOut(memDc,
(rc.left + rc.right) / 2,
(rc.top + rc.bottom) / 2,
ETO_OPAQUE,
NULL,
pszText,
ATL::lstrlen(pszText),
NULL);
#endif
//__debugbreak();
//SelectStockFont(&memDc);
BOOL b=BitBlt(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom,memDc,0,0,SRCCOPY);
DeleteObject(bitmap);
DeleteDC(memDc);
}
return S_OK;
}
BitBlt(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom,memDc,0,0,SRCCOPY);
--》
BitBlt(di.hdcDraw, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, memDc, 0, 0, SRCCOPY);
是不是黑屏?
Ellipse(memDc, rc.left, rc.top, rc.right, rc.bottom);之前填充一个底色试试
这里应该用Ellipse(memDc, 0, 0, rc.right-rc.left, rc.bottom-rc.top);
同样,TextOut(memDc,
(rc.left + rc.right) / 2,
(rc.top + rc.bottom) / 2,
pszText,
lstrlen(pszText));
等都有问题。
你要注意一个问题,rc.left和rc.top是相对di.hdcDraw而言的位置;与之对应,在memDc中,它的坐标应该是(0,0)
(rc.left + rc.right) / 2,
(rc.top + rc.bottom) / 2,
pszText,
lstrlen(pszText));
应该是
TextOut(memDc,
(rc.right-rc.left) / 2,
(rc.bottom-rc.top) / 2,
pszText,
lstrlen(pszText));
SelectObject(memDc, &bitmap);
Ellipse(memDc, rc.left, rc.top, rc.right, rc.bottom);改成
Ellipse(memDc, 0, 0, rc.Width(), rc.Height());看看极端的例子,假设rc.left = 100, rc.top = 100,然而rc的宽度为50,高度为50,
那么Ellipse(memDc, rc.left, rc.top, rc.right, rc.bottom);将画在了图片外面
而Ellipse(memDc, 0, 0, rc.Width(), rc.Height());从0,0开始算起,应该就能画上去了
是个好主意,不过好像Bitmap不太好保存成文件
{
RECT& rc = *(RECT*)di.prcBounds;
HDC memDc;
HBITMAP bitmap;
memDc=CreateCompatibleDC(di.hdcDraw);
if (memDc!=NULL)
{
int nWidth = rc.right - rc.left();
int nHeight = rc.bottom - rc.top;
bitmap=CreateCompatibleBitmap(di.hdcDraw, nWidth, nHeight);
HBITMAP hOldbmp = (HBITMAP)SelectObject(memDc, &bitmap);
Ellipse(memDc, 0, 0, rc.right, rc.bottom); LPCTSTR pszText = _T("²âÊÔ"); DrawText(memDc, pszText, _tcslen(pszText), &rc, DT_CENTER|DT_VCENTER); BitBlt(di.hdcDraw, 0, 0, nWidth, nHeight, memDc, 0, 0, SRCCOPY);
SelectObject(memDc, &hOldbmp);
DeleteObject(bitmap);
DeleteDC(memDc);
}
return S_OK;
}
{
RECT& rc = *(RECT*)di.prcBounds;
HDC memDc=CreateCompatibleDC(di.hdcDraw);
if (memDc!=NULL)
{
HBITMAP bitmap=CreateCompatibleBitmap(memDc,rc.right-rc.left,rc.bottom-rc.top);
SelectObject(memDc, &bitmap);
Ellipse(memDc, 0, 0, rc.right-rc.left,rc.bottom-rc.top);
SetTextAlign(memDc, TA_CENTER|TA_BASELINE);
LPCTSTR pszText = _T("测试");
ExtTextOut(memDc,
(rc.right-rc.left) / 2,
(rc.bottom-rc.top) / 2,
ETO_OPAQUE,
NULL,
pszText,
lstrlen(pszText),
NULL);
BOOL b=BitBlt(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom,memDc,0,0,SRCCOPY);
DeleteObject(bitmap);
DeleteDC(memDc);
}
return S_OK;
}
我现在的代码是这样的,还是不行,郁闷
HRESULT OnDraw(ATL_DRAWINFO& di)
{
RECT& rc = *(RECT*)di.prcBounds;
HDC memDc=CreateCompatibleDC(di.hdcDraw);
if (memDc!=NULL)
{
HBITMAP bitmap=CreateCompatibleBitmap(memDc,rc.right-rc.left,rc.bottom-rc.top);
SelectObject(memDc, &bitmap);
Ellipse(memDc, 0, 0, rc.right-rc.left,rc.bottom-rc.top);
SetTextAlign(memDc, TA_CENTER|TA_BASELINE);
LPCTSTR pszText = _T("测试");
TextOut(memDc,
(rc.right-rc.left) / 2,
(rc.bottom-rc.top) / 2,
pszText,
lstrlen(pszText));
BOOL b=BitBlt(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom,memDc,0,0,SRCCOPY);
DeleteObject(bitmap);
DeleteDC(memDc);
}
return S_OK;
}补充:我用的是Window7,不会是这个问题吧。
{
RECT& rc = *(RECT*)di.prcBounds;
HDC memDc=CreateCompatibleDC(di.hdcDraw);
if (memDc!=NULL)
{
HBITMAP bitmap=CreateCompatibleBitmap(memDc,rc.right-rc.left,rc.bottom-rc.top);
SelectObject(memDc, &bitmap);
Ellipse(memDc, 0, 0, rc.right-rc.left,rc.bottom-rc.top);
SetTextAlign(memDc, TA_CENTER|TA_BASELINE);
LPCTSTR pszText = _T("测试");
TextOut(memDc,
(rc.right-rc.left) / 2,
(rc.bottom-rc.top) / 2,
pszText,
lstrlen(pszText));
BOOL b=BitBlt(di.hdcDraw, rc.left, rc.top, rc.right-rc.left,rc.bottom-rc.top,memDc,0,0,SRCCOPY);
DeleteObject(bitmap);
DeleteDC(memDc);
}
return S_OK;
}
我觉得不是坐标的问题。
你的坐标很成问题,Maybe就是坐标的问题
我希望你们通过Atl项目测试通过后再给我说我哪里错了。
对于坐标我试了几种写法了,都是不对的,我倒真希望是我的坐标不合适造成的,但结果都是不对的。不要再只靠自己想像回复了。
{
RECT& rc = *(RECT*)di.prcBounds;
HDC memDc;
HBITMAP bitmap;
memDc=CreateCompatibleDC(di.hdcDraw);
if (memDc!=NULL)
{
int nWidth = rc.right - rc.left();
int nHeight = rc.bottom - rc.top;
bitmap=CreateCompatibleBitmap(memDc, nWidth, nHeight);
ASSERT(bitmap);
HBITMAP hOldbmp = (HBITMAP)SelectObject(memDc, &bitmap);
Ellipse(memDc, 0, 0, rc.right, rc.bottom); LPCTSTR pszText = _T("²âÊÔ"); DrawText(memDc, pszText, _tcslen(pszText), &rc, DT_CENTER|DT_VCENTER); BitBlt(di.hdcDraw, 0, 0, nWidth, nHeight, memDc, 0, 0, SRCCOPY);
SelectObject(memDc, &hOldbmp);
DeleteObject(bitmap);
DeleteDC(memDc);
}
return S_OK;
}
Sorry,这个地方写错了,你调试一下,看看的Rect,memDC,bitmap是否正确有效??Debug下看看值是不是正确的
SelectObject(memDc, &bitmap);
Ellipse(memDc, rc.left, rc.top, rc.right, rc.bottom);改成
Ellipse(memDc, 0, 0, rc.Width(), rc.Height());看看极端的例子,假设rc.left = 100, rc.top = 100,然而rc的宽度为50,高度为50,
那么Ellipse(memDc, rc.left, rc.top, rc.right, rc.bottom);将画在了图片外面
而Ellipse(memDc, 0, 0, rc.Width(), rc.Height());从0,0开始算起,应该就能画上去了
//参数说明: hbmp :需保存的图象的句柄 path :保存路径
void XXXX::SaveBmpTofile(HBITMAP hbmp, CString path)
{
//参数说明: hbmp :需保存的图象的句柄 path :保存路径//定义文件头结构 BITMAPFILEHEADER fileHead;
int fileHeadLen = sizeof( BITMAPFILEHEADER );//定义图象信息结构BITMAPINFOHEADER bmpHead;
int bmpHeadLen =sizeof( BITMAPINFOHEADER );
BITMAP bmpObj;
GetObject( hbmp, sizeof(BITMAP), &bmpObj );DWORD fileSizeInByte; //文件总的字节大小//获取系统颜色深度,即每个象素用多少位表还示
DWORD PixelSizeInBit;
CDC srcDC; //系统屏幕设备描述表
srcDC.CreateDC(_T("DISPLAY"), NULL, NULL, NULL);PixelSizeInBit=srcDC.GetDeviceCaps( BITSPIXEL ) * srcDC.GetDeviceCaps( PLANES );fileSizeInByte = fileHeadLen + bmpHeadLen + bmpObj.bmWidth*bmpObj.bmHeight*PixelSizeInBit/8;//初始化文件头结构
fileHead.bfOffBits = fileHeadLen + bmpHeadLen;
fileHead.bfReserved1=0;
fileHead.bfReserved2=0;
fileHead.bfSize = fileSizeInByte;
fileHead.bfType = 0x4D42;///初始图像信息结构
bmpHead.biBitCount = PixelSizeInBit;
bmpHead.biCompression = BI_RGB;
bmpHead.biPlanes = 1;
bmpHead.biHeight = bmpObj.bmHeight;
bmpHead.biWidth = bmpObj.bmWidth;
bmpHead.biSize = bmpHeadLen;//为文件分配空间
PBYTE pFile=new byte[ fileSizeInByte ];
memset( pFile, 0, fileSizeInByte );//填充文件头部
memcpy( pFile, (PBYTE)&fileHead, fileHeadLen); //填充文件信息头部结构
memcpy( pFile+fileHeadLen, (PBYTE)&bmpHead, bmpHeadLen); //填充象素部分
GetDIBits( srcDC.m_hDC, hbmp, 0, bmpObj.bmHeight, pFile+fileHeadLen+bmpHeadLen, (LPBITMAPINFO)(pFile+fileHeadLen), DIB_RGB_COLORS);
//打开文件并写入数据
HANDLE hFile;hFile=CreateFile( path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);if( hFile==INVALID_HANDLE_VALUE )
{
MessageBox(_T("创建文件失败"));
return;
} DWORD nByteTransfered;WriteFile( hFile, pFile, fileSizeInByte, &nByteTransfered, NULL);CloseHandle( hFile ); //清理
delete pFile;
srcDC.DeleteDC();}
lz 给分吧,我应该给你找到原因了HBITMAP bitmap=CreateCompatibleBitmap(memDc,rc.right-rc.left,rc.bottom-rc.top);
这句话,我也遇到过 你的bitmap创建的时候,使用的不是物理的dc,而是用的内存DC,这样画出来的只有黑白。我也遇到过这样的问题
把你的memDc 换成你的物理DC,这里不能使用内存DC
不用mfc的类库,用hdc,hbitmap 都可以噻,
SelectObject(memDc, bitmap);都是代码复制过来不细心造成的!不好意思,连这里的大侠们都惊动了!
散分了!