Windows SDK(四)鼠标和键盘消息处理

鼠标基础知识

顶级窗口:存在多个窗口时,在最上面的窗口

焦点:鼠标点击窗口后,只有该窗口可以被执行各种操作

鼠标的按键消息

鼠标一般分为三种状态,三个按钮

三种状态:单击,双击,拖动

三个按钮:左键(LBUTTON),右键(RBUTTON),中键(MBUTTON)

左键具有的消息

WM_LBUTTONDOWM 点击鼠标产生的消息

WM_LBUTTONUP 抬起鼠标产生的消息

WM_LBUTTONDBLCLK 双击鼠标产生的消息,有的窗口不支持

右键具有的消息

WM_RBUTTONDOWM 点击鼠标

WM_RBUTTONUP 抬起鼠标

WM_RBUTTONDBLCLK 双击,有时窗口不支持

中键具有的消息

WM_MBUTTONDOWM 点击鼠标

WM_MBUTTONUP 抬起鼠标

WM_MBUTTONDBLCLK 双击,有时窗口不支持

WM_MOUSEWHEEL  鼠标滚轮消息

直接通过messsage进行分发的消息一般是WM开头,也叫顶层消息,如上诸多消息都是顶层消息

鼠标的附加消息

鼠标具有lParam和wParam两种附加消息

lParam,32位大小,低16位LOWORD存储x坐标,高16位HIWORD存储y坐标,用于存储鼠标目

标前的坐标信息

wParam,32位大小,用于存储系统键盘,鼠标输入的消息以及其他按键的状态,例如Ctrl/Shift等

一般情况下鼠标按下和抬起成对出现,在鼠标移动的过程中,会根据移动速度产生一系列的

WM_MOUSEMOVE消息

键盘基础知识

键盘消息的发送:键盘发送的消息只会发送到有焦点的窗口,点击键盘时,系统将对应的硬件扫描

码格式化成消息,发送到操作系统的消息队列中,由操作系统进行消息的初步存储,当应用完成上

一次消息的处理后,系统将会从消息队列中抽取消息分发到应用程序进行翻译处理

我们可以自行操作的键盘消息有四种,可以分为以下两种类型:

非系统按键:

WM_KEYDOWN:按键按下去产生的消息

WM_KEYUP:按键抬起来产生的消息

当按键按下去不放时,系统认为有很多个按下去的消息发送给操作系统,但此时抬起来时,只会有

一次抬起来的消息发送给操作系统

GetMessageTime:获取上次消息时间

系统按键:

WM_SYSKEYDOWN 系统按键按下时产生

WM_SYSKEYUP 系统放开时产生

如ALT+TAB:页面切换,ALT+F4:关闭窗口,诸如此类ALT按键+,都属于系统按键

如果使用系统按键,应用程序会跳过安全消息,直接把该消息交给默认处理程序:

DefWindowProc进行转发,由Windows进行默认处理,应用程序不对该消息进行处理

每个按键都有相应的wParam虚拟键码对应,用于表示按键动作

可以与鼠标或键盘的输入的状态作为参数结合,用于判断是否同时多种行为同时进行,这

些参数如下显示,都是以MK_ 前缀:

MK_LBUTTON : 左键按下

MK_MBUTTON : 中键按下

MK_RBUTTON: 右键按下

MK_SHIFT : Shift键按下

MK_CONTROL : Ctrl键按下

应用如下:在点击鼠标左键时

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

    switch (message)

    {

    case WM_LBUTTONDOWN 用于接收系统鼠标消息,此处左键按下

    {

       if(wParam & MK_SHIFT) 指在左键点击的前提下,shift键按下

       {

           MessageBox(NULL, L"MK_SHIFT + LBUTTON", L"Msg", MB_OK);

       }

       break;

    }

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    default:

        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

}

查找指定类名和窗口名的顶级窗口的两种方式:

方式一,用类名寻找窗口:

HWND hMyHWnd = FindWindow(L"rkvir", NULL); 

方式二,用标题名寻找窗口:

HWND hMyHWnd = FindWindow(NULL, L"GrkDemo");

鼠标点击画点

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

    switch (message)

    {

    case WM_LBUTTONDOWN: 用于接收系统鼠标消息,此处左键按下

    {

        int nPosX = LOWORD(lParam); IParam高低位存储的是点的yx坐标

       int nPosY = HIWORD(lParam); 获取鼠标点击处的xy坐标

       HWND hMyHWnd = FindWindow(NULL, L"GrkDemo");查找指定类名和窗口名的顶级窗口。

       HDC hDC = GetDC(hMyHWnd); 获取窗口句柄

       HPEN hPen = CreatePen(PS_SOLID, 8, RGB(255, 0, 0)); 创建一个画笔

       SelectObject(hDC, hPen); 选择画笔

       POINT pi = { 0 };画笔位置初始化

       MoveToEx(hDC, nPosX, nPosY, &pi); 设置起点坐标

       LineTo(hDC, nPosX, nPosY);  设置终点坐标,此处原地画一个点

       ReleaseDC(hMyHWnd, hDC);  释放设备上下文

    }

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    default:

        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

}

