这次,我们将要学习WINDOWS程序是如何处理键盘消息的。

理论:

因为大多数的PC只有一个键盘,所以所有运行中的WINDOWS程序必须共用它。WINDOWS 将负责把击键消息送到具有输入焦点的那个应用程序中去。尽管屏幕上可能同时有几个应用程序窗口,但一个时刻仅有一个窗口有输入焦点。有输入焦点的那个应用程序的标题条总是高亮度显示的。 实际上您可以从两个角度来看键盘消息:一是您可以把它看成是一大堆的按键消息的集合,在这种情况下,当您按下一个键时,WINDOWS就会发送一个 WM_KEYDOWN 给有输入焦点的那个应用程序,提醒它有一个键被按下。当您释放键时,WINDOWS又会发送一个 WM_KYEUP 消息,告诉有一个键被释放。您把每一个键当成是一个按钮;另一种情况是:您可以把键盘看成是字符输入设备。当您按下“a”键时,WINDOWS发送一个 WM_CHAR 消息给有输入焦点的应用程序,告诉它“a”键被按下。实际上WINDOWS 内部发送 WM_KEYDOWNWM_KEYUP 消息给有输入焦点的应用程序,而这些消息将通过调用 TranslateMessage 翻译成 WM_CHAR 消息。WINDOWS窗口过程函数将决定是否处理所收到的消息,一般说来您不大会去处理 WM_KEYDOWNWM_KEYUP 消息,在消息循环中 TranslateMessage 函数会把上述消息转换成 WM_CHAR 消息。这次学习中将只处理 WM_CHAR

例子:

.386
.model flat,stdcall
option casemap:noneWinMain proto :DWORD,:DWORD,:DWORD,:DWORDinclude windows.inc
include user32.inc
include kernel32.inc
include gdi32.inc
includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib.data
ClassName db "SimpleWinClass",0
AppName   db "Our Fourth Window",0
char WPARAM 20h.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?.code
start:
invoke GetModuleHandle,NULL
mov    hInstance,eax
invoke GetCommandLine
mov    CommandLine,eax
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eaxWinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORDLOCAL wc:WNDCLASSEXLOCAL msg:MSGLOCAL hwnd:HWNDmov wc.cbSize,SIZEOF WNDCLASSEXmov wc.style,CS_HREDRAW or CS_VREDRAWmov wc.lpfnWndProc,OFFSET WndProcmov wc.cbClsExtra,NULLmov wc.cbWndExtra,NULLpush hInstpop wc.hInstancemov wc.hbrBackground,COLOR_WINDOW+1mov wc.lpszMenuName,NULLmov wc.lpszClassName,OFFSET ClassNameinvoke LoadIcon,NULL,IDI_APPLICATIONmov wc.hIcon,eaxmov wc.hIconSm,eaxinvoke LoadCursor,NULL,IDC_ARROWmov wc.hCursor,eaxinvoke RegisterClassEx,ADDR wcinvoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,\CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInst,NULLmov hwnd,eaxinvoke ShowWindow,hwnd,SW_SHOWNORMALinvoke UpdateWindow,hwnd.while TRUEinvoke GetMessage,ADDR msg,NULL,0,0.break .if (!eax)invoke TranslateMessage,ADDR msginvoke DispatchMessage,ADDR msg.endwmov eax,msg.wParamretWinMain endp WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAMLOCAL hdc:HDCLOCAL ps:PAINTSTRUCT.if uMsg==WM_DESTROYinvoke PostQuitMessage,NULL.elseif uMsg==WM_CHARpush wParampop  charinvoke InvalidateRect,hWnd,NULL,TRUE.elseif uMsg==WM_PAINTinvoke BeginPaint,hWnd,ADDR psmov    hdc,eaxinvoke TextOut,hdc,0,0,ADDR char,1invoke EndPaint,hWnd,ADDR ps.elseinvoke DefWindowProc,hWnd,uMsg,wParam,lParamret.endifxor eax,eaxretWndProc endp
end start

