MFC Windows程序设计--位图,区域

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画刷三者结合的方式。

名字等价的二进制值执行的操作
SRCCOPY0xCC0020S
SRCPAINT0xEE0086S OR D
SRCAND0x880DC6S AND D
SRCINVERT0x660046S XOR D
SRCERASE0x440328S AND (NOT D)
NOTSRCCOPY0x330008NOT S
NOTSRCERASE0x1100A6(NOT S) AND (NOT D)
MERGECOPY0xC000CAS AND P
PATCOPY0xF00021P
PATPAINT0xFB0A09P OR (NOT S) OR D
PATINVERT0x5A0049P XOR D
DSTINVERT0x550009NOT D
BLACKNESS0x000042BLACK
WHITENESS0xFF0062WHITE

通过对下面位值做逻辑运算,用结果在 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);

nFlagResult
RGN_COPY1
RGN_AND1 and 2
RGN_OR1 or 2
RGN_DIFF1 - 2
RGN_XOR1 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 // 使窗口具备定制的形状,不必再非得是矩形。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值