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

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

其实,在第一期创建了对话框窗口之后,这个消息泵就已经可以登场了,原因是这样的:大家尝试下在窗口显示之后打打字,看看字符是不是全部输入到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

http://www.jsqmd.com/news/1170195/

相关文章:

  • AI智能体驱动的求职申请自动化工作流:技术原理与工程实践
  • 【仅限前500名】Cursor AI深色模式强制同步方案:跨设备/跨OS/跨编辑器统一暗色策略(含VS Code双模同步脚本)
  • TB67H480FNG与PIC18F86J50电机控制方案解析
  • 亲身到店探访深圳江诗丹顿官方售后服务中心|网点地址与官方热线(2026年7月最新) - 江诗丹顿官方服务中心
  • mba论文开题报告的研究内容怎么写
  • 2026年重庆老牌牙齿矫正医疗机构:经验与技术优势深度剖析
  • DeepSeek数学推理能力跃迁指南(从符号推演到定理生成的7层认知升级)
  • SPI、I2C、UART 3大嵌入式总线深度对比:从速率、引脚到抗干扰的10项关键指标
  • 3分钟搞定!Blender 3MF格式插件:3D打印工作流终极解决方案
  • VSCode Remote-WSL 1.89 配置:3步连接Ubuntu 22.04,解决WSL2 0x800701bc报错
  • 科技巨头温室气体排放量上升,微软投资或致排放进一步增加!
  • 技术发布信号监测与工程准备:开发者应对AI模型更新策略
  • 如何在五分钟内掌握网盘直链下载助手:开源项目的完整使用指南
  • 2026年7月四氟波纹管、铁氟龙管、四氟金属软管优质源头厂家推荐报告 - 新闻快传
  • 【新手入门】 OpenClaw 自动化程序安装与功能调试教程(含安装包)
  • 瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
  • STM32 智能输液系统 3 大模块硬件选型对比:步进电机驱动 vs 蠕动泵 vs 电磁阀
  • Codex本地编程代理框架:国产大模型接入与定制化部署指南
  • 2026 广州搬家避坑干货|全市主流搬家品牌实测打分,资质价格售后全解析,教你一站式选出靠谱服务商 - gzdjxd
  • TB6593FNG与PIC18F86K90的直流电机驱动方案
  • 24位ΔΣ ADC与MCU构建高精度信号采集系统
  • ThinkPad风扇控制终极指南:如何彻底解决散热与噪音问题
  • Citra模拟器:在PC上体验任天堂3DS游戏的完整解决方案
  • 湖南优质护理专业优选:衡阳科技职业学院王牌护理专业全解析 - 新闻快传
  • openEuler/imageTailor常见问题解答:从制作失败到镜像优化的解决方案
  • mba人力资源论文开题报告
  • Gemini 3.5 Flash与Antigravity harness:AI智能体如何变革天文数据分析
  • 百度智能云AI零售解决方案:从数据中台到精准营销的技术实践
  • 手把手编写儿童手机远程监控App之vue3使用高德地图2
  • Unity高性能动画系统实战:Playable API与Animation Job优化指南