CDC(HDC)绘图类:
五大GDI对象类:CPen,CBrush,CFont,CBitmap,CRgn
24.1 梯形分页的双缓冲改进和尺寸自适应
24.2 蝴蝶跟随鼠标点击运动
class CHitFlyDlg : public CDialogEx
{CMemoryDC m_dc;//缓冲enum { PAGE_COUNT = 7 };CMemoryDC m_dcBack;CMemoryDC m_dcFly[PAGE_COUNT];int m_nIndex;CPoint m_pos,m_des;//中心点与目标public:CHitFlyDlg(CWnd* pParent = NULL); // 标准构造函数
protected:HICON m_hIcon;virtual BOOL OnInitDialog();afx_msg void OnPaint();
public:afx_msg void OnTimer(UINT_PTR nIDEvent);afx_msg BOOL OnEraseBkgnd(CDC* pDC);afx_msg void OnNcPaint();afx_msg void OnLButtonDown(UINT nFlags, CPoint point);void rePosition();
};
BOOL CHitFlyDlg::OnInitDialog()
{CDialogEx::OnInitDialog();int cx = GetSystemMetrics(SM_CXSCREEN);int cy = GetSystemMetrics(SM_CYSCREEN);m_pos.SetPoint(cx / 2, cy / 2);m_des = m_pos;MoveWindow(0, 0, cx, cy, FALSE);m_dc.Create(cx, cy);//缓冲dcm_dcBack.LoadBitmap(_T("./images/back.bmp"));//背景dcint i = -1;CString str;while (++i<_countof(m_dcFly)){str.Format(_T("./images/%03d.bmp"), i + 1);m_dcFly[i].LoadBitmap(str);//7张蝴蝶dc}SetTimer(1, 20, NULL);SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon, FALSE); // 设置小图标return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CHitFlyDlg::OnPaint()
{CPaintDC dc(this); // 用于绘制的设备上下文CRect rect;GetClientRect(rect);//dc.BitBlt(0, 0, m_dcBack.GetWidth(), m_dcBack.GetHeight(), &m_dcBack, 0, 0, SRCCOPY);m_dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &m_dcBack, 0, 0, m_dcBack.GetWidth(), m_dcBack.GetHeight(), SRCCOPY);if (m_pos != m_des)rePosition();CPoint point = m_pos-CPoint(m_dcFly->GetWidth() / 2, m_dcFly->GetHeight() / 2);m_dcFly[m_nIndex].BitTrans(point.x,point.y, m_dcFly->GetWidth(), m_dcFly->GetHeight(), &m_dc, 0, 0, 0);dc.BitBlt(0, 0, rect.Width(), rect.Height(), &m_dc, 0, 0, SRCCOPY);if (++m_nIndex > 6)m_nIndex = 0;
}
void CHitFlyDlg::OnTimer(UINT_PTR nIDEvent)
{Invalidate(FALSE);CDialogEx::OnTimer(nIDEvent);
}BOOL CHitFlyDlg::OnEraseBkgnd(CDC* pDC)
{return TRUE;
}void CHitFlyDlg::OnNcPaint()
{}void CHitFlyDlg::OnLButtonDown(UINT nFlags, CPoint point)
{m_des = point;CDialogEx::OnLButtonDown(nFlags, point);
}void CHitFlyDlg::rePosition()
{int cx = m_des.x - m_pos.x;int cy = m_des.y - m_pos.y;int r = sqrt(cx*cx + cy*cy);if (r < 5)m_pos = m_des;else{m_pos.x += cx * 5 / r;m_pos.y += cy * 5 / r;}
}
24.3 QQ宠物静止版
void MakeRgn(CRgn& r, COLORREF clTrans)//假设背景颜色是:0,0,0{if (r.GetSafeHandle())r.DeleteObject();r.CreateRectRgn(0, 0, 0, 0);//空RGNint x=0, y=0;int cx = m_size.cx,cy=m_size.cy;while (y < cy){x = 0;while (x < cx){if (GetPixel(x, y) != clTrans){CRgn r1;//一个像素大小的RGNr1.CreateRectRgn(x, y, x + 1, y + 1);//面积为1x1的RGNr.CombineRgn(&r, &r1,RGN_OR);}++x;}++y;}}
BOOL CQQDlg::OnInitDialog()
{CDialogEx::OnInitDialog();m_dcFly.LoadBitmap(_T("./images/001.bmp"));MoveWindow(500, 500, m_dcFly.GetWidth(), m_dcFly.GetHeight(), FALSE);CRgn r;m_dcFly.MakeRgn(r, 0);this->SetWindowRgn(r,FALSE);SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon, FALSE); // 设置小图标return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CQQDlg::OnPaint()
{CPaintDC dc(this); // 用于绘制的设备上下文dc.BitBlt(0, 0, m_dcFly.GetWidth(), m_dcFly.GetHeight(), &m_dcFly, 0, 0, SRCCOPY);/*CRect rect;GetClientRect(rect);dc.FillSolidRect(rect, RGB(255, 0, 0));*/
}
HCURSOR CQQDlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}BOOL CQQDlg::OnEraseBkgnd(CDC* pDC)
{return TRUE;
}
void CQQDlg::OnNcPaint()
{}LRESULT CQQDlg::OnNcHitTest(CPoint point)
{return HTCAPTION;
}
24.4 QQ宠物动画版
class CQQDlg : public CDialogEx
{
// 构造enum {FLY_COUNT=7};CMemoryDC m_dcFly[FLY_COUNT];CRgn m_rs[FLY_COUNT];int m_nIndex;//当前第几帧BOOL CQQDlg::OnInitDialog()
{CDialogEx::OnInitDialog();CString str;int i = 0;while (i < _countof(m_dcFly)){str.Format(_T("./images/%03d.bmp"),i+1);m_dcFly[i].LoadBitmap(str);m_dcFly[i].MakeRgn(m_rs[i], 0);++i;}int x = GetSystemMetrics(SM_CXSCREEN), y = GetSystemMetrics(SM_CYSCREEN);MoveWindow(x/2, y/2, m_dcFly->GetWidth(), m_dcFly->GetHeight(), FALSE);CRgn r;r.CreateRectRgn(0, 0, 0, 0); //必须得先创建一个空白的进行初始化r.CopyRgn(m_rs);//m_rs 等价于 &m_rs[0]this->SetWindowRgn(r,FALSE); //CRgn对象只能设置一次,设置后失效,因此先复制到新对象r中SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon, FALSE); // 设置小图标SetTimer(1, 16, NULL);// TODO: 在此添加额外的初始化代码return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CQQDlg::OnPaint()
{CPaintDC dc(this); // 用于绘制的设备上下文//&m_dcFly[m_nIndex]等价于m_dcFly+m_nIndexdc.BitBlt(0, 0, m_dcFly->GetWidth(), m_dcFly->GetHeight(), m_dcFly+m_nIndex, 0, 0, SRCCOPY);/*CRect rect;GetClientRect(rect);dc.FillSolidRect(rect, RGB(255, 0, 0));*/
}
HCURSOR CQQDlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}BOOL CQQDlg::OnEraseBkgnd(CDC* pDC)
{// TODO: 在此添加消息处理程序代码和/或调用默认值return TRUE;
}void CQQDlg::OnNcPaint()
{}LRESULT CQQDlg::OnNcHitTest(CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值return HTCAPTION ;
}void CQQDlg::OnTimer(UINT_PTR nIDEvent)
{CRgn r;r.CreateRectRgn(0, 0, 0, 0);r.CopyRgn(&m_rs[m_nIndex]);SetWindowRgn(r, TRUE);//Invalidate(FALSE);if (++m_nIndex > 6)m_nIndex = 0;CDialogEx::OnTimer(nIDEvent);
}
24.5 单文档应用程序——绘图软件
24.5.1 矢量图和非矢量图:
矢量图,也称为面向对象的图像或绘图图像,在数学上定义为一系列由线连接的点。
矢量文件中的图形元素称为对象。每个对象都是一个自成一体的实体,它具有颜色、形状、轮廓、大小和屏幕位置等属性。
矢量图是根据几何特性来绘制图形,矢量可以是一个点或一条线,矢量图只能靠软件生成,文件占用内在空间较小,因为这种类型的图像文件包含独立的分离图像,可以自由无限制的重新组合。
它的特点是放大后图像不会失真,和分辨率无关,适用于图形设计、文字设计和一些标志设计、版式设计等。
矢量图软件包括:
corel draw
adobe flash(HTM5取代)
非矢量图形软件包括:
adobe Photoshop。
windows画笔
24.5.2 图形软件的设计:
a)每个层可是圆形、矩形、圆角矩形、直线、铅笔画等等;
b)如果是圆形或矩形层,就需要记录矩形数据(RECT);
c)如果是直线层,就需要记录两个点;
d)如果是铅笔话,就需要记录动态多个点;