通行证: 用户 密码 域名空间  下载中心 社区论坛 信息公告 MY小屋
联系我们
设为首页
加入收藏

 

QQ,ASP,PHP,JSP,XML,SQL,.Net,编程 程序 网页图象 建站经验 私服
首页 | 新闻资讯 | 编程开发 | 网页设计 | 图形图象 | 网络媒体 | 网站模板 | 数 据 库 | 投稿
论坛 | 操作系统 | 系统优化 | 网络安全 | 黑客技术 | 硬件学堂 | 硬件报价 | 服 务 器 | 地图
专题 | 应用软件 | 聊天通讯 | Q Q 专栏 | 建站经验 | 在线工具 | 站长Club | 注 册 表 | 旧版
社会 | 游戏娱乐 | 设计欣赏 | 疑难解答 | 社区论坛 | 韩国素材 | 素材图库 | 广告服务 | 服务
当前位置:首页>>编程开发>>汇编语言>>正文 新版上线![旧版]
注:打开慢时请稍等

处理键盘输入消息

http://www.iyit.net  日期:2006-5-22 12:34:11  来源:网络转载   点击:
参加讨论】处理键盘输入消息:

  在本课中,我们将要学习WINDOWS程序是如何处理键盘消息的。

理论:

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

例子:

.386
.model flat,stdcall
option casemap:none
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib

.data
ClassName db "SimpleWinClass",0
AppName db "Our First Window",0
char WPARAM 20h ; the character the program receives from keyboard

.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,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT

.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CHAR
push wParam
pop char
invoke InvalidateRect, hWnd,NULL,TRUE
.ELSEIF uMsg==WM_PAINT
invoke BeginPaint,hWnd, ADDR ps
mov hdc,eax
invoke TextOut,hdc,0,0,ADDR char,1
invoke EndPaint,hWnd, ADDR ps
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start

分析:


char WPARAM 20h ; the character the program receives from keyboard

这个变量将保存从键盘接收到的字符。因为它是在窗口过程中通过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消息,处理该消息的程序段然后根据相关数据重新绘制客户区。尽管这么做事有点像走了弓背,但WINDOWS要处理那么庞大的消息群,没有一定的规矩可不行。实际上我们完全可以通过调用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消息的程序段中去。


编辑:黑鹰 [发送给好友] [打印本页] [关闭窗口] [返回顶部]
上一篇:处理键盘输入消息
下一篇:绘制文本
转载请注明来源:www.iyit.net
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。

 相关文章
最新更新 热点排行 推荐新闻
基本概念(win32)汇编教程
win32消息框
创建简单的窗口
绘制文本
处理键盘输入消息
基本概念(win32)汇编教程
win32消息框
创建简单的窗口
绘制文本
处理键盘输入消息
处理键盘输入消息
菜单
子窗口控件
以对话框为主要界面的应用程序
进一步学习对话框
基本概念(win32)汇编教程
win32消息框
创建简单的窗口
绘制文本
处理键盘输入消息
优秀公益广告作品欣赏(8)
java数据类型转换
Windows XP专业版IIS连接数的更改
新开放QQ免费挂级网站
免费在QQ上看在线电影电视听音乐
优秀公益广告作品欣赏(7)
WEB服务器配置全攻略(三)
QQ珊瑚虫外挂4.0版本发布!
免费把QQ炫铃设为本机QQ的系统提示音
Office2007简体中文版浮出水面 美图抢
 AMD处理器AM2测试 风扇竟运行7分钟
exeplorer.exe错误的问题的总结、解决
ASP.NET 2.0 中的异步页功能应用
硬盘坏道修复及数据恢复宝典
免费登录搜索引擎入口大全
搜索引擎注册九大秘法
小心摄像头成为黑客偷窥你的眼睛
内存混插常见问题和解决方法
Office2007简体中文版浮出水面 美图抢
0689版Windows Live Messenger五大看点
 友情链接
设置首 页 - 版权声明 - 广告服务 - 关于我们 - 联系我们 - 友情连接
Copyrights © 2004-2006 iYiT.Net All Rights Reserved.
网站合作、广告联系QQ:147007642、466949678
易特网络技术 点击这里给我发消息