分析:

char WPARAM 20h

这个变量将保存从键盘接收到的字符。因为它是在窗口过程中通过WPARAM型变量传送的,所以我们简单地把它定义为WPARAM型。由于我们的窗口在初次刷新时(也即刚被创建的那一次)是没有键盘输入的所以我们把他设成空格符(20h),这样显示时您就什么都看不见。

.ELSEIF uMsg==WM_CHAR push wParam pop  char invoke InvalidateRect, hWnd,NULL,TRUE 

这一段是用来处理WM_CHAR消息的。它把接收到的字符放入变量char中,接着调用InvalidateRect,而InvalidateRect使得窗口的客户区无效,这样它会发出WM_PAINT消息,而WM_PAINT消息迫使WINDOWS重新绘制它的客户区。该函数的语法如下:

InvalidateRect proto hWnd:HWND, lpRect:DWORD, bErase:DWORD 

lpRect是指向客户区我们想要其无效的一个正方形结构体的指针。如果该值等于NULL,则整个客户区都无效;布尔值bErase告诉WINDOWS是否擦除背景,如果是TRUE,则WINDOWS在调用BeginPaint函数时把背景擦掉。 所以我们此处的做法是:我们将保存所有有关重绘客户区的数据,然后发送WM_PAINT消息(通过InvalidateRect),处理该消息的程序段然后根据相关数据重新绘制客户区。实际上我们完全可以通过调用 GetDC 获得设备上下文句柄,然后绘制字符,然后再调用ReleaseDC释放设备上下文句柄,毫无疑问这样也能在客户区绘制出正确的字符。但是如果这之后接收到WM_PAINT消息要处理时,客户区会重新刷新,而我们这稍前所绘制的字符就会消失掉。所以为了让字符一直正确地显示,就必须把它们放到WM_PAINT的处理过程中处理。而在本消息处理中发送WM_PAINT消息即可。

invoke TextOut,hdc,0,0,ADDR char,1 

在调用InvalidateRect时,WM_PAINT消息被发送到了WINDOWS窗口处理过程,程序流程转移到处理WM_PAINT消息的程序段,然后调用BeginPaint得到设备上下文的句柄,再调用TextOut在客户区的(0,0)处输出保存的按键字符。这样无论您按什么键都能在客户区的左上角显示,不仅如此,无论您怎么缩放窗口(迫使WINDOWS重新绘制它的客户区),字符都会在正确的地方显示,所以必须把所有重要的绘制动作都放到处理WM_PAINT消息的程序段中去

转载于:https://www.cnblogs.com/Akkuman/p/8433816.html

