友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
依依小说 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

windows环境下32位汇编语言程序设计-第32部分

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!



中有定义的固定属性内容。

如果要获取字符串类型信息块中的版本信息,那就比较复杂一点了,必须首先知道语言集的名称,所以先要获取版本信息资源中变量类型信息块的内容,方法是:

invoke   VerQueryValue;addr dbVerInfo;addr szVarInfo;addr lpBuffer;addr dwLen

mov      eax;lpBuffer

mov      eax;'eax'

ror      eax;16

szVarInfo是一个字符串:“VarFileInfoTranslation”,这时函数在lpBuffer中返回语言集变量指针的指针,所以要先mov eax;lpBuffer,再用eax作指针用mov eax;'eax'得到语言集变量。语言集变量的高16位是字符集ID,低16位是语言ID,可以使用ror eax;16来调换高低位,以我们的例子为例,现在eax中的值就是080404b0h了!

接下来就可以获取字符串版本信息了,先将语言集的值通过wsprintf函数转换成“080404b0”的形式,然后拼装成“StringFileInfo080404b0字符串名称”形式的字符串;中间的“字符串名称”可以是表5。9中的12种名称之一,最后调用下面的语句(假定拼装好的字符串地址为szString):

invoke   VerQueryValue;addr dbVerInfo;addr szString;addr lpBuffer;addr dwLen

执行后lpBuffer中会得到一个指针,指向版本信息字符串定义的内容,这就是我们最后需要的东西!重复这个步骤可以得到所有12种字符串版本信息。

读者可以在所附光盘的Chapter05ShowVersionInfo目录中找到一个ShowInfo程序,它可以获取PE文件中的版本信息资源并显示出来,详细的代码请参考该目录中的文件,主文件ShowInfo。asm是界面程序,版本信息资源的代码在GetVersionInfo。inc文件中,由于篇幅有限,源程序在这里就不列出来了。



 
来源:电子工业出版社 作者:罗云彬 上一页         回书目         下一页          
上一页         回书目         下一页          
  


第5章 使用资源


5。7 二进制资源和自定义资源

    
5。7。1  使用二进制资源

在第2章中曾经提到DOS的exe文件可以带一个覆盖部分,覆盖部分实际上就是在真正的可执行部分后面附加的数据,然后由程序在运行中打开自身文件并使用这些数据。Win32的可执行文件中除了上面介绍的这些标准类型的资源外,也可以在程序中附带其他数据,当然方法完全不同——Win32资源中允许用户自己定义二进制的资源或者自定义格式的资源,资源的内容可以是任何数据,也可以将一个磁盘文件按二进制格式包括进去。

二进制资源的定义格式是:

资源ID   RCDATA 'DISCARDABLE'

BEGIN

         数据定义

         …

END

也可以用一个磁盘文件当做资源的内容:

资源ID  RCDATA 'DISCARDABLE' 文件名

在程序中要使用资源的内容时,可以通过以下步骤将资源装入内存使用:

(1)用FindResource(hInstance;lpName,lpType)查找资源。lpName的值为资源ID,lpType的值为RT_RCDATA,如果找到资源。那么函数返回一个资源信息句柄。

(2)用LoadResource(hInstance; hResInfo)装入资源。hResInfo是上一步中得到的资源信息句柄,装入成功的话函数会返回一个资源句柄。

(3)用LckResource(hResData)将资源锁定到内存中。hResData是上一步得到的资源句柄,函数返回资源装入的内存地址,程序就可以使用内存中的数据了。

(4)如果想知道装入资源的大小是多少,可以使用FindResource返回的hResInfo来调用SizeofResource(hInstance;hResInfo)从而得到资源大小。

下面是一个装入资源ID为ID_MYRES的RCDATA类型资源的例子:

invoke   FindResource;hInstance;ID_MYRES;RT_RCDATA   ;寻找资源

。if      eax

        mov     hResInfo;eax

        invoke  SizeofResource;hInstance;eax            ;获取资源尺寸

         mov     dwResSize;eax

        invoke  LoadResource;hInstance;hResInfo     ;装入资源

        。if     eax

                 invoke  LockResource;eax                ;锁定资源

                 。if     eax

                         mov     lpRes;eax

                         ;处理lpRes指向的资源内容

                 。endif

         。endif

。endif

5。7。2  使用自定义资源

自定义资源的定义格式比二进制资源更灵活,它和二进制资源的区别在于可以指定资源类别为自定义的名称:

资源ID       类型ID 'DISCARDABLE'

BEGIN

     数据定义

    …

END

或用一个磁盘文件当做资源的内容:

资源ID  类型ID 'DISCARDABLE' 文件名

类型ID可以是大于255的数值(255及以下的数值由Windows使用)或字符串,如可以定义如下:

1000     WAVE        〃Hello。wav〃     ;定义类型为“WAVE”,资源ID为1000的资源

1000     TEXT        〃Readme。txt〃        ;定义类型为“TEXT”,资源ID为1000的资源

1000     1000        〃Test。bin〃      ;定义类型ID为1000,资源ID为1000的资源

在程序中使用自定义资源的方法和使用二进制资源类似,惟一的区别是使用FindResource得到hResInfo的参数有些区别,得到hResInfo以后的步骤是一模一样的。针对上面3句定义,查找资源的方法可以是:

szResType1       db      〃WAVE〃;0

szResType2       db      〃TEXT〃;0

                 。。。

invoke   FindResource;hInstance;1000;addr szResType1 ;针对上面第一句

invoke   FindResource;hInstance;1000;addr szResType2 ;针对上面第二句

invoke   FindResource;hInstance;1000;1000                ;针对上面第三句

在使用完二进制或自定义资源以后,不必使用任何函数去释放它们,Windows在程序退出的时候会自动将它们释放。



 
来源:电子工业出版社 作者:罗云彬 上一页         回书目         下一页          
上一页         回书目         下一页          
  


第6章 定时器


6。1 定时器简介/6。2 定时器的使用(1)

    
在应用程序需要使用定时器时,可以用SetTimer函数向Windows申请一个定时器,要求系统在指定的时间以后“通知”应用程序,如果申请成功的话,系统会以指定的时间周期调用SetTimer函数指定的回调函数,或者向指定的窗口过程发送WM_TIMER消息,和DOS操作系统固定以55 ms的间隔触发中断服务程序相比,SetTimer函数可以指定的时间间隔更为灵活——以ms为单位,可以指定的时间周期为一个32位的整数,也就是从1~4 294 967 295 ms,这可是一个将近50天的范围!

但是在具体的使用中不要被这个参数所迷惑:由于Windows的定时器同样是基于时钟中断的,所以虽然参数的单位是ms,但精度还是55 ms,如果指定一个小于55 ms的周期,不管是1 ms还是54 ms,Windows最快也只能在每个时钟中断的时候触发这个定时器,也就是说,实际上这个定时器是以55 ms为触发周期的;另外,当指定一个时间间隔的时候,Windows以和这个间隔最接近的55 ms的整数倍时间来触发定时器,假定建立一个周期为1 000 ms的定时器,定时器的触发周期实际上不是1 s而是989 ms(55 ms×18)。

使用定时器时还有一个要点就是定时器消息是一个低级别的消息,这表现在两个方面:首先就是Windows只有在消息队列中没有其他消息的情况下才会发送WM_TIMER消息,如果窗口过程忙于处理某个消息没有返回,使消息队列中有消息积累起来,那么WM_TIMER消息就会被丢弃,在消息队列再度空闲的时候,被丢弃的WM_TIMER消息不会被补发(用一句经典的话来描述就是:“过去的就让它过去吧!”);其次,消息队列中不会有多条WM_TIMER消息,如果消息队列中已经有一条WM_TIMER消息,还没来得及处理,又到了定时的时刻,那么两条WM_TIMER消息会被合并成一条。

 
 
所以,应用程序不能依靠定时器来保证某件事情必须在规定的时刻被处理,另外,也不能依赖对定时器消息计数来确定已经过去了多少时间。

读者可以在所附光盘的Chapter06Timer目录中找到一个例子,运行Timer。exe以后出现的界面如图6。1所示。

这个例子程序中共定义了3个定时器,第1个以250 ms为周期更换对话框上的图标;第2个以1s为单位进行计数并把结果显示在对话框上;第3个以2s为单位驱动扬声器发出“嘟嘟”的响声。为了验证WM_TIMER消息的级别,读者可以在运行中按住标题栏的“关闭”按钮不放,就可以发现3个定时器全部停止了,然后将鼠标移出“关闭”按钮并释放,定时器会重新工作,但对话框上的计数结果在定时器停止的期间并没有补上去,也就是说,在这期间,WM_TIMER消息被全部丢弃了。

6。2  定时器的使用

下面以Timer程序为例说明定时器的使用方法,这个程序的资源脚本文件定义如下:

#include        

#define DLG_MAIN            1

#define ICO_1           1

#define ICO_2           2

#define IDC_SETICON     100

#define IDC_COUNT       101

//》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

ICO_1   ICON        〃1。ico〃

ICO_2   ICON        〃2。ico〃

//》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

DLG_MAIN DIALOG 50; 50; 113; 40

STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU

CAPTION 〃定时器例子〃

FONT 9; 〃宋体〃



 ICON ICO_1; IDC_SETICON; 8; 9; 18; 21

 LTEXT 〃计数:〃; …1; 35; 16; 25; 10

 LTEXT 〃〃; IDC_COUNT; 62; 16; 40; 10



对资源的定义读者现在一定不会陌生了,这个文件中定义了两个图标和一个对话框,对话框中定义了一个图标框和两个文本框,其中的一个文本框中的文字为空,这是以后显示每秒一次的计数值用的。

Timer。asm源程序如下:

                。386

                。model flat;stdcall

                option casemap:none

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

; Include 文件定义

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

include         windows。inc

include         user32。inc

includelib      user32。lib

include         kernel32。inc

includelib      kernel32。lib

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

ID_TIMER1       equ     1

ID_TIMER2       equ     2

ICO_1           equ     1

ICO_2           equ     2

DLG_MAIN            equ     1

IDC_SETICON     equ     100

IDC_COUNT       equ     101

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

; 数据段

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

                    。data?

hInstance       dd      ?

hWinMain            dd      ?

dwCount         dd      ?

idTimer         dd      ?

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

; 代码段

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

                de

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

; 定时器过程

;》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

_ProcTimer      proc        _hWnd;uMsg;_idEvent;_dwTime

 

                    pu
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!