鼠标点击划线

鼠标点击某处,再移动到其他处,松开鼠标,出现一条线

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

    switch (message)

    {

    case WM_LBUTTONDOWN: 用于接收系统鼠标消息,此处左键按下

    {

       Pos[0].x = LOWORD(lParam); 保存第一个点x坐标

       Pos[0].y = HIWORD(lParam); 保存第一个点y坐标

        break;

    }

case WM_LBUTTONUP: 鼠标抬起时绘制

    {

       Pos[1].x = LOWORD(lParam); 保存第二个点x坐标

       Pos[1].y = HIWORD(lParam); 保存第二个点y坐标

       HWND hMyHWnd = FindWindow(NULL, L"GrkDemo"); 查找指定窗口名的顶级窗口。

       HDC hDC = GetDC(hMyHWnd); 获取该窗口的句柄

       HPEN hPen = CreatePen(PS_SOLID, 8, RGB(255, 0, 0)); 创建画笔

       SelectObject(hDC, hPen); 选择画笔

       POINT pi = { 0 }; 画笔位置初始化

       MoveToEx(hDC, Pos[0].x, Pos[0].y, &pi); 画笔移至起始位置

       LineTo(hDC, Pos[1].x, Pos[1].y); 画笔移至结束位置

        break;

    }

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    default:

        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

}

鼠标点击画矩形

鼠标点击某处,再移动到其他点,松开鼠标,出现一个矩形

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM

lParam)

{

    switch (message)

    {

    case WM_LBUTTONDOWN: 用于接收系统鼠标消息,此处左键按下

    {

       Pos[0].x = LOWORD(lParam);保存第一个点x坐标

       Pos[0].y = HIWORD(lParam); 保存第一个点y坐标

        break;

    }

case WM_LBUTTONUP: 鼠标抬起时绘制

    {

        Pos[1].x = LOWORD(lParam);保存第二个点x坐标

       Pos[1].y = HIWORD(lParam); 保存第二个点y坐标

       HWND hMyHWnd = FindWindow(NULL, L"GrkDemo"); 查找指定窗口名的顶级窗口。

       HDC hDC = GetDC(hMyHWnd); 获取该窗口的句柄

       HPEN hPen = CreatePen(PS_SOLID, 8, RGB(255, 0, 0)); 创建画笔

       SelectObject(hDC, hPen); 选择画笔

       Rectangle(hDC, Pos[0].x, Pos[0].y, Pos[1].x, Pos[1].y); 绘制长矩形

        break;

    }

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    default:

        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

}

鼠标点击画圆

鼠标点击某处,再移动到其他点,松开鼠标,出现一个圆

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM

lParam)

{

    switch (message)

    {

    case WM_LBUTTONDOWN: 用于接收系统鼠标消息,此处左键按下

    {

       Pos[0].x = LOWORD(lParam);保存第一个点x坐标

       Pos[0].y = HIWORD(lParam); 保存第一个点y坐标

        break;

    }

case WM_LBUTTONUP: 鼠标抬起时绘制

    {

        Pos[1].x = LOWORD(lParam);保存第二个点x坐标

       Pos[1].y = HIWORD(lParam); 保存第二个点y坐标

       HWND hMyHWnd = FindWindow(NULL, L"GrkDemo");  查找指定窗口名的顶级窗口

       HDC hDC = GetDC(hMyHWnd); 获取该窗口的句柄

       HPEN hPen = CreatePen(PS_SOLID, 8, RGB(255, 0, 0)); 创建画笔

       SelectObject(hDC, hPen); 选择画笔

       Arc(hDC, Pos[0].x, Pos[0].y, Pos[1].x, Pos[1].y, 350, 350, 350, 350); 绘制圆形

       ReleaseDC(hMyHWnd, hDC); 释放设备上下文

       break;

    }

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    default:

        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

}

鼠标点击移动画圆

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM

lParam)

