[SDK]-键盘消息和鼠标消息

前言

各位师傅大家好,我是qmx_07,今天给大家讲解键盘消息和鼠标消息,下一节讲解控件的相关知识点

键盘消息

  • 应用程序从windows接收的关于键盘事件的消息分为击键字符两种
  • windows再发送击键消息的同时 还会发送字符消息
  • Shift、ctrl、alt、光标移动键盘,这些键值只会产生击键消息

系统按键与非系统按键

当键盘按下时,windows会将消息送到消息队列
在这里插入图片描述

  • SYS代表系统,表示这个按键 对于应用程序来讲,更加重要
  • 比如说 ALT+F4 关闭应用程序,ALT+TAB 换页,程序通常忽略WM_SYSKEYUP和WM_SYSKEYDOWN消息,并将它们传送到DefWindowProc。
  • 由于Windows要处理所有Alt键的功能,所以不需要进行拦截消息
  • WM_KEYDOWN和WM_KEYUP消息通常是在按下或者释放不带Alt键的键时产生的

虚拟键码

  • 虚拟键码保存在WM_KEYDOWN,WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP消息的wParam参数中,该参数标识了按下或释放的键

获取键盘消息

LRESULT CALLBACK WndProc(
HWND hWnd,//窗口句柄
UINT message,//消息ID
WPARAM wParam, //虚拟码
LPARAM lParam)//键盘发过来的原始数据,转换为虚拟码

位移状态

  • SHORT FLAG = GetKeyState (VK_SHIFT) & 0x8000; 如果按下了键盘按钮,则这个值为负,& 0x8000 会让系统更加稳定,减少出错

获取键盘消息

    case WM_KEYDOWN:
    {
        switch (wParam)
        {
        case VK_F1:
        {
            SHORT Flag = (GetKeyState(VK_SHIFT) & 0x8000);//判断SHIFT是否按下
            if (Flag < 0)
            {
                MessageBox(NULL, L"SHIFT + F1", L"Msg", MB_OK);//SHIFT + F1同时按下
            }
            else
            {
                MessageBox(NULL, L"F1", L"Msg", MB_OK);//F1按下
            }

            break;
        }

        default:
            break;
        }
        break;
    }

在这里插入图片描述

  • 通过GetKeyState()函数的方式,捕获多个按键消息

通过SendMessage()获取键盘消息

SendMessage(
    _In_ HWND hWnd,//窗口句柄
    _In_ UINT Msg,//消息 也就是到那个地方去处理
    _Pre_maybenull_ _Post_valid_ WPARAM wParam,//按下的按钮
    _Pre_maybenull_ _Post_valid_ LPARAM lParam);

我们也可以通过按下其他按键来向窗口模拟对应内容,比如说 我们想要通过按下F2,对应F1的按键内容
在这里插入图片描述

    case WM_KEYDOWN:
    {
        switch (wParam)
        {
        case VK_F1:
        {
            SHORT Flag = (GetKeyState(VK_SHIFT) & 0x8000);
            if (Flag < 0)
            {
                MessageBox(NULL, L"SHIFT + F1", L"Msg", MB_OK);
            }
            else
            {
                MessageBox(NULL, L"F1", L"Msg", MB_OK);
            }

            break;
        }
        case VK_F2:
        {
            SendMessage(hWnd,WM_KEYDOWN, VK_F1, NULL);
            break;
        }
        default:
            break;
        }
        break;
    }
    

通过SendMessage()获取其他ID消息

 case WM_KEYDOWN:
    {
        switch (wParam)
        {
        case VK_F1:
        {
            SHORT Flag = (GetKeyState(VK_SHIFT) & 0x8000);
            if (Flag < 0)
            {
                MessageBox(NULL, L"SHIFT + F1", L"Msg", MB_OK);
            }
            else
            {
                MessageBox(NULL, L"F1", L"Msg", MB_OK);
            }

            break;
        }
        case VK_F2:
        {
            SendMessage(hWnd,0x12138, 9999, NULL);
            break;
        }
        default:
            break;
        }
        break;
    }
    case 0x12138:
    {
        switch (wParam)
        {
        case 9999:
        {
            MessageBox(NULL, L"MyMsg", L"Msg", MB_OK);
            break;
        }
        default:
            break;

        }
    }

在这里插入图片描述

  • SendMessage函数,也可以向其他消息ID发送消息请求,来触发处理程序

FindWindow()函数 讲解

FindWindowW(
    _In_opt_ LPCWSTR lpClassName,//窗口类名
    _In_opt_ LPCWSTR lpWindowName);//窗口标题
  • 用于在系统中查找具有指定类名和窗口名的顶级窗口
    在这里插入图片描述
    在这里插入图片描述
    通过 FindWindow()函数来获取句柄,触发消息
        case VK_F2:
        {
            HWND class_hwnd = FindWindow(L"qmx_07", NULL);
            HWND title_hwnd = FindWindow(NULL,L"demo");
            SendMessage(class_hwnd, WM_KEYDOWN, VK_F1, NULL);
            SendMessage(title_hwnd, 0x12138, 9999, NULL);
            break;
        }

鼠标消息

概念

  • 三种状态:单击、双击、拖动
  • 三个按钮:左键(LBUTTON)、右键(RBUTTON)、中键(MBUTTON)
    在这里插入图片描述

1Param的结构解析

  • 低16位存储X坐标:这部分数据表示鼠标光标的X轴位置。
  • 高16位存储Y坐标:这部分数据表示鼠标光标的Y轴位置

宏的使用

  • LOWORD宏提取X坐标
  • HIWORD宏提取Y坐标

通过1Param参数,可以实时获取鼠标位置

wParam的含义

  • 鼠标键状态标识:wParam用来标识鼠标键的状态,例如MK_LBUTTON代表鼠标左键

代码案例

通过鼠标 画线段

POINT Pos[2] = { 0 };
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜单选择:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此处添加使用 hdc 的任何绘图代码...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_LBUTTONDOWN://获取起点的坐标位置
    {

        Pos[0].x = LOWORD(lParam);
        Pos[0].y = HIWORD(lParam);
        break;
    }
    case WM_LBUTTONUP://获取终点的坐标位置画图
    {
        
        Pos[1].x = LOWORD(lParam);
        Pos[1].y = HIWORD(lParam);
        HDC hDC = GetDC(hWnd);
        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);
        ReleaseDC(hWnd, hDC);
        break;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

画面演示:
在这里插入图片描述

  • 通过WM_LBUTTONDOWN 获取鼠标按下的位置,再通过WM_LBUTTONUP获取鼠标抬起的位置,就可以画出线段

通过 WM_MOUSEMOVE 按住鼠标左键 自由绘制图形

    case WM_LBUTTONDOWN:
    {


        break;
    }
    case WM_LBUTTONUP:
    {
        
        break;
    }
    case WM_MOUSEMOVE:
    {
        if (wParam & WM_LBUTTONDOWN)
        {
            int nPosX = LOWORD(lParam);
            int nPosY = HIWORD(lParam);
            HDC hDC = GetDC(hWnd);
            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(hWnd, hDC);
        }
        break;
    }

画图演示:
在这里插入图片描述
通过鼠标左键按住滑动 绘制图形

总结

学习了键盘消息和鼠标消息的原理和使用,下一章节我们学习控件的相关知识

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值