首先在View类定义一些用到的变量:
UINT m_nDrawType; //绘图方式
BOOL m_bLButton; //判断左键状态
CPoint m_ptOrigin; //绘制图形起点
CPoint m_End; //绘制图形终点
在构造函数中赋初值为0,然后在View中添加消息响应函数
void CGraphicView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_ptOrigin=point;
m_ptEnd=point;
m_bLButton=TRUE;
CView::OnLButtonDown(nFlags, point);
}
void CGraphicView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CStatusBar *pStatus; //状态栏显示当前坐标
pStatus=(CStatusBar*)AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
CString status;
status.Format("当前坐标 X = %d Y = %d", point.x, point.y);
pStatus->SetPaneInfo(1,ID_SEPARATOR,SBPS_STRETCH,20);
pStatus->SetPaneText(1,status);
CClientDC dc(this);
int nDrawmode=dc.SetROP2(R2_NOT); //设置绘图模式,并将先前的绘图模式加以保存
dc.SelectStockObject(NULL_BRUSH); //选择空
if(m_bLButton)
{
switch(m_nDrawType) //绘图方式选择
{
case IDM_LINE: //直线
//擦除上次绘制的直线
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
m_ptEnd=point;
//绘制新直线
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
break;
case IDM_Rectangle: //矩形
dc.Rectangle(CRect(m_ptOrigin,m_ptEnd));
m_ptEnd=point;
dc.Rectangle(CRect(m_ptOrigin,m_ptEnd));
break;
case IDM_Ellipse: //椭圆
dc.Ellipse(CRect(m_ptOrigin,m_ptEnd));
m_ptEnd=point;
dc.Ellipse(CRect(m_ptOrigin,m_ptEnd));
break;
}
}
dc.SetROP2(nDrawmode); //恢复到先前的绘图模式
CView::OnMouseMove(nFlags, point);
}
void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_bLButton=FALSE;
CClientDC dc(this);
CPen pen(PS_SOLID,m_nLineWidth,m_color);
dc.SelectObject(&pen);
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
dc.SelectObject(pBrush);
switch(m_nDrawType)
{
case IDM_LINE:
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
break;
case IDM_Rectangle:
dc.Rectangle(CRect(m_ptOrigin,point));
break;
case IDM_Ellipse:
dc.Ellipse(CRect(m_ptOrigin,point));
break;
}
CView::OnLButtonUp(nFlags, point);
}
关于 SetROP2(int nDrawMode)的使用
该函数的主要的作用是根据nDrawMode设置的方式重新设定绘图的方式,下面就不同的nDrawMode值具体解释绘图模式是如何改变的。
首先就nDrawMode的取值有以下的情况:
R2_BLACK Pixel is always black. //所有绘制出来的像素为黑色
R2_WHITE Pixel is always white. //所有绘制出来的像素为白色
R2_NOP Pixel remains unchanged. //任何绘制将不改变当前的状态
R2_NOT Pixel is the inverse of the screen color. //当前绘制的像素值设为屏幕像素值的反,这样可以覆盖掉上次的绘图,(自动擦除上次绘制的图形)
R2_COPYPEN Pixel is the pen color. //使用当前的画笔的颜色
R2_NOTCOPYPEN Pixel is the inverse of the pen color. //当前画笔的反色
//下面是当前画笔的颜色和屏幕色的组合运算得到的绘图模式。
R2_MERGEPENNOT Pixel is a combination of the pen color and the inverse of the screen color (final pixel = (NOT screen pixel) OR pen). //像素颜色是画笔颜色和屏幕颜色的反色中共有颜色的组合 像素颜色=(NOT屏幕颜色)AND画笔颜色
R2_MASKPENNOT Pixel is a combination of the colors common to both the pen and the inverse of the screen (final pixel = (NOT screen pixel) AND pen).
R2_MERGENOTPEN Pixel is a combination of the screen color and the inverse of the pen color (final pixel = (NOT pen) OR screen pixel).
R2_MASKNOTPEN Pixel is a combination of the colors common to both the screen and the inverse of the pen (final pixel = (NOT pen) AND screen pixel).
R2_MERGEPEN Pixel is a combination of the pen color and the screen color (final pixel = pen OR screen pixel).
R2_NOTMERGEPEN Pixel is the inverse of the R2_MERGEPEN color (final pixel = NOT(pen OR screen pixel)).
R2_MASKPEN Pixel is a combination of the colors common to both the pen and the screen (final pixel = pen AND screen pixel).
R2_NOTMASKPEN Pixel is the inverse of the R2_MASKPEN color (final pixel = NOT(pen AND screen pixel)).
R2_XORPEN Pixel is a combination of the colors that are in the pen or in the screen, but not in both (final pixel = pen XOR screen pixel).
R2_NOTXORPEN Pixel is the inverse of the R2_XORPEN color (final pixel = NOT(pen XOR screen pixel)). //像素颜色是既属于画笔颜色又属于屏幕颜色,但并不是两种颜色的公共部分的组合颜色的反色。 XOR代表异或
总之,上述api的一个作用是在需要改变绘图的模式时,不需要重新设置画笔,只需要设置不同的绘图的模式即可达到相应的目的。