很美丽的一个错误,一小段代码居然生成了一堆我控制不了的花纹,谁能给我解释一下

时间:2021-01-30 10:02:10
OnDraw()函数中使用内存绘图:
CBitmap bmp;
CDC mDC;
myBrush.CreateSolidBrush(m_colorbk);//背景颜色
mDC.CreateCompatibleDC(pDC);
mDC.SetMapMode(MM_HIMETRIC);
bmp.CreateCompatibleBitmap(&mDC,x,y);///............(1)
bmp.CreateCompatibleBitmap(pDC,x,y);///...............(2)
....

pDC->BitBlt(r.left,r.top,r.right,r.bottom,&mDC,r.left,r.top,SRCCOPY);
用(1)居然在屏幕上出现了很漂亮的花纹,但不能显示彩色(2)则正常,这是问什么,
原则上应该用(1)吧?不知道,请高手指点

7 个解决方案

#1


把你的 CDC mDC ;换成 CDC *mDC=GetDC();试一下.

#2


不是这个原因

#3


原则上(2)是对的。 msdn上说得很清楚,基于内存dc的bitmap只能是单色的

#4


调色板问题,pDC与mDC不同

#5


MSDN上对CreateCompatibleBitmap的描述:
If pDC is a memory device context, the bitmap returned has the same format as the currently selected bitmap in that device context. A "memory device context" is a 
block of memory that represents a display surface. It can be used to prepare images in memory before copying them to the actual display surface of the compatible device.

When a memory device context is created, GDI automatically selects a monochrome stock bitmap for it

注意第一句和最后一句:)

#6


mDC.CreateCompatibleDC(pDC);
改为:
mDC.CreateCompatibleDC(&pDC);

#7


你的代码有问题?
bmp.CreateCompatibleBitmap(pDC,x,y);///............(1)
CBitmap* pOldBmp = memDC.SelectObject(&bmp); //add this one
...

memDC.SelectOjbect(pOldBmp);

//use this class ok
class CxMemDC : public CDC
{
private:
CBitmap* m_pBitmap;
CBitmap* m_pOldBitmap;
CDC*     m_pDC;
CRect    m_rcBounds;

public:
CxMemDC(CDC* pDC,  CRect& rcBounds) : CDC()
{
CreateCompatibleDC(pDC);
m_pBitmap = new CBitmap;
m_pBitmap->CreateCompatibleBitmap(pDC,rcBounds.Width(),rcBounds.Height());
m_pOldBitmap = SelectObject(m_pBitmap);
m_rcBounds = rcBounds;
m_pDC = pDC;
}

~CxMemDC()
{
::BitBlt(m_pDC->m_hDC,m_rcBounds.left,m_rcBounds.top,m_rcBounds.Width(),m_rcBounds.Height(),
   this->m_hDC, m_rcBounds.left,m_rcBounds.top,SRCCOPY);
SelectObject(m_pOldBitmap);
if(m_pBitmap != NULL)
{
delete m_pBitmap;
m_pBitmap = 0;
}
}

CxMemDC* operator ->()
{
return this;
}
};

#1


把你的 CDC mDC ;换成 CDC *mDC=GetDC();试一下.

#2


不是这个原因

#3


原则上(2)是对的。 msdn上说得很清楚,基于内存dc的bitmap只能是单色的

#4


调色板问题,pDC与mDC不同

#5


MSDN上对CreateCompatibleBitmap的描述:
If pDC is a memory device context, the bitmap returned has the same format as the currently selected bitmap in that device context. A "memory device context" is a 
block of memory that represents a display surface. It can be used to prepare images in memory before copying them to the actual display surface of the compatible device.

When a memory device context is created, GDI automatically selects a monochrome stock bitmap for it

注意第一句和最后一句:)

#6


mDC.CreateCompatibleDC(pDC);
改为:
mDC.CreateCompatibleDC(&pDC);

#7


你的代码有问题?
bmp.CreateCompatibleBitmap(pDC,x,y);///............(1)
CBitmap* pOldBmp = memDC.SelectObject(&bmp); //add this one
...

memDC.SelectOjbect(pOldBmp);

//use this class ok
class CxMemDC : public CDC
{
private:
CBitmap* m_pBitmap;
CBitmap* m_pOldBitmap;
CDC*     m_pDC;
CRect    m_rcBounds;

public:
CxMemDC(CDC* pDC,  CRect& rcBounds) : CDC()
{
CreateCompatibleDC(pDC);
m_pBitmap = new CBitmap;
m_pBitmap->CreateCompatibleBitmap(pDC,rcBounds.Width(),rcBounds.Height());
m_pOldBitmap = SelectObject(m_pBitmap);
m_rcBounds = rcBounds;
m_pDC = pDC;
}

~CxMemDC()
{
::BitBlt(m_pDC->m_hDC,m_rcBounds.left,m_rcBounds.top,m_rcBounds.Width(),m_rcBounds.Height(),
   this->m_hDC, m_rcBounds.left,m_rcBounds.top,SRCCOPY);
SelectObject(m_pOldBitmap);
if(m_pBitmap != NULL)
{
delete m_pBitmap;
m_pBitmap = 0;
}
}

CxMemDC* operator ->()
{
return this;
}
};