尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

使用消息泵让个人窗口项目捕获键盘输入

使用消息泵让个人窗口项目捕获键盘输入
📅 发布时间:2026/7/11 22:55:55

其实,在第一期创建了对话框窗口之后,这个消息泵就已经可以登场了,原因是这样的:大家尝试下在窗口显示之后打打字,看看字符是不是全部输入到Excel表格当中了,这个现象已经说明了我们的对话框是接收不到键盘输入的。

窗口无法接收键盘输入

这个问题会在后续窗口完善中愈发严重,不管是创建出来用于搜索的编辑框,还是虚拟列表的标头筛选框,都无法输入任何一个字符。

所以,我们本期来一个防患于未然。


VBA消息泵的完整应用

要想让我们的个人窗口能够接收到键盘输入,就必须要用到本期的消息泵。其实,如果你有在百度上搜索关于VBA消息泵的使用案例,那你肯定会发现,这类的文章少的可怜,甚至都找不到......

但没关系,晚间现在就能给你完整使用教学!

1. 必要的API函数和结构声明

#If VBA7 And Win64 Then Private Declare PtrSafe Sub PostQuitMessage Lib "user32" (ByVal nExitCode As Long) Private Declare PtrSafe Function GetMessageA Lib "user32" (lpMsg As MSGTYPE, ByVal hwnd As LongPtr, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long) As Long Private Declare PtrSafe Function IsDialogMessageA Lib "user32" (ByVal hDlg As LongPtr, lpMsg As MSGTYPE) As Long Private Declare PtrSafe Function TranslateMessage Lib "user32" (lpMsg As MSGTYPE) As Long Private Declare PtrSafe Function DispatchMessageA Lib "user32" (lpMsg As MSGTYPE) As LongPtr #Else Private Declare Sub PostQuitMessage Lib "user32" (ByVal nExitCode As Long) Private Declare Function GetMessageA Lib "user32" (lpMsg As MSGTYPE, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long) As Long Private Declare Function IsDialogMessageA Lib "user32" (ByVal hDlg As Long, lpMsg As MSGTYPE) As Long Private Declare Function TranslateMessage Lib "user32" (lpMsg As MSGTYPE) As Long Private Declare Function DispatchMessageA Lib "user32" (lpMsg As MSGTYPE) As Long #End If #If VBA7 And Win64 Then Private Type POINTAPI x As Long y As Long End Type Private Type MSGTYPE hwnd As LongPtr message As Long wParam As LongPtr lParam As LongPtr time As Long pt As POINTAPI End Type #Else Private Type POINTAPI x As Long y As Long End Type Private Type MSGTYPE hwnd As Long message As Long wParam As Long lParam As Long time As Long pt As POINTAPI End Type #End If

2. 阻塞式消息循环的建立代码

要知道系统消息一次性会产生很多个,像是用户在移动鼠标时会一直产生的移动消息等,它们会被各个窗口捕获并处理。因此,我们需要一个循环来持续的泵取系统消息,分发给我们的对话框窗口。

Dim Gsm As MSGTYPE, Rtu& Do While True Rtu = GetMessageA(Gsm, 0, 0, 0) If Rtu = 0 Or Rtu = -1 Then Exit Do Else If IsDialogMessageA(Ud.Dialog, Gsm) = 0 Then TranslateMessage Gsm DispatchMessageA Gsm End If End If Loop

所以,在代码的最外层,我们添加了一个循环条件永远满足的Do While语句,当代码运行到这里后就会无限的泵取消息。如果循环条件永远满足的话那什么时候结束循环呢?

接着,我们添加了一个叫做GetMessage的函数,这个函数在接收到消息之后会返回一个数值,只有当接收到WM_QUIT消息时会返回零值,当遇到错误时会返回-1(这就是结束循环的方法);当GetMessage函数返回非零值时,则将该消息转换分发来让当前窗口接收。

3. 阻塞式消息循环的终止代码

PostQuitMessage 0

在这句代码运行之后,我们的消息循环就会因为Rtu=0而结束。

4. 防止中断循环导致弹窗提示(重要)

在进入消息循环之前,你需要忽略VBA默认的中断事件,比如用户连按Esc键或是Ctrl+Break。

'先记录原来的默认值,再赋予新值 Ud.EnableCancelKey = Application.EnableCancelKey Application.EnableCancelKey = xlDisabled
'窗口关闭时恢复原来的默认值 Application.EnableCancelKey = Ud.EnableCancelKey

因为,这些操作会造成代码运行中断的弹窗提示。然而,我们的个人窗口项目又离不开子类化技术,在子类化的过程中一旦遇到代码调试的现象,必定导致程序崩溃!

代码运行中断的弹窗提示

相关阅读

https://club.excelhome.net/thread-1727175-1-1.html

https://mp.weixin.qq.com/s/wKWfdbGwon6Zqu7q-RrnTQ

相关新闻

  • mba论文开题报告的研究内容怎么写
  • 科技巨头温室气体排放量上升,微软投资或致排放进一步增加!
  • DeepSeek数学推理能力跃迁指南(从符号推演到定理生成的7层认知升级)

最新新闻

  • 虚幻5 C++调试实战指南:从环境配置到高级问题排查
  • 直流负载管理:G6D-ASI继电器与PIC24微控制器的优化方案
  • 秒懂 SDK:给新手的“软件开发工具包”指南
  • Git reset 3种模式深度对比:--hard/--mixed/--soft 对工作区与暂存区的影响
  • TCP/IP 五元组深度解析:从 Wireshark 抓包到 5 种网络安全策略实战
  • 去烟味喷雾分场景选购指南:适配衣物应急、车载常备、家居布艺、办公室需求,根源分解烟味更靠谱 - 行业洞察分析师

日新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号