友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
windows环境下32位汇编语言程序设计-第16部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
essage最后收到的是0012号WM_QUIT消息,消息循环结束。
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第4章 第一个窗口程序
4。4 实 验(3)
实验2。 全部消息都经过消息循环吗
在做这个实验之前,读者已经知道并不是所有的消息都是经过消息循环的,它们中的有些是Windows直接发送到窗口过程的,上一个实验中就已经可以看到GetMessage返回的次数明显地比调用窗口过程的次数少,这意味着窗口过程有很多次是由Windows直接调用的。
这次,我们用极端的方式来验证,先把消息循环中的DispatchMessage去掉,这样GetMessage得到的消息将不会再被送到窗口过程了,窗口过程收到的就是由Windows直接调用的了。改变后的源代码见所附光盘中的Chapter04MsgWindow02目录。
编译后,同样先打开记事本,再执行MsgWindow,然后将鼠标移过MsgWindow窗口,并尝试着单击“关闭”按钮和双击等各种动作;结果是窗口过程还是在被调用:
WndProc: '0084'WM_NCHITTEST 00000000 007e0088
WndProc: '0020'WM_SETCURSOR 0026030c 02000001
WndProc: '0084'WM_NCHITTEST 00000000 006c0070
WndProc: '0020'WM_SETCURSOR 0026030c 02000001
…
由于没有了DispatchMessage,大部分消息被忽略了,窗口就停在了屏幕上,不能进行移动、缩放或关闭等操作,但还是有一部分消息直接由Windows发送给窗口过程,它们是鼠标位置测试的WM_NCHITTEST消息和要求设置光标的WM_SETCURSOR消息,所以在鼠标移动到边框的时候,鼠标光标还是会变成双箭头的样子。
另外,尝试着单击别的窗口来切换焦点,然后再单击标题栏来重新激活窗口,可以发现WM_MOUSEACTIVATE,WM_ACTIVATE和WM_KILLFOCUS等消息也是不经过消息循环的。接下来,把一个窗口移动到MsgWindow窗口前覆盖它的位置,再移开,可以发现WM_SYNCPAINT和WM_ERASEBKGND等消息也是由Windows直接发给窗口过程的。
最后,关闭窗口,当然这个窗口只能用Ctrl+Alt+Del键在任务管理器中关闭了!
实验3。 TranslateMessage有什么用
首先执行实验1的MsgWindow,在窗口上敲几个键,每次敲一个键,得到的消息是:WM_KEYDOWN,WM_CHAR和WM_KEYUP。如果按下键盘不放,则首先得到一个WM_KEYDOWN,接下来就是重复的WM_CHAR和WM_KEYUP消息,直到放开键盘为止,最后才会看到一个WM_KEYUP。显示如下:
WndProc: '0100'WM_KEYDOWN 00000041 001e0001
WndProc: '0102'WM_CHAR 00000061 001e0001
WndProc: '0101'WM_KEYUP 00000041 c01e0001
在WM_KEYDOWN和WM_KEYUP消息中,wParam中是按键的扫描码,上面的数据是按下了键“A”得到的,00000041h是“A”的扫描码,到了WM_CHAR消息中,wParam中就是已经转换过的ASCII码61了,代表输入的是小写的字母“a”。
好!现在从程序中去掉TranslateMessage语句(修改以后的源代码放在Chapter04MsgWindow03目录中),然后看这个程序的运行结果,同样,按几次键以及按下键盘不放,我们发现:这中间的区别就是少了WM_CHAR,所以只有在处理键盘输入要用到转换后的ASCII码的时候,TranslateMessage函数才是有用的,在别的时候完全可以省略这个语句。这个函数的功能就是看到WM_KEYDOWN的时候把消息检查一下,然后根据键值将一条新的WM_CHAR或WM_SYSCHAR消息放入消息循环中。
实验4。 DefWindowProc做了什么工作
现在把DefWindowProc语句去掉(源代码详见Chapter04MsgWindow04目录),然后再以同样的方法运行,窗口根本就没有出现!看记事本中出现了什么:
Creating Window。。。
WndProc: '0024'WM_GETMINMAXINFO 00000000 0012fda4
WndProc: '0081'WM_NCCREATE 00000000 0012fd8c
WndProc: '0082'WM_NCDESTROY 00000000 00000000
CreateWindow end
Showing Window。。。
ShowWindow end
Updating Window。。。
UpdateWindow end
Getting Message。。。
原来在建立窗口的时候执行到WM_NCCREATE消息后窗口就摧毁掉了,看WM_NCCREATE的说明:The DefWindowProc function returns TRUE,原来需要返回1来表示执行成功,所以需要处理WM_NCCREATE并返回1,现在在窗口过程中加上下列分支:
。elseif eax WM_NCCREATE
mov eax;1
ret
接着编译后执行,怎么编译不成功了?不能写exe文件?原来上次的程序还停留在消息循环中没有退出来,让我们在任务管理器中将它终止再编译,成功了!
好!现在继续执行,窗口成功建立了,但似乎陷入了死循环,因为记事本上不停地有消息冒出来,而且只是冒出WM_PAINT消息来,为什么呢?原来WM_PAINT消息是不能不处理的,也不能丢弃,只要Windows认为窗口的客户区需要绘画(或者说是无效的),它就会不停地向窗口发送WM_PAINT消息,一般WM_PAINT消息的处理中用BeginPaint和EndPaint会隐含地让客户区有效,如果不用BeginPaint/EndPaint,程序必须显式地把客户区设置为有效,Windows才不会再发送WM_PAINT消息。这个函数是ValidateRect,现在在分支中再加上处理WM_PAINT的代码:
。elseif eax WM_PAINT
invoke ValidateRect;hWnd;NULL
再编译执行,现在程序可以正常执行下去了,记事本上出现的信息也显示程序停留在了GetMessage处,一切正常。但是,窗口在哪里呢,屏幕上什么都没有,隐身了?把鼠标移到窗口原来应该出现的地方,记事本中熟悉的WM_NCHITTEST和WM_SETCURSOR消息出现了,原来窗口还在那里,只不过没有了DefWindowProc的处理,窗口的绘画等所有工作都没有做,窗口的边框与客户区等所有东西连画都没有画上去,所以窗口是存在的,但我们看不到它!
是不是再加上WM_NCPAINT消息自己画边框呢,这就不是这个实验的内容了。我们已经知道,DefWindowProc做的工作太多了,缺了它我们要补上的代码可不是一两个分支的问题,而是上百个分支了!在这个实验中,我们根本不可能把它补全。
来源:电子工业出版社 作者:罗云彬 上一页 回书目 下一页
上一页 回书目 下一页
第5章 使用资源
5。1 菜单和加速键(1)
5。1。1 菜单和加速键的组成
如图5。1所示,在窗口中菜单位于标题栏下面,这个菜单称为“主菜单”或“顶层菜单”,菜单中的菜单项有“文件”、“查看”和“帮助”;单击主菜单上的项目后,可以弹出下一层菜单,叫做“弹出式菜单”或“子菜单”,子菜单中可以继续包含下一层子菜单,如单击“查看”弹出一个子菜单后,再单击其中的“工具栏”可以继续弹出一个子菜单,在子菜单中可以继续弹出下一层子菜单的菜单项最右边用一个三角箭头来表示。
有的程序在窗口的客户区单击鼠标右键也可以弹出一个菜单,单击标题栏图标也可以弹出一个系统菜单,这些菜单都属于弹出式菜单。
菜单中的菜单项有好几种,从资源定义的角度来看,分隔用的横线也是一个菜单项,除横线外其他菜单项可以供用户选择,也可以设置为“禁止”或“灰化”状态暂时停用,如图5。1中“被禁用的菜单项”和“被灰化的菜单项”所示。“禁用”的菜单项看上去和普通菜单项相同,但无法在上面单击鼠标,“灰化”的菜单项从外观上就已经表示是不可用的。菜单项也可以在左边显示选中标记,如图5。1中的“大图标”前的圆点和“状态栏”前的对钩,圆点表示选中标记是互斥的,对钩表示是不互斥的。
图5。1 菜单示意图
加速键就是菜单项的快捷键,如图5。1中的“字体”菜单项右边有个说明,表示当窗口是激活的时候,不必打开菜单,直接按“Alt”加“F”的组合键就相当于选择了“字体”菜单项,同样,直接按下“Ctrl”加“Alt”加“B”键等于选择了“背景色”菜单项,加速键也是资源的组成部分,一般将最常用的菜单项定义为加速键,以减少打开菜单的操作。加速键的定义要遵循惯例,如“Ctrl+C”和“Ctrl+V”一般定义为“拷贝”和“粘贴”,“Ctrl+X”定义为“剪切”等。当然加速键的定义并不是必需的,不定义加速键并不会影响程序的功能。
不管程序中是否定义加速键,Windows总是定义了几个默认的加速键,如“F10”键会打开窗口的主菜单,“Alt+空格”会打开系统菜单,“Alt+F4”等于单击了“关闭”按钮等。
5。1。2 菜单和加速键的资源定义
先来看一个用于演示菜单和加速键使用的例子程序,所有的源文件包含在所附光盘的Chapter05Menu目录下面,运行后产生如图5。1所示的菜单,目录中包括资源脚本文件Menu。rc,汇编源文件Menu。asm,makefile文件和图标、光标等文件,这里是资源脚本文件Menu。rc:
#include
#define ICO_MAIN Ox1000 //图标
#define IDM_MAIN Ox2000 //菜单
#define IDA_MAIN Ox2000 //加速键
#define IDM_OPEN Ox4101
#define IDM_OPTION Ox4102
#define IDM_EXIT Ox4103
#define IDM_SETFONT Ox4201
#define IDM_SETCOLOR Ox4202
#define IDM_INACT Ox4203
#define IDM_GRAY Ox4204
#define IDM_BIG Ox4205
#define IDM_SMALL Ox4206
#define IDM_LIST Ox4207
#define IDM_DETAIL Ox4208
#define IDM_TOOLBAR Ox4209
#define IDM_TOOLBARTEXT Ox4210
#define IDM_INPUTBAR Ox4211
#define IDM_STATUSBAR Ox4212
#define IDM_HELP Ox4301
#define IDM_ABOUT Ox4302
//》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
ICO_MAIN ICON 〃Main。ico〃
//》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
IDM_MAIN menu discardable
BEGIN
popup 〃文件(&F)〃
BEGIN
menuitem 〃打开文件(&O)。。。〃;IDM_OPEN
menuitem 〃关闭文件(&C)。。。〃;IDM_OPTION
menuitem separator
menuitem 〃退出(&X)〃;IDM_EXIT
END
popup 〃查看(&V)〃
BEGIN
menuitem 〃字体(&F)。。。tAlt+F〃;IDM_SETFONT
menuitem 〃背景色(&B)。。。tCtrl+Alt+B〃;IDM_SETCOLOR
menuitem separator
menuitem 〃被禁用的菜单项〃;IDM_INACT;INACTIVE
menuitem 〃被灰化的菜单项〃;IDM_GRAY;GRAYED
menuitem separator
menuitem 〃大图标(&G)〃;IDM_BIG
menuitem 〃小图标(&M)〃;IDM_SMALL
menuitem 〃列表(&L)〃;IDM_LIST
menuitem 〃详细资料(&D)〃;IDM_DETAIL
menuitem separator
popup 〃工具栏(&T)〃
BEGIN
menuitem 〃标准按钮(&S)〃;IDM_TOOLBAR
menuitem 〃文字标签(&C)〃;IDM_TOOLBARTEXT
menuitem 〃命令栏(&I)〃;IDM_INPUTBAR
END
menuitem 〃状态栏(&U)〃;IDM_STATUSBAR
END
Popup 〃帮助(&H)〃 ;HELP
BEGIN
menuitem 〃帮助主题(&H)tF1〃;IDM_HELP
menuitem separator
menuitem 〃关于本程序(&A)。。。〃;IDM_ABOUT
END
END
//》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
IDA_MAIN accelerators
BEGIN
VK_F1; IDM_HELP; VIRTKEY
〃B〃; IDM_SETCOLOR; VIRTKEY;CONTROL;ALT
〃F〃; IDM_SETFONT; VIRTKEY;ALT
END
//》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
来源:电子工业出版社 作者:罗云彬 上一页
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!