{

    switch (message)

    {

    case WM_LBUTTONDOWN: 用于接收系统鼠标消息,此处左键按下

    {

       Pos[0].x = LOWORD(lParam);保存第一个点x坐标

       Pos[0].y = HIWORD(lParam); 保存第一个点y坐标

        break;

    }

case WM_MOUSEMOVE: 鼠标滑动

    {

       if (wParam & WM_LBUTTONDOWN) 滑动的同时按住左键

       {

            Pos[1].x = LOWORD(lParam);保存第二个点x坐标

           Pos[1].y = HIWORD(lParam); 保存第二个点y坐标

           HWND hMyHWnd = FindWindow(NULL, L"GrkDemo");  查找指定窗口名的顶级窗口

           HDC hDC = GetDC(hMyHWnd); 获取该窗口的句柄

           HPEN hPen = CreatePen(PS_SOLID, 8, RGB(255, 0, 0)); 创建画笔

           SelectObject(hDC, hPen); 选择画笔

           POINT pi = { 0 }; 画笔位置初始化

           MoveToEx(hDC, nPosX, nPosY, &pi); 画笔移至起始位置

           LineTo(hDC, nPosX, nPosY); 画笔移至终点位置

           ReleaseDC(hMyHWnd, hDC); 释放设备上下文

       }      

       break;

    }

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    default:

        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

}

键盘的应用

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

    switch (message)

    {

    case WM_KEYDOWN 用于接收系统键盘按下的消息

    {

       switch (wParam) 传入按键信息

       {

       case VK_F1: 按下按键F1

       {       

           SHORT bFlag = (getKeyState(VK_SHIFT) & 0x8000); 该函数用来获取指定的虚拟键码的按

键的状态,此处判断是否同时按下shift键,加上&0x8000,可以屏蔽其他无关状态

           if(bFlag < 0)  如果获取短整数小于0,说明shift键被按下,如果大于0则没有按下

           {

                MessageBox(NULL, L"F1 + SHIFT", L"Msg", MB_OK); 生成一个窗口

           }

           else

           {

                 MessageBox(NULL, L"F1", L"Msg", MB_OK); 生成一个窗口

           }  

           break;

       }

       case VK_F2: 按下F2,如果想要触发按下F1的消息:

       {

           SendMessage(hWnd, WM_KEYDOWN, VK_F1, NULL); 发送消息到某窗口 参数依次 要发

送到的窗口的句柄 发送的消息 两个附加消息,如主消息的内部各种选择,一般写NULL。该函数不

仅可以发送给自己的窗口,也可以是别的窗口,此处是发送给别的窗口。此时窗口按下F2,会在

要发送的窗口触发按下F1的指令

            SendMessage(hWnd, 0x12138, 9999, NULL); 按下F2,触发0x12138的指令

            break;

       }

       case 'B':

       case 'b': 该方式可以设置按到两种不同按键时,都可以同一种操作

       {

           MessageBox(NULL, L"B/b", L"Msg", MB_OK); 生成一个窗口

           break;

       }

    case 0x12138: 接收一个自定义消息

    {

       switch (wParam)

       {

       case 9999:

       {

           MessageBox(NULL, L"MyMsg", L"Msg", MB_OK);

           break;

       }

       }

       break;

    }

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    default:

        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

}

按钮绘制

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

    switch (message)

    {

    case WM_PAINT:

        {

            PAINTSTRUCT ps; 创建一个包含窗口信息的结构体

            HDC hdc = BeginPaint(hWnd, &ps);告诉Windows系统,开始向显示卡输出内容并将和绘图有关的信息填充到PAINTSTRUCT结构

           HFONT hFont = CreateFont(20, 10, 0, 0, 0, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, L"宋体"); 创建一个字体

           SelectObject(hdc, hFont); 选择应用该字体

           SetBkMode(hdc, TRANSPARENT); 设置背景色

           RECT rect; 创建矩形对象

           SetRect(&rect, 30, 50, 400, 200);设置指定矩形的坐标位置

           SetTextColor(hdc, RGB(0, 0, 255)); 设置字体颜色

           DrawText(hdc, L"蓝色", -1, &rect, DT_NOCLIP); 输出字体

           SetRect(&rect, 30, 100, 400, 200);

           SetTextColor(hdc, RGB(255, 0, 0));

           DrawText(hdc, L"红色", -1, &rect, DT_NOCLIP);

           HBRUSH hSolidBrushBlue = CreateSolidBrush(RGB(0, 0, 255));创建实心画刷

           SelectObject(hdc, hSolidBrushBlue); 选择画刷

           Rectangle(hdc, 90, 50, 120, 80); 绘制矩形

           HBRUSH hSolidBrushRed = CreateSolidBrush(RGB(255, 0, 0));

           SelectObject(hdc, hSolidBrushRed);

           Rectangle(hdc, 90, 100, 120, 130);

           EndPaint(hWnd, &ps);

           break;

      }

    case WM_DESTROY:

        PostQuitMessage(0);

        break;

    default:

        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

}

  • 27
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值