友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
读书室 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

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

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


; 定时器过程

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

_ProcTimer      proc        _hWnd;uMsg;_idEvent;_dwTime

 

                    pushad

                    invoke      GetDlgItemInt;hWinMain;IDC_COUNT;NULL;FALSE

                    inc         eax

                    invoke      SetDlgItemInt;hWinMain;IDC_COUNT;eax;FALSE

                    popad

                    ret

 

_ProcTimer      endp

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

; 窗口过程

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

_ProcDlgMain        proc            uses ebx edi esi;hWnd;uMsg;wParam;lParam

 

                    mov eax;uMsg

;********************************************************************



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


第6章 定时器


6。2 定时器的使用(2)

    
                。if eax   WM_TIMER

                    mov     eax;wParam

                    。if     eax   ID_TIMER1

                            inc     dwCount

                            mov     eax;dwCount

                            and     eax;1

                            inc     eax

                            invoke  LoadIcon;hInstance;eax

                            invoke  SendDlgItemMessage;hWnd;IDC_SETICON;

                                    STM_SETIMAGE;IMAGE_ICON;eax

                    。elseif eax   ID_TIMER2

                            invoke  MessageBeep;…1

                    。endif

;********************************************************************

                。elseif eax   WM_INITDIALOG

                        push        hWnd

                        pop     hWinMain

                        invoke  SetTimer;hWnd;ID_TIMER1;250;NULL

                        invoke  SetTimer;hWnd;ID_TIMER2;2000;NULL

                        invoke  SetTimer;NULL;NULL;1000;addr _ProcTimer

                        mov     idTimer;eax

;********************************************************************

                。elseif eax   WM_CLOSE

                        invoke  KillTimer;hWnd;ID_TIMER1

                        invoke  KillTimer;hWnd;ID_TIMER2

                        invoke  KillTimer;NULL;idTimer

                        invoke  EndDialog;hWnd;NULL

;********************************************************************

                。else

                        mov     eax;FALSE

                        ret

                。endif         

                mov     eax;TRUE

                ret

 

_ProcDlgMain    endp

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

start:

                invoke  GetModuleHandle;NULL

                mov     hInstance;eax

                invoke  DialogBoxParam;hInstance;DLG_MAIN;

                        NULL;offset _ProcDlgMain;NULL

                invoke  ExitProcess;NULL

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

                end start

这个程序的基本结构非常简单,就是一个标准的对话框程序而已,在WM_INITDIALOG中用SetTimer申请了3个定时器,并在WM_CLOSE消息中用KillTimer撤销这3个定时器。

申请一个定时器使用SetTimer函数,函数的使用方法如下:

    invoke  SetTimer;hWnd;nIDEvent;uElapse;lpTimerFunc

hWnd参数是WM_TIMER消息发往的窗口句柄;nIDEvent参数是一个用户指定的任意整数,用来标识一个程序中的多个定时器;uElapse是时间周期,以ms为单位,这个参数是必须指定的;lpTimerFunc是定时器过程,在下面的内容中有详细介绍。如果定时器建立成功的话,函数的返回值是定时器的标识符。

撤销定时器的函数是KillTimer,该函数的使用方法是:

invoke  KillTimer;hWnd;uIDEvent

参数hWnd和uIDEvent就是建立定时器时使用的数值。

使用SetTimer函数的方法有两种,第一种方法是要求Windows将WM_TIMER消息发往指定的窗口过程,这时候lpTimerFunc必须为NULL,如例子中的:

    invoke  SetTimer;hWnd;ID_TIMER1;250;NULL        (例1)

    invoke  SetTimer;hWnd;ID_TIMER2;2000;NULL

这两个句子设置了两个标识分别为ID_TIMER1和ID_TIMER2的定时器,定时周期分别为250 ms和2 s。在窗口过程收到WM_TIMER消息的时候,wParam中是用SetTimer建立定时器时使用的标识uIDEvent,所以程序可以建立一个分支,通过判断wParam来处理不同的定时器引起的WM_TIMER消息。在例子中,当wParam是ID_TIMER1的时候更换图标框中的图标,是ID_TIMER2的时候用MessageBeep函数来发出一声“嘟”的声音。如果要撤销用这种方法建立的定时器,那么只需要用建立时的hWnd和uIDEvent参数简单地调用KillTimer就可以了。

还有一种使用定时器的方法,那就是要求Windows在时间到的时候调用指定的定时器过程,而不是某个窗口过程,那么只需要指定lpTimerFunc参数,如例子中的:

invoke  SetTimer;NULL;NULL;1000;addr _ProcTimer     (例2)

这句语句要求系统把定时器消息发送到_ProcTimer定时器过程中去,但是,这时候没有参数用来指定定时器标识,到最后如何用KillTimer撤销这个定时器呢?答案是SetTimer函数会返回一个标识,程序可以保存这个标识并在KillTimer函数中使用。

当然,这种用法中的定时器标识也可以自己指定,但这时候一定要同时指定hWnd,虽然这个hWnd没有实际的用途,如果hWnd为NULL,那么即使指定了定时器标识,这个标识也会被忽略,如:

