当前位置: 首页 > article >正文

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

鼠标基础知识

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

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

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

左键具有的消息

WM_LBUTTONDOWM 点击鼠标

WM_LBUTTONUP 抬起鼠标

WM_LBUTTONDBLCLK 双击鼠标,有时窗的不支持

右键具有的消息

WM_RBUTTONDOWM

WM_RBUTTONUP

WM_RBUTTONDBLCLK(双击,有时窗口不支持)

中键具有的消息

WM_MBUTTONDOWM

WM_MBUTTONUP

WM_MBUTTONDBLCLK(双击,有时窗口不支持)

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

lParam,32位大小,低16位存储x坐标,高16位存储y坐标,用于存储鼠标目前的坐标信息

wParam,32位大小,用于存储系统键盘或鼠标输入的消息

键盘基础知识

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

焦点:鼠标点击窗口后,只有该窗口可以被执行各种操作,如键盘发送的消息只会发送到有焦点的

窗口,鼠标点击处叫做焦点

键盘消息的发送:点击键盘时,系统将对应的硬件扫描码格式化成消息,发送到操作系统的消息队

列中,由操作系统进行消息的初步存储,当应用完成上一次消息的处理后,系统将会从消息队列中

抽取消息分发到应用程序进行翻译处理

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

非系统按键:

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);

       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);

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

        break;

    }

case WM_LBUTTONUP: 鼠标抬起时绘制

    {

       Pos[1].x = LOWORD(lParam);

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

       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);

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

        break;

    }

case WM_LBUTTONUP: 鼠标抬起时绘制

    {

        Pos[1].x = LOWORD(lParam);

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

       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);

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

        break;

    }

case WM_LBUTTONUP: 鼠标抬起时绘制

    {

        Pos[1].x = LOWORD(lParam);

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

       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);

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

        break;

    }

case WM_MOUSEMOVE: 鼠标滑动

    {

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

       {

           int nPosX = LOWORD(lParam);

           int nPosY = HIWORD(lParam);

           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键被按到

           {

                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);

           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);设置x30y50位置

           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;

}


http://www.kler.cn/a/231905.html

相关文章:

  • 高翔【自动驾驶与机器人中的SLAM技术】学习笔记(十三)图优化SLAM的本质
  • 李秀贤主演警匪片《蓝色霹雳火》
  • 数据库的隔离机制---对MySQL 默认隔离级别的理解
  • 红外遥控信号解码
  • 如何从docker-hub下载镜像
  • Web导出Excel表格
  • 已解决:tpm2_createpriimay: command not found
  • 相机图像质量研究(7)常见问题总结:光学结构对成像的影响--镜片固化
  • pytorch入门第一天
  • 【Spring连载】使用Spring Data访问Redis(九)----Redis流 Streams
  • 打卡今天学习的命令 (linux
  • 深度学习本科课程 实验3 网络优化
  • Terraform实战(三)-在AWS上尝试Terraform的Vault Provider
  • Golang 并发 Cond条件变量
  • TS学习与实践
  • freertos 源码分析五 任务调度一
  • Linux大集合
  • 使用python实现:判断任意坐标点在STL几何模型的内部或外部
  • go 内存二进制数据操作
  • Redis——缓存设计与优化
  • Python面试题13-18
  • vue3 mathjax2.7.7 数学公式
  • Chrome 沙箱逃逸 -- Plaid CTF 2020 mojo
  • 服务器运存使用率多少正常?
  • Spring Cloud Netflix Eureka的参数调优
  • 在windows的控制台实现贪吃蛇小游戏