MFC中绘图的时候,不止是绘制单独的线、圆、正方形等。
还需要显示图片等功能。
MFC中显示图片需要用到CDC类和CBitmap等类中的函数。
下面以加载一张位图为例,在MFC中增加一张位图。
1 定义一个位图对象和CDC绘图设备对象
CBitmap bitmap;//定义位图对象
CDC m_dc;//定义绘图设备
2 给位图对象加载一张位图资源
bitmap.LoadBitmap(IDB_BITMAP1);//加载位图资源,将位图资源加载位图对象中
3 使用CDC对象显示位图
void C绘图Dlg::OnPaint()
{
CRect rect;
GetClientRect(&rect);
CPaintDC dc(this); // 用于绘制的设备上下文
m_dc.CreateCompatibleDC(&dc);//产生与pDC指定设备兼容的设备上下文内存
m_dc.SelectObject(bitmap); //将位图对象选入设备上下文中
dc.BitBlt(0, 0, rect.Width(), rect.Height(), &m_dc, 0, 0, SRCCOPY);
}
4 释放CDC类对象
m_dc.DeleteDC();//释放m_dc
运行结果:
加载一张透明位图
1 定义一个位图对象和CDC绘图设备对象
CBitmap bitmap;//定义位图对象
CDC m_dc;//定义绘图设备
2 给位图对象加载一张位图资源
bitmap.LoadBitmap(IDB_BITMAP2);//加载位图资源,将位图资源加载位图对象中
3 在OnPaint函数中加载透明位图
void C绘图Dlg::OnPaint()
{
CRect rect;
GetClientRect(&rect);
CPaintDC dc(this); // 用于绘制的设备上下文
m_dc.CreateCompatibleDC(&dc);//产生与pDC指定设备兼容的设备上下文内存
m_dc.SelectObject(bitmap);
CDC dcImage;//创建临时DC
CBitmap bmp;
bmp.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
dcImage.CreateCompatibleDC(&dc);
dcImage.SelectObject(bmp);
CBitmap bmpMask;//创建临时DC
bmpMask.CreateBitmap(rect.Width(), rect.Height(), 1, 1, NULL);// 创建单色掩码位图
CDC dcMask;//掩码DC
dcMask.CreateCompatibleDC(&dc);
dcMask.SelectObject(bmpMask);
//将载入位图的内存DC中的位图,拷贝到临时的DC中
dcImage.BitBlt(0, 0, rect.Width(), rect.Height(), &m_dc, 0, 0, SRCCOPY);
//设置临时DC的透明色
dcImage.SetBkColor(RGB(0, 0, 0));
//掩码DC的透明区域为白色其他区域为黑色
dcMask.BitBlt(0, 0, rect.Width(), rect.Height(), &dcImage, 0, 0, SRCCOPY);
//临时DC透明区域为黑色,其他区域不变
dcImage.SetBkColor(RGB(0, 0, 0));
dcImage.SetTextColor(RGB(255, 255, 255));
dcImage.BitBlt(0, 0, rect.Width(), rect.Height(), &dcMask, 0, 0, SRCAND);
//目标DC透明部分保持屏幕不变,其他部分变成黑色
dc.SetBkColor(RGB(255, 255, 255));
dc.SetTextColor(RGB(0, 0, 0));
dc.BitBlt(0, 0, rect.Width(), rect.Height(), &dcMask, 0, 0, SRCAND);
dc.BitBlt(0, 0, rect.Width(), rect.Height(), &dcImage, 0, 0, SRCPAINT);
m_dc.DeleteDC();
}
4 释放CDC类对象
m_dc.DeleteDC();
原图:
显示透明图:
加载一张动图
1 创建需要用到的CBitmap位图对象加载需要显示的图片(在.h 文件中)
CBitmap bit[8];//定义绘图对象位图数组,用于加载蝴蝶位图
2 创建在绘图过程中需要使用的CDC类上下文绘图设备(在.h 文件中)
CDC dc[8];//定义蝴蝶突变设备
3 创建定时器和向位图中加载图片(在初始化窗口函数中)
for (int i = 0; i < 8; i++)//加载蝴蝶位图
{
bit[i].LoadBitmap(IDB_1+i);
}
SetTimer(1, 10, NULL);//设计定时器,没10ms触发一次
4 在定时器中显示需要显示的图片
void C二级缓存Dlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CClientDC cd(this);
static int i = 0;
if (i > 7)
{
i = 0;
}
CRect rect;
GetClientRect(&rect);
dc[i].CreateCompatibleDC(&cd);//产生与pDC指定设备兼容的设备上下文内存
dc[i].SelectObject(bit[i]);
CDC dcImage;//创建临时DC
CBitmap bmp;
bmp.CreateCompatibleBitmap(&cd, rect.Width(), rect.Height());
dcImage.CreateCompatibleDC(&cd);
dcImage.SelectObject(bmp);
CBitmap bmpMask;//创建临时DC
bmpMask.CreateBitmap(rect.Width(), rect.Height(), 1, 1, NULL);// 创建单色掩码位图
CDC dcMask;//掩码DC
dcMask.CreateCompatibleDC(&cd);
dcMask.SelectObject(bmpMask);
//将载入位图的内存DC中的位图,拷贝到临时的DC中
dcImage.BitBlt(0, 0, rect.Width(), rect.Height(), &dc[i], 0, 0, SRCCOPY);
//设置临时DC的透明色
dcImage.SetBkColor(RGB(0, 0, 0));
//掩码DC的透明区域为白色其他区域为黑色
dcMask.BitBlt(0, 0, rect.Width(), rect.Height(), &dcImage, 0, 0, SRCCOPY);
//临时DC透明区域为黑色,其他区域不变
dcImage.SetBkColor(RGB(0, 0, 0));
dcImage.SetTextColor(RGB(255, 255, 255));
dcImage.BitBlt(0, 0, rect.Width(), rect.Height(), &dcMask, 0, 0, SRCAND);
//目标DC透明部分保持屏幕不变,其他部分变成黑色
cd.SetBkColor(RGB(255, 255, 255));
cd.SetTextColor(RGB(0, 0, 0));
cd.BitBlt(0, 0, rect.Width(), rect.Height(), &dcMask, 0, 0, SRCAND);
cd.BitBlt(0, 0, rect.Width(), rect.Height(), &dcImage, 0, 0, SRCPAINT);
dc[i].DeleteDC();
i++;
CDialogEx::OnTimer(nIDEvent);
}