七、图形编程实例
l 在Win32程序中画线
1. 定义两个全局变量用于记录鼠标按下的(x,y)坐标。
int nOrginX;
int nOrginY;
2. 响应鼠标按下和鼠标抬起的消息:
在Swich中加入case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
3. 在鼠标按下时记录鼠标按下的(x,y)坐标,查MSDN得知WM_LBUTTONDOWN
lParam的低字存放x坐标,高字存放y坐标,将其取出存入nOrginX,nOrginY。
case WM_LBUTTONDOWN:
nOrginX=lParam & 0x0000ffff;
nOrginY=lParam >> 16 & 0x0000ffff;
break;
4. 在鼠标抬起时画线:
case WM_LBUTTONUP:
HDC hdc;
hdc=GetDC(hwnd);
::MoveToEx(hdc,nOrginX,nOrginY,NULL);
::LineTo(hdc,LOWORD(lParam),HIWORD(lParam) );
::ReleaseDC(hwnd,hdc);
l 在MFC程序中画线:
1. 在CxxxView(其中xxx是你的工程名字)中响应鼠标按下和鼠标抬起的消息(因为只有CxxxView中才能接收到鼠标消息):
使用ClassWizard加入WM_LBUTTONDOWN,WM_LBUTTONUP的消息响应函数OnLButtonDown, OnLButtonUp。
2. 在CxxxView中添加成员变量CPoint m_ptOrigin,用于记录鼠标按下的(x,y)坐标。
CPoint是一个用于描述点的简单的类,它有两个成员变量可以存放点的(x,y)坐标。
3. 在鼠标按下时记录该点的坐标:
m_ptOrigin =point;其中point是调用OnLButtonDown传入的鼠标按下的点的坐标。
4. 在鼠标抬起时画线:
CClientDC dc(this);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
其中CClientDC 是一个CDC的子类,在它的构造函数中调用了GetDC,析构函数中调用了ReleaseDC,简化了用户的操作。
l 实现橡皮筋功能:
5. 再定义一个成员变量,用于记录鼠标抬起的点,以便擦线。
CPoint m_ptEnd;
6. 在鼠标按下时记录该点的坐标:
m_ptOrigin=m_ptEnd=point;
7.使用ClassWizard加入WM_MOUSEMOVE的消息响应函数OnMouseMove。
在鼠标移动时判断鼠标左鍵是否按下,如果按下,就不断地擦去上一条线,画出鼠标按下点到鼠标移动的当前点之间的线。
if(MK_LBUTTON & nFlags)
{
CClientDC dc(this);
dc.SetROP2(R2_NOT);
dc.MoveTo(m_ptOrigin);
dc.LineTo(m_ptEnd);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
m_ptEnd=point;
}
其中:
if (MK_LBUTTON & nFlags)
是判断鼠标左鍵是否按下。在调用OnMouseMove时,不仅为用户传来了坐标信息,还把鼠标左鍵是否按下,Shift鍵是否按下(详细信息可查MSDN)等信息放在UINT nFlags中传入OnMouseMove,用户可以检查相应位是否为1来判断相应键是否按下。
dc.SetROP2(R2_NOT);
该句设置逆转当前屏幕颜色的绘图模式。这种模式下,在屏幕上首次画出的线的是可见的,但在同一位置再画一遍时,线就不见了。这样可以方便的实现不断画线、擦线的效果。