DDB
DIB
DIB扩展
DDB和CBitmap类
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc, nWidth, nHeight);
CBitmap::CreateBitmap
CBitmap::CreateBitmapIndirect
// 用于创建单色位图
// 内存设备描述表,可选入位图作为其显示表面。进内存设备描述表可以。
CClientDC dcScreen(this);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dcScreen, 100, 100);
CDC dcMem;
dcMem.CreateCompatibleDC(&dcScreen);
CBrush brush(RGB(0, 0, 255));
CBitmap *pOldBitmap = dcMem.SelectObject(&bitmap);
dcMem.FillRect(CRect(0, 0, 100, 100), &brush);
dcMem.SelectObject(pOldBitmap);
按位将位图传送到屏幕和其它设备
CDC::BitBlt
CDC::StretchBlt
// 两个函数中出现的数字的单位都是相应设备描述表下的逻辑单位
dcScreen.BitBlt(0, 0, 100, 100, &dcMem, 0, 0, SRCCOPY);
dcScreen.StretchBlt(0, 0, 50, 200, &dcMem, 0, 0, 100, 100, SRCCOPY);
CDC::SetStretchBltMode
CBitmap::GetBitmap(BITMAP*);
typedef struct tagBITMAP
{
LONG bmType;// =0
LONG bmWidth; // 设备单位
LONG bmHeight;// 设备单位
LONG bmWidthBytes;// 字节为单位。每行长度。总是2倍数。
WORD bmPlanes;// 颜色位面数
WORD bmBitsPixel;// 每位像素数
LOVOID bmBits;// 位图信息
}
BITMAP;
// 位图可包含颜色数
int nColors = 1 << (bm.bmPlanes * bm.bmBitsPixel);
…
void CMyBitmap::DrawBitmap(CDC *pDC, int x, int y)
{
BITMAP bm;
GetBitmap(&bm);
CPoint size(bm.bmWidth, bm.bmHeight);
pDC->DPtoLP(&size);
CPoint org(0, 0);
pDC->DPtoLP(&org);
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
CBitmap *pOldBitmap = dcMem.SelectObject(this);
dcMem.SetMapMode(pDC->GetMapMode());
pDC->BitBlt(x, y, size.x, size.y, &dcMem, org.x, org.y, SRCCOPY);
dcMem.SelectObject(pOldBitmap);
}
CDC::DPtoLP传入参数是 CSize,MFC会干预让CSize中负值变为正值。(有时这样是不希望的。都传入CPoint吧)
位图资源:
// RC
IDB_MYLOGO BITMAP logo.bmp
// cpp
CBitmap bitmap;
bitmap.LoadBitmap(IDB_MYLOGO);
// 加载位图,并将位图中某颜色变为指定色
bitmap.LoadMappedBitmap(IDB_BITMAP);
// 黑色-->COLORBTNTEXT
// 深灰色-->COLOR_BTNSHADOW
DIB和DIB分区
::CreateDIBitmap
::GetDIBits
::SetDIBits
位块传送,光栅操作,颜色映射
BitBlt,StretchBlt中光栅操作码,规定了 源DC,目标DC,目标DC画刷三者结合的方式。
名字 | 等价的二进制值 | 执行的操作 |
---|---|---|
SRCCOPY | 0xCC0020 | S |
SRCPAINT | 0xEE0086 | S OR D |
SRCAND | 0x880DC6 | S AND D |
SRCINVERT | 0x660046 | S XOR D |
SRCERASE | 0x440328 | S AND (NOT D) |
NOTSRCCOPY | 0x330008 | NOT S |
NOTSRCERASE | 0x1100A6 | (NOT S) AND (NOT D) |
MERGECOPY | 0xC000CA | S AND P |
PATCOPY | 0xF00021 | P |
PATPAINT | 0xFB0A09 | P OR (NOT S) OR D |
PATINVERT | 0x5A0049 | P XOR D |
DSTINVERT | 0x550009 | NOT D |
BLACKNESS | 0x000042 | BLACK |
WHITENESS | 0xFF0062 | WHITE |
通过对下面位值做逻辑运算,用结果在 Ternary Raster Operations找到相应的DWORD码,可使用自定义的光栅操作。
PAT 1 1 1 1 0 0 0 0
SRC 1 1 0 0 1 1 0 0
DEST 1 0 1 0 1 0 1 0
CDC位块传送函数:
BitBlt
StretchBlt
PatBlt
MaskBlt
PlgBlt
GetDeviceCaps(RASTERCAPS);
如果返回值设置了 RC_BITBLT,则设备支持BitBlt。
如返回值设置了 RC_STRETCHBLT,则设备支持StretchBlts。
源DC,目标DC颜色特性匹配时,位块传输最快。
// BitBlt改变的是dcAnd选入的bitmapAnd。这个的每一位只能选0或1.
// BitBlt
// S:单色位图 D:彩色位图 —> 最终结果中,0:D的前景色。1:D的背景色
// S:彩色位图 D:单色位图 —> 最终结果中,S背景色:1 ,其它色:0 // 书上说是D背景色。观察得出是S背景色。
// S:dcImage 彩色位图
// D:dcAnd 单色位图
// D = S,
// dcAnd结果: 位图中和dcImage背景颜色相同,为1.其余为0.
得到HBITMAP方法:
CreateBitmap/CreateCompatibleBitmap
LoadBitmap/LoadImage
区域
CRgn
CRgn创建区域函数
函数名 | 描述 |
---|---|
CreateRectRgn | |
CreateRectRgnIndirect | |
CreateEllipticRgn | |
CreateEllipticRgnIndirect | |
CreateRoundRectRgn | |
CreatePolygonRgn | |
CreatePolyPolygonRgn | |
CreateFromPath | |
CopyRgn |
创建区域函数采用的坐标值是逻辑坐标。
区域不使用时,需要删除。CRgn析构函数中自动删除。
dc.BeginPath();
dc.Ellipse(0, 0, 400, 200);/ dc.TextOut(0, 0, CString(_T("Hello MFC")));
dc.EndPath();
CRgn rgn;
rgn.CreateFromPath(&dc);
Path:
CDC::
BeginPath
EndPath
FillPath
StrokePath
StrokeAndFillPath
WidenPath
SelectClipPath
区域结合:
CRgn::CombineRgn(Rgn1, Rgn2, nFlag);
nFlag | Result |
---|---|
RGN_COPY | 1 |
RGN_AND | 1 and 2 |
RGN_OR | 1 or 2 |
RGN_DIFF | 1 - 2 |
RGN_XOR | 1 xor 2 |
CDC::
FillRgn
PaintRgn
InvertRgn
FrameRgn
CWnd::InvalidateRgn
CDC::GetClipBox //
CRgn::PtInRegion
void CMyWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
CClient dc(this);
dc.DPtoLP(&point);
if(m_rgn.PtInRegion(point))
{
//
}
}
CDC::SelectObject
CDC::SelectClipRgn // 把区域选入设备描述表,选入后,区域成为设备描述表的剪切边界。
CWnd::SetWindowRgn // 使窗口具备定制的形状,不必再非得是矩形。