1.在CDrawView里添加一个消息响应按下左键。会在程序的三个地方有变动。
头文件中添加了一条消息响应函数的声明。
// 生成的消息映射函数
protected:
afx_msg void OnFilePrintPreview();
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
DECLARE_MESSAGE_MAP()
另外还有一条消息映射表,确定了消息和消息响应函数的映射。
BEGIN_MESSAGE_MAP(CDrawView, CView)
// 标准打印命令
ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CDrawView::OnFilePrintPreview)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
具体执行程序:
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
MessageBox(TEXT("View cliked!"));
CView::OnLButtonDown(nFlags, point);
}
2.给CDrawView添加CPoint变量。
会自动更新构造函数,给该变量一个缺省值。
CDrawView::CDrawView()
: m_tOrigin(0)
{
// TODO: 在此处添加构造代码
}
3.添加一个响应左键抬起的消息响应函数。MoveToEx是指把当前点(左上角0点)移动到一个特定的位置,即鼠标按下的位置。LineTo是画线到某一个特定点即鼠标抬起的位置。
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
HDC hdc;
hdc=::GetDC(m_hWnd);
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);//从当前点回到某一个特定的点
LineTo(hdc,point.x,point.y);//从当前点划线到某一个特定点
::ReleaseDC(m_hWnd,hdc);
CView::OnLButtonUp(nFlags, point);
}
4.使用CDC类来绘图:即不再使用全局SDK提供的GetDC,ReleaseDC等等函数,而是封装在CDC类里的函数。
<span style="font-size:14px;">void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
CDC *pDC=GetDC();
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);
CView::OnLButtonUp(nFlags, point);
}</span>
5.使用CClientDC,派生类,其父类为CDC。支持自动获得DC和析构DC,只需要一个CWnd* 就可以构造一个CClientDC对象。
<span style="font-size:14px;">void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
CClientDC dc(this);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
CView::OnLButtonUp(nFlags, point);
}</span>
如果想把DC关联到CMainFrame,只需要用CClientDC dc(GetParent());
如果要把DC关联到整个桌面窗口,需要用CWindowDC类,并且要获得桌面的指针。
CWindowDC dc(GetDesktopWindow());
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
CView::OnLButtonUp(nFlags, point);
6.画笔CPen:通过DC的Slectobject函数可以选择线的性质。
CBrush brush(RGB(255,0,0));
CClientDC dc(this);
dc.FillRect(CRect(m_ptOrigin,point),&brush);
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP2);
CBrush brush(&bitmap);
CClientDC dc(this);
dc.FillRect(CRect(m_ptOrigin,point),&brush);
CClientDC dc(this);
CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
CBrush *pOldBrush = dc.SelectObject(pBrush);
dc.Rectangle(CRect(m_ptOrigin,point));
7.如何绘制连续的线:首先增加一个BOOL型的成员变量给CDrawView,然后在这个变量在ON BOTTOMDOWN的消息响应函数中置为TRUE,在ON BOTTOMUP里被置为0.另外写MOUSEMOVE的消息响应函数。
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CClientDC dc(this);
CPen pen(PS_SOLID,4,RGB(0,0,255));
CPen *pOldPen = dc.SelectObject(&pen);
if(m_bDraw == TRUE)
{
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
m_ptOrigin = point;
}
dc.SelectObject(pOldPen);
CView::OnMouseMove(nFlags, point);
}
画出扇形:设置两个点,m_pOld和point,不断的从m_ptOrigin划线到m_pOld就可以画出扇形。
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(0,0,255));
CPen *pOldPen = dc.SelectObject(&pen);
if(m_bDraw == TRUE)
{
dc.SetROP2(R2_BLACK);
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_pOld);
m_pOld = point;
}
dc.SelectObject(pOldPen);
CView::OnMouseMove(nFlags, point);
}
如果希望画出有边框的扇形:
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(0,0,255));
CPen *pOldPen = dc.SelectObject(&pen);
if(m_bDraw == TRUE)
{
dc.SetROP2(R2_BLACK);
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_pOld);
dc.MoveTo(m_pOld);
dc.LineTo(point);
m_pOld = point;
}
dc.SelectObject(pOldPen);
CView::OnMouseMove(nFlags, point);
}