Win32汇编学习(6):键盘输入消息相关推荐

  1. Win32汇编学习——windows汇编语法(小甲鱼教程)

    Win32汇编学习--windows汇编语法(小甲鱼教程) 1)指令集 .386 语句是汇编语句的伪指令,类似指令有:.8086 . .186  ..286  ..386/.386p  . .486/ ...

  2. 【无标题】汇编实现从键盘输入并输出

    汇编实现从键盘输入一个带符号字节数据(如-56)存入内存,并将结果在显示器上以十进制形式显示输出. data segmentx db '-' ;x存放'-',后面用于判断sfn db 0 ;标识,用于 ...

  3. Win32汇编学习(7):鼠标输入消息

    这次我们将学习如何在我们的窗口过程函数中处理鼠标按键消息.例子演示了如何等待鼠标左键按下消息,我们将在按下的位置显示一个字符串. 理论: 和处理键盘输入一样,WINDOWS将捕捉鼠标动作并把它们发送到 ...

  4. Win32汇编学习笔记之基础篇

    基础篇 第一章 背景知识 1.1 Win32的软硬件平台 1.1.1    80x86系列处理器简史 Win32可以在多种硬件平台上运行,但使用最广泛的硬件平台是基于Intel公司80x86系列处理器 ...

  5. WinAPI键盘输入消息

    WM_KEYDOWN 按下按键消息 WM_KEYUP       松开按键消息 WM_CHAR         字符消息 "系统键"通常是[ALT]与其他按键的组合 WM_SYSK ...

  6. c语言学习-从键盘输入10个字符,按照字典顺序将其排序输出(二维字符数组)

    从键盘输入10个字符,按照字典顺序将其排序输出(二维字符数组) 程序流程图: 代码: #include<stdio.h> void main() {int b[10]; int a[5][ ...

  7. c语言学习-从键盘输入三个数,按照从小到大(或从大到小)的顺序输出

    从键盘输入三个数,按照从小到大(或从大到小)的顺序输出 程序流程图: 代码: #include<stdio.h> void main() {float a,b,c,d; printf(&q ...

  8. Win32汇编学习——windows基础知识(小甲鱼教程)

    <Win32汇编语言程序设计>(小甲鱼) 1)windows特权保护机制 1)80386的中断和异常 2)80386的保护机制 3)Windows的保护机制 2)80x86处理器的工作模式 ...

  9. [Win32]Win32 SDK编程系列文章——键盘输入消息

    理论 因为大多数的PC只有一个键盘,所以所有运行中的WINDOWS程序必须共用它.WINDOWS 将负责把击键消息送到具有输入焦点的那个应用程序中去.尽管屏幕上可能同时有几个应用程序窗口,但一个时刻仅 ...

  10. Win32汇编学习(10):对话框(1)

    现在我们开始学习一些有关GUI编程的有趣的部分:以对话框为主要界面的应用程序. 理论: 如果您仔细关注过前一个程序就会发现:您无法按TAB键从一个子窗口控件跳到另一个子窗口控件,要想转移的话只有 用鼠 ...

最新文章

  1. sql server 2014预览版发布
  2. python自学入门教程-Python学习教程(一)自学资源分享
  3. C#访问MySQL数据库的方法
  4. lucky前面加a还是an_微信昵称前加个“A” 不是微商就是销售?看看这个“A”的含义!...
  5. VBS的疑惑,它们不考虑效率吗?
  6. attr()与setAttribute()的区别
  7. 注重代码效率_如何提升质量:注重态度
  8. [Usaco2015 dec]Breed Counting
  9. java.lang.UnsatisfiedLinkError: D:\Tomcat\apache-tomcat-7.0.67\bin\tcnative-1.dll:
  10. 为什么从事软件开发测试?
  11. Stm32 基于蓝牙的串口通信 详细篇
  12. 我的五年百度博客文章列表
  13. AnkhSVN支持vs2012~2022
  14. XWPFTemplate生成根据模板文件填充内容生成word文件
  15. vmware,qemu各种方式上网设置(转)
  16. Call to a member function validate() on null
  17. 【游戏数据库】大型网络游戏数据库设计方面讨论?(微软平台) 游戏数据库
  18. hao643.com劫持(修改快捷方式跳转至hao123.com)
  19. 利用sklearn中 ID3算法实现简单的课程销量预测+决策树可视化
  20. Gazebo仿真平台模型搭建与修改

热门文章

  1. 数据结构-02-链表数据结构之双链表和循环链表
  2. 官宣 | 千呼万唤,Apache Flink 1.11.0 正式发布啦!(内含福利)
  3. 社区活动 | Apache RocketMQ × Apache Flink Meetup · 上海站
  4. 15 张图,了解一下 TCP/IP 必知也必会的 10 个问题
  5. 10年腾讯技术专家有话对你说
  6. php增加html元素,使用php将appendChild($ element)添加到现有的html元素中
  7. word文档怎么一分为二_word文档转pdf要怎么实现?word转pdf好方法推荐
  8. 第二周函数-的基本格式:
  9. 多示例代码:go语言中循环练习题,不包括break,continue
  10. 创建dataframe_Spark原理与实战(五) Spark核心数据抽象DataFrame