invoke  SetTimer;hWnd;ID_TIMER3;1000;addr _ProcTimer    (例3)

这个语句定义了一个标识为ID_TIMER3、消息发往_ProcTimer子程序的定时器。

定时器过程是如下定义的:

TimerProc   proc        hwnd;uMsg;idEvent;dwTime

Windows回调定时器过程的时候会有4个参数,uMsg总是WM_TIMER,hwnd和idEvent是例3用法中指定的hWnd和定时器标识,如果是例2的用法,那么hwnd就是NULL,而idEvent就是SetTimer返回的由Windows定义的定时器标识。由于有idEvent参数,所以我们同样可以把多个定时器消息指向同一个定时器过程中,并且根据idEvent参数构建一个分支来处理不同定时器引发的消息。

程序中还可能遇到一种情况:当在SetTimer中指定的定时器标识已经存在会怎样呢?答案是Windows会用新的参数代替老的定时器参数,函数执行以后,这个标识的定时器消息将以新的时间周期发送。

读者可能注意到,例子程序的窗口过程中把WM_TIMER的消息的处理代码放在第一个分支上,这是对程序的简单优化,把频繁发生的消息放到前面可以使程序少执行一系列的比较指令,像WM_CREATE和WM_DESTROY等仅发生一次的消息可以放到分支的最后面。



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


第6章 定时器


6。3 取Windows时间

    
很多读者看到“定时器”这个词的时候往往就联想到时钟,笔者也曾是如此,但是经过6。2节的介绍后就可以发现,定时器是不能用来构造时钟的,定时器用于时钟程序中只能是用在定时刷新屏幕这个功能上,要得到系统的时间还是要靠别的方法。

在Win32编程中,和获取系统时间相关的函数有3个:

    invoke  GetLocalTime;lpSystemTime

    invoke  GetSystemTime;lpSystemTime

    invoke  GetTickCount

它们之间的区别是:

GetTickcount返回的是本次Windows启动以来的ms数,得到的时间数值直接在eax中返回,由于这是一个32位的整数,可以表示的范围是1~ffffffffh ms,所以当Windows连续运行49。7天以后,计数器会清零并重新开始。

GetLocalTime返回当前的时间,GetSystemTime返回当前的格林威治标准时间,这两个函数返回的时间数据包括年、月、日、时、分、秒、毫秒以及星期,数据比较多,所以无法放在eax中返回,应用程序需要预先设置一个SYSTEMTIME结构的缓冲区,并将缓冲区地址lpSystemTime当参数传递给函数,函数会把时间数据返回到这个缓冲区中。

SYSTEMTIME结构的定义如下:

SYSTEMTIME STRUCT

  wYear             WORD    ? ;年

  wMonth            WORD    ? ;月

  wDayOfWeek        WORD   ? ;星期,0=星期日,1=星期一,……

  wDay              WORD    ? ;日

  wHour             WORD    ? ;时

  wMinute           WORD    ? ;分

  wSecond           WORD    ? ;秒

  wMilliseconds     WORD   ? ;毫秒

SYSTEMTIME ENDS

需要注意的是,结构中的字段全部是word类型的,而Win32程序中用的往往是dword型变量,所以在使用这些数据之前往往要先把它们转换为dword类型,用movzx指令就可以很方便地完成这个工作,如movzx eax;stSystemTime。wYear将wYear字段扩展到32位后放到eax中。

和获取系统时间的函数相对应,可以用下面的两个函数设置系统时间:

invoke  SetLocalTime;lpSystemTime

invoke  SetSystemTime;lpSystemTime

同样,SetLocalTime中的参数代表本地时间,SetSysTime中的参数代表格林威治标准时间,在调用函数之前,要把需要设置的时间放到一个SYSTEMTIME结构中并把结构地址当做参数传递给Windows。



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


第7章 图形操作


7。1 GDI原理(1)

    
Windows是基于图形界面的,所以在Win32编程中,图形操作是最常用的操作。GDI的意义在于将程序对图形界面的操作和硬件设备隔绝开来,在程序中可以将所有的图形设备都看成是虚拟设备,包括视频显示器和打印机等,然后通过GDI函数用同样的方法去操作它们,由Windows负责将函数调用转化成针对具体硬件的操作。只要一个设备提供了和Windows兼容的驱动程序,它就可以被看做是一个标准的设备。以前在DOS系统下写应用程序的时候,如果要进行图形操作,那么就要考虑到市场上每种显示卡的不同,否则在装配某种显卡的计算机上就可能无法正常运行,对汇编程序员来说,这真是一个恶梦。在Win32编程中,正是GDI函数让这个恶梦成为历史。

GDI函数全部包括在GDI32。DLL中,在编程的时候,注意要在源程序的开头加上相应的包含语句:

    include     gdi32。inc

    includelib  gdi32。lib

和GDI相关的内容真是太庞大了,只要查看一下gdi32。inc文件就可以发现,函数的总数达到了300多个,和GDI相关的数据结构也非常多,要完全深入GDI编程,用上本书的全部篇幅可能也不够。在本章中,笔者希望
返回目录 上一页 下一页 回到顶部 1 4
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!