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;

}

相关推荐
askah66448 小时前
如何快速解决Windows系统中的emp.dll问题
windows·microsoft·电脑·dll文件找回·dll丢失
Code成立14 小时前
《Java核心技术 卷I》用户图形界面鼠标事件
java·开发语言·计算机外设
湖南罗泽南19 小时前
Windows C++ TCP/IP 两台电脑上互相传输字符串数据
c++·windows·tcp/ip
小奥超人19 小时前
PPT技巧:如何合并PPT文件?
windows·经验分享·microsoft·powerpoint·办公技巧
MarcoAI20 小时前
github SSH连接(windows)
windows·ssh·github
IT技术分享社区1 天前
电脑技巧:推荐一款开源免费的多显示器管理工具Dual Monitor Tools
计算机外设·电脑·硬件知识·屏幕管理
天幕繁星1 天前
docker desktop es windows解决vm.max_map_count [65530] is too low 问题
windows·elasticsearch·docker·docker desktop
百锦再2 天前
详解基于C#开发Windows API的SendMessage方法的鼠标键盘消息发送
windows·c#·计算机外设
IT-民工211102 天前
Ansible剧本检测Windows防火墙状态
linux·运维·windows·自动化·ansible
菜鸟江多多2 天前
【windows 下使用 tree】
windows