Windows消息,消息循环的处理,消息队列,键盘消息,鼠标消息,定时器消息(三)

简介: Windows消息,消息循环的处理,消息队列,键盘消息,鼠标消息,定时器消息(三)

4.WM_SIZE

MSDN官方文档解释WM_SIZE消息

#define WM_SIZE 0X0005
• 1
  • 产生时间:当窗口大小改变后
  • 附加信息:
  • wParam:请求的大小调整类型
  • lParam:
  • LOWORD:变化后的宽度
  • HIWORD:变化后的高度
  • 返回值:如果应用程序处理此消息,它返回0。
  • 一般用法:常用于窗口大小变化后,调整窗口内各个部分的布局

我们来到回调函数中处理WM_SIZE消息:

LRESULT CALLBACK WindowProc(
  IN  HWND hwnd,
  IN  UINT uMsg,
  IN  WPARAM wParam,
  IN  LPARAM lParam
)
{
  char output[256] = { 0 };
  switch (uMsg)
  {
  //常见消息
  case WM_DESTROY: {
    sprintf(output, TEXT("窗口即将被销毁,将向消息队列中发送WM_QUIT消息"));
    WriteConsole(g_hOUTPUT,output,strlen(output), 0, 0);
    PostMessage(NULL, WM_QUIT, 0, 0);
    break;
    }
  case WM_SYSCOMMAND:{
      sprintf(output, TEXT("检测到WM_COMMAND消息,将弹出提示窗口\n"));
      WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
      MessageBox(hwnd, "记住我!!!", "别忘了", MB_YESNO);
    break;
  }
  case WM_CREATE: {
    sprintf(output, TEXT("检测到WM_CREATE消息,将创建窗口。\n"));
    WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
    break;
  }
  case WM_SIZE: {
    sprintf(output, "iParam:窗口宽变化为:%d,窗口高变化为:%d \n", HIWORD(lParam), LOWORD(lParam));
    WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
    break;
  }
  }
  return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

效果图:

5.WM_QUIT

MSDN官方文档解释WM_QUIT消息

#define WM_QUIT 0X0012
• 1
  • 产生时间:指示终止应用程序的请求,并在应用程序调用PostQuitMessage函数时生成,此消息导致GetMessage函数返回0。
  • 附加信息:
  • wParam:PostQuitMessage函数传递的参数(PostQuitMessage函数中给定的退出代码)
  • lParam:未使用
  • 一般用法:用于结束消息循环,当GetMessage函数抓到这个消息后,会返回FALSE,结束while循环。

我们来到回调函数中处理这个消息:

五.键盘消息

1.键盘消息分类

  • WM_KEYDOWN----键盘被按下时产生
  • WM_KEYUP----键盘被放开时产生
  • WM_SYSKEYDOWN----系统键被按下时产生
  • WM_SYSKEYUP----系统键被放开时产生
  • 附加信息:
  • wParam:按键的虚拟键码
  • lParam:按键的参数,例如按下多少次
  • 2.字符消息 WM_CHAR
  • TranslateMessage函数在转换WM_KEYDOWN消息时,对于可见的字符可以产生WM_CHAR消息,对于不可见字符,不会产生此消息
  • 附加信息
  • wParam:输入字符的ASCII字符编码码值
  • lParam:按键的相关参数

这里我给出一段伪代码,帮助大家理解GetMessage函数抓到字符消息后,TranslateMessage函数翻译此消息的过程:

TranslateMessage(&Msg){
  if(Msg.message != WM_KEYDOWN){
    return ;
  }else{
  根据Msg.wParam(键码值)可以获知哪个按键被按下
  if(不可见字符){
    return;
  }
  查看Capslock键是否处于打开状态
  if(打开){
    PostMessage(Msg.hwnd,WM_CHAR,......);
  }else{
    PostMessage(Msg.hwnd,WM_CHAR,......);
  }
}


我们来到回调函数中来看看键盘消息:

LRESULT CALLBACK WindowProc(
  IN  HWND hwnd,
  IN  UINT uMsg,
  IN  WPARAM wParam,
  IN  LPARAM lParam
)
{
  char output[256] = { 0 };
  switch (uMsg)
  {
  //常见消息
  case WM_QUIT: {
    MessageBox(hwnd, "确定退出程序吗?", "退出", MB_YESNO);
    break;
  }
  case WM_DESTROY: {
    sprintf(output, TEXT("窗口即将被销毁,将向消息队列中发送WM_QUIT消息"));
    WriteConsole(g_hOUTPUT,output,strlen(output), 0, 0);
    PostMessage(NULL, WM_QUIT, 0, 0);
    break;
    }
  case WM_SYSCOMMAND: {
      sprintf(output, TEXT("检测到WM_COMMAND消息,将弹出提示窗口\n"));
      WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
      MessageBox(hwnd, "记住我!!!", "别忘了", MB_YESNO);
    break;
  }
  case WM_CREATE: {
    sprintf(output, TEXT("检测到WM_CREATE消息,将创建窗口。\n"));
    WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
    break;
  }
  case WM_SIZE: {
    sprintf(output, "lParam:窗口宽变化为:%d,窗口高变化为:%d \n", HIWORD(lParam), LOWORD(lParam));
    WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
    break;
  }
  //键盘消息
  case WM_KEYDOWN: {
    sprintf(output, "检测到WM_KEYDOWN消息,键码值:%d.\n", wParam);
    WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
    break;
  }
  case WM_KEYUP: {
    sprintf(output, "检测到WM_KEYUP消息,键码值:%d.该按键被放开\n", wParam);
    WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
    break;
  }
  }
  return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

我们来看看效果:

我们不难发现,每个键位都有一个专属的键码值,而且我们发现,大写和小写的键码值一样,是通过TranslateMessage函数来检测CapsLock是否打开区分大小写的。



相关文章
|
Shell 开发者 Windows
windows 10中将任意程序添加进鼠标右键菜单里面
windows 10中将任意程序添加进鼠标右键菜单的详细步骤
223 0
windows 10中将任意程序添加进鼠标右键菜单里面
|
6月前
|
人工智能 机器人 测试技术
【windows批处理batch】.bat文件循环判断语句
【windows批处理batch】.bat文件循环判断语句
|
1月前
|
Windows
Windows 11 鼠标右键可选择 cmd 命令行选项
Windows 11 鼠标右键可选择 cmd 命令行选项
42 0
windows10为何鼠标右键失灵,桌面右键一直转圈的解决
windows10为何鼠标右键失灵,桌面右键一直转圈的解决
1094 0
|
Windows
【windows批处理batch】.bat文件循环判断语句
【windows批处理batch】.bat文件循环判断语句
440 0
|
消息中间件 Windows
Windows消息,消息循环的处理,消息队列,键盘消息,鼠标消息,定时器消息(四)
Windows消息,消息循环的处理,消息队列,键盘消息,鼠标消息,定时器消息
|
4月前
|
消息中间件 C语言 RocketMQ
消息队列 MQ操作报错合集之出现"Connection reset by peer"的错误,该如何处理
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
4月前
|
消息中间件 Java C语言
消息队列 MQ使用问题之在使用C++客户端和GBase的ESQL进行编译时出现core dump,该怎么办
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
18天前
|
消息中间件 存储 Kafka
MQ 消息队列核心原理,12 条最全面总结!
本文总结了消息队列的12个核心原理,涵盖消息顺序性、ACK机制、持久化及高可用性等内容。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
2月前
|
消息中间件
手撸MQ消息队列——循环数组
队列是一种常用的数据结构,类似于栈,但采用先进先出(FIFO)的原则。生活中常见的排队场景就是队列的应用实例。在数据结构中,队列通常用数组实现,包括入队(队尾插入元素)和出队(队头移除元素)两种基本操作。本文介绍了如何用数组实现队列,包括定义数组长度、维护队头和队尾下标(front 和 tail),并通过取模运算解决下标越界问题。此外,还讨论了队列的空与满状态判断,以及并发和等待机制的实现。通过示例代码展示了队列的基本操作及优化方法,确保多线程环境下的正确性和高效性。
37 0
手撸MQ消息队列——循环数组