鼠标

来源:互联网 发布:在access表中加数据 编辑:程序博客网 时间:2024/04/28 15:23

WM_LBUTTONDOWN、WM_LBUTTONUP、WM_MOUSEMOVE是鼠标的三个基本消息处理,分别表示鼠标左键按下、鼠标左键松开、鼠标移动,这三个主消息的副消息的内容完全相同,下面小雅用WM_MOUSEMOVE的二个副消息为例,来剖析其内容究竟是什么。

lParam副消息存放的是鼠标的座标位置,字节的低4位为x座标,高4位为y座标。用位操作符&很容易就取到鼠标的x和y座标,VC也提供了宏HIWORD()和LOWORD()。

wParam的高4位不用,低4位表示组合键的使用状态。第1位为“1”表示鼠标左键按下,第2位为“1”表示鼠标右键按下,第3位为“1”表示Shift键按下,第4位为“1”表示Ctrl键按下,这4种状态可以组合使用。例如,鼠标左右键同时按下,wParam为3;鼠标左右键和Shift、Ctrl键全部按下则wParam为F。

例子:
        case WM_LBUTTONDOWN:
            if (LOWORD(wParam) & 0x01)
            {
                MessageBox(hWnd, "left mouse", NULL, MB_OK);
            }
            break;  

光标:

作图时,习惯上按下鼠标左键时光标变为“十字形”,松开后恢复为缺省的“箭头”,因此在WM_LBUTTONDOWN消息处理和WM_LBUTTONUP消息处理中要增加对鼠标光标的控制。
光标都是由窗口类最初设定的,一般为箭头,但有人会改变成自己喜好的光标。窗口要控制光标首先要取当前光标的类型并保存,然后取消窗口对光标的控制,并设置光标为“十字形”,这些都是在WM_LBUTTONDOWN的消息处理程序中实现的。在WM_LBUTTONUP的消息处理程序中,还必须恢复窗口对光标的控制,并立即让光标成为窗口默认的光标。
设置光标是用SetCursor()函数,因其简单,不作解释应该没有问题。取当前系统光标的类型是用GetClassLong()函数,设置系统光标的类型是用SetClassLong()函数,这2个函数很重要,并不仅仅针对光标,根据参数的不同,可以取得或设置窗口类型、背景、图标、光标、菜单等等,这些全是注册窗口类时设置的内容。  

如:

  HCURSOR clsCur;
        case WM_LBUTTONDOWN:
            clsCur = (HCURSOR)GetClassLong(hWnd,GCL_HCURSOR); //取当前的光标值 并保存
            SetClassLong(hWnd,GCL_HCURSOR,NULL);   //关闭窗口类对光标的控制
            SetCursor (LoadCursor(NULL, IDC_CROSS)); //设置光标为十字形
            break;
        case WM_LBUTTONUP:
            SetClassLong(hWnd,GCL_HCURSOR,(LONG) clsCur);  //恢复窗口类对光标的控制
            SetCursor (LoadCursor(NULL, IDC_ARROW)); //恢复箭头光标
            break;
画线:

HCURSOR clsCur;
POINTS  point;

        case WM_LBUTTONDOWN:
            clsCur = (HCURSOR)GetClassLong(hWnd,GCL_HCURSOR); //取当前的光标值
            SetClassLong(hWnd,GCL_HCURSOR,NULL);   //关闭窗口类对光标的控制
            SetCursor (LoadCursor(NULL, IDC_CROSS)); //设置光标为十字形
            point .x = LOWORD(lParam);
            point .y = HIWORD(lParam);
            break;
        case WM_LBUTTONUP:
            SetCursor (LoadCursor(NULL, IDC_ARROW));
            hdc = GetDC(hWnd);
            MoveToEx(hdc, point.x, point.y, NULL);
            LineTo(hdc, LOWORD(lParam), HIWORD(lParam));
            ReleaseDC(hWnd, hdc);
            break; 

一个不错的例子:

HCURSOR clsCur;
POINTS  start;
bool bDrawing;


        case WM_LBUTTONDOWN:
            bDrawing = true;   //描画状态开始
            start = MAKEPOINTS(lParam); //开始点保存于start中
 
            //取得窗口有效区
            RECT rect;
            GetClientRect(hWnd,&rect);
 
            //转换窗口有效区为屏幕座标
            POINT point;
            point.x = 0, point.y = 0;
            ClientToScreen(hWnd,&point);
            rect.top = point.y;
            rect.left = point.x;
            rect.bottom += rect.top;
            rect.right += rect.left;
 
            //将光标限定在窗口有效区内
            ClipCursor(&rect);  //rect一定要是屏幕座标
 
            if (!clsCur)
            {
                clsCur =  (HCURSOR)GetClassLong(hWnd,GCL_HCURSOR);  //    取当前窗口的光标
            }
            SetClassLong(hWnd,GCL_HCURSOR,NULL);  //设置当前窗口的光标为NULL
            SetCursor(LoadCursor(NULL, IDC_CROSS));  //设置当前光标为十字形
            break;
        case WM_MOUSEMOVE:
            HDC hdc;
            hdc = GetDC(hWnd);
 
            if (bDrawing) {
                MoveToEx(hdc, start.x, start.y,NULL);
                LineTo(hdc, LOWORD(lParam), HIWORD(lParam));
            }  
            ReleaseDC(hWnd, hdc);
            break;
        case WM_LBUTTONUP:
            bDrawing = false;    //描画状态结束
            ClipCursor(NULL);  //使光标可以在屏幕任意位置移动  
            SetClassLong(hWnd,GCL_HCURSOR, (long)clsCur);  //设置窗口光标为原先的光标
            SetCursor((HCURSOR)clsCur);  //设置当前光标为原先的光标
            break; 



原创粉丝点击