青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

luqingfei@C++

為中華之崛起而崛起!
兼聽則明,偏聽則暗。

Win32匯編--定時器

 

Win32匯編--定時器

 

1、定時器簡介

在應用程序需要使用定時器時,可以用SetTimer函數向Windows申請一個定時器,要求系統在指定的時間以后“通知”應用程序,如果申請成功的話,系統會以指定的時間周期調用SetTimer函數指定的回調函數,或者向指定的窗口過程發送WM_TIMER消息,和DOS操作系統固定以55ms的間隔觸發中斷服務程序相比,SetTimer函數可以指定的時間間隔更為靈活——以ms為單位,可以指定的時間周期為一個32位的整數,也就是從1~4294 967 295ms,這可是一個將近50天的范圍!

 

但是在具體的使用中不要被這個參數所迷惑:由于Windows的定時器同樣是基于時鐘中斷的,所以雖然參數的單位是ms,但精度還是55ms,如果指定一個小于55ms的周期,不管是1ms還是54msWindows最快也只能在每個時鐘中斷的時候觸發這個定時器,也就是說,實際上這個定時器是以55ms為觸發周期的;另外,當指定一個時間間隔的時候,Windows以和這個間隔最接近的55ms的整數位時間來觸發定時器,假定建立一個周期為1000ms的定時器,定時器的觸發周期實際上不是1s而是989ms55ms*18)。

 

使用定時器時還有一個要點就是定時器消息是一個低級別的消息,這表現在兩個方面:首先就是Windows只有在消息隊列中沒有其他消息的情況下才會發送WM_TIMER消息,如果窗口過程忙于處理某個消息沒有返回,使消息隊列中有消息積累起來,那么WM_TIMER消息就會被丟棄,在消息隊列再度空閑的時候,被丟棄的WM_TIMER消息不會被補發;其次,消息隊列中不會有多條WM_TIMER消息,如果消息隊列中已經有一條WM_TIMER消息,還沒來得及處理,又到了定時的時刻,那么兩條WM_TIMER消息會被合并成一條。

 

所以,應用程序不能依靠定時器來保證某件事情必須在規定的時刻被處理,另外,也不能依賴對定時器消息計數來確定已經過去了多少時間。

 

 

2、定時器的使用

//Timer.rc

#include <resource.h>

#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      ?

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 代碼段

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                .code

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 定時器過程

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_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

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

                .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

參數hWnduIDEvent就是建立定時器時使用的數值。

使用SetTimer函數的方法有兩種,第一種方法是要求WindowsWM_TIMER消息發往指定的窗口過程,這時候lpTimerFunc必須為NULL,如例子中的:

invoke SetTimer, hWnd, ID_TIMER1, 250, NULL

invoke SetTimer, hWnd, ID_TIMER2, 2000, NULL

這兩個句子設置了兩個標識分別為ID_TIMER1ID_TIMER2的定時器,定時周期分別為250ms2s。在窗口過程收到WM_TIMER消息的時候,wParam中是用SetTimer建立定時器時使用的標識uIDEvent,所以程序可以建立一個分支,通過判斷wParam來處理不同的定時器引起的WM_TIMER的消息。在例子中,當wParamID_TIMER1的時候更換圖標框中的圖標,是ID_TIMER2的時候用MessageBeep函數來發出一聲“嘟”的聲音。如果要撤銷用這種方法建立的定時器,那么只需要用建立時的hWnduIDEvent參數簡單地調用KillTimer就可以了。

 

還有一種使用定時器的方法,那就是要求Windows在時間到的時候調用指定的定時器過程,而不是某個窗口過程,那么只需要指定lpTimerFunc參數,如例子中的:

invoke SetTimer, NULL, NULL, 1000, addr _ProcTimer

這句語句要求系統把定時器消息發送到_ProcTimer定時器過程中去,但是,這時候沒有參數用來指定定時器標識,到最后如何用KillTimer撤銷這個定時器呢?答案是SetTimer函數會返回一個標識,程序可以保存這個標識并在KillTimer函數中使用。

 

當然,這種用法中的定時器標識也可以自己指定,但這時候一定要同時指定hWnd,雖然這個hWnd沒有實際的用途,如果hWndNULL,那么即使指定了定時器標識,這個標識也會被忽略,如:

invoke SetTimer, hWnd, ID_TIMER3, 1000, addr _ProcTimer

這個語句定義了一個標識為ID_TIMER3、消息發往_ProcTimer子程序的定時器。

 

定時器過程是如下定義的:

TimerProc      proc        hWnd, uMsg, idEvent, dwTime

Windows回調定時器過程的時候會有4個參數,uMsg總是WM_TIMERhWndidEvent是窗口句柄和定時器標識。由于有idEvent參數,所以我們同樣可以把多個定時器消息指向同一個定時器過程中,并且根據idEvent參數構建一個分支來處理不同定時器引發的消息。

 

程序中還可能遇到一種情況:當在SetTimer中指定的定時器標識已經存在會怎樣呢?答案是Windows會用新的參數代替老的定時器參數,函數執行以后,這個標識的定時器消息將以新的時間周期發送。

 

注意:例子程序的窗口過程中把WM_TIMER的消息的處理代碼放在第一個分支上,這是對程序的簡單優化,把頻繁發生的消息放到前面可以使程序少執行一系列的比較指令,像WM_CREATEWM_DESTROY等僅發生一次的消息可以放到分支的最后面。

 

 

3、取Windows時間

“定時器”這個詞很容易讓人聯想到時鐘,但是在前面介紹過,定時器是不能用來構造時鐘的,定時器用于時鐘程序中只能是用在定時刷新屏幕這個功能上,要得到系統的時間還是要靠別的方法。

 

Win32編程中,和獲得系統時間相關的函數有3個:

invoke GetLocalTime, lpSystemTime

invoke GetSystemTime, lpSystemTime

invoke GetTickCount

 

它們之間的區別是:

GetTickCout返回的是本次Windows啟動以來的ms數,得到的時間數值直接在eax中返回,由于這是一個32位的整數,可以表示的范圍是1~ffffffffms,所以當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.wYearwYear字段擴展到32位后放在eax中。

 

和獲得系統時間的函數相對應,可以用下面的兩個函數設置系統時間:

invoke SetLocalTime, lpSystemTime

invoke SetSystemTime, lpSystemTime

同樣,SetLocalTime中的參數代表本地時間,SetSysTime中的參數代表格林威治標準時間,在調用函數之前,要把需要設置的時間放到一個SYSTEMTIME結構中并把結構地址當做參數傳遞給Windows

 

posted on 2010-09-23 11:40 luqingfei 閱讀(2023) 評論(0)  編輯 收藏 引用 所屬分類: Win32匯編程語言序設計

導航

<2011年9月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

統計

留言簿(6)

隨筆分類(109)

隨筆檔案(105)

Blogers

Game

Life

NodeJs

Python

Useful Webs

大牛

搜索

積分與排名

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            在线免费日韩片| 国产综合久久久久久| 欧美日韩卡一卡二| 国产一区视频网站| 一区二区三区产品免费精品久久75 | 午夜精品视频网站| 欧美激情第9页| 久久xxxx精品视频| 国产拍揄自揄精品视频麻豆| 一区二区三区成人| 亚洲精品国产系列| 久久综合网hezyo| 国产自产2019最新不卡| 欧美伊人久久久久久午夜久久久久 | 亚洲欧洲三级电影| 免费观看成人鲁鲁鲁鲁鲁视频| 国产一区美女| 午夜精品亚洲| 亚洲天堂网站在线观看视频| 欧美视频一区二区| 亚洲在线一区二区三区| 亚洲嫩草精品久久| 国产精品一区二区在线观看不卡| 亚洲综合第一页| 99精品欧美一区二区蜜桃免费| 欧美日韩国产黄| 亚洲在线黄色| 性欧美暴力猛交69hd| 国产一区二区三区在线播放免费观看| 性欧美超级视频| 亚洲欧美国产视频| 国自产拍偷拍福利精品免费一| 久久人人97超碰国产公开结果| 久久久久高清| 日韩一区二区免费看| 日韩手机在线导航| 国产精品久久久久久五月尺| 欧美一级视频精品观看| 久久精品亚洲一区二区| 亚洲高清不卡在线| 亚洲美女在线国产| 国产午夜精品久久久久久久| 久久综合中文| 欧美日本在线| 久久精品亚洲热| 牛牛国产精品| 小黄鸭精品aⅴ导航网站入口| 久久av在线看| 91久久午夜| 中文av一区特黄| 狠狠色丁香久久婷婷综合_中| 亚洲黄一区二区三区| 国产精品嫩草99a| 久久蜜桃精品| 欧美激情亚洲国产| 欧美一级视频精品观看| 一区二区三区视频在线| 欧美一级午夜免费电影| 99re成人精品视频| 午夜视频在线观看一区二区三区| 亚洲第一福利视频| 中文欧美在线视频| 亚洲国产精品一区二区三区| 日韩视频中文字幕| 在线观看欧美黄色| 亚洲欧美视频在线| 中文日韩电影网站| 麻豆久久婷婷| 欧美影视一区| 欧美片在线观看| 国产精品一区二区a| 久久综合99re88久久爱| 久久激情婷婷| 在线电影院国产精品| 卡通动漫国产精品| 久久久久久亚洲精品杨幂换脸 | 亚洲午夜精品17c| 亚洲精品乱码久久久久久蜜桃麻豆 | 一二三区精品| 国产精品久久9| 亚洲欧美日韩久久精品| 99精品免费网| 国产伦精品一区二区三区照片91| 欧美一区二区三区日韩| 欧美一级专区免费大片| 136国产福利精品导航网址应用| 免费中文日韩| 欧美精品在线视频观看| 亚洲视频视频在线| 午夜精品一区二区三区电影天堂| 国产综合久久久久影院| 亚洲日本免费| 国产精品一区免费视频| 久热精品视频在线| 欧美日韩成人在线观看| 久久国产精品高清| 久久久久一区二区| 亚洲视频中文| 欧美在线视频观看| 99热免费精品| 欧美在线精品免播放器视频| 亚洲国产91| 亚洲一级二级在线| 亚洲日本成人| 午夜精品久久久久久久| 亚洲人成人77777线观看| aa国产精品| 亚洲福利在线视频| 午夜精品剧场| 一区二区三区欧美激情| 欧美中文在线视频| 欧美成人伊人久久综合网| 欧美视频精品在线观看| 欧美在线视频在线播放完整版免费观看| 久久黄金**| 这里只有精品电影| 久久久www成人免费精品| 亚洲午夜电影| 欧美精品亚洲| 欧美成人免费大片| 国产日韩精品一区二区| 一区二区三区国产精华| 日韩视频在线观看国产| 久久精品一区二区三区不卡牛牛| 亚洲免费在线播放| 欧美日韩国产三区| 免费h精品视频在线播放| 国产精品欧美精品| 亚洲国产精品va在线看黑人| 黑人巨大精品欧美黑白配亚洲| 亚洲久久视频| 日韩亚洲一区在线播放| 女人天堂亚洲aⅴ在线观看| 久久综合给合久久狠狠色| 国产欧美日韩视频一区二区三区| 亚洲美女黄色片| 99这里有精品| 欧美激情一区二区三级高清视频| 女仆av观看一区| 1024亚洲| 麻豆国产精品一区二区三区 | 影音先锋亚洲一区| 欧美一级久久久久久久大片| 亚洲视屏在线播放| 老司机成人在线视频| 欧美视频1区| 日韩视频免费观看高清在线视频| 99精品欧美一区| 欧美视频观看一区| 亚洲网站视频| 久久国产日韩欧美| 一区二区三区在线免费观看| 欧美影视一区| 久久免费黄色| 亚洲电影中文字幕| 欧美母乳在线| 亚洲一级二级在线| 久久久久久久久一区二区| 狠狠色综合网站久久久久久久| 久久国产婷婷国产香蕉| 国产在线观看精品一区二区三区 | 国产精品国产a| 亚洲欧美日韩国产一区二区| 久久激情视频久久| 在线精品一区二区| 欧美日韩二区三区| 亚洲欧美日韩在线一区| 久久尤物视频| 亚洲另类在线视频| 欧美日韩一区二区在线| 亚洲手机在线| 免费观看久久久4p| 亚洲精品国产精品久久清纯直播| 欧美美女视频| 欧美激情一区二区在线| 亚洲激情视频在线播放| 亚洲日本乱码在线观看| 欧美一区激情| 日韩亚洲欧美成人| 免费不卡在线观看av| 99国产精品99久久久久久| 亚洲国产导航| 久久免费少妇高潮久久精品99| 亚洲一区二区三区中文字幕| 久久精品国产免费| 一区二区三区不卡视频在线观看| 国产精品一卡二| 亚洲免费在线精品一区| 日韩一二三区视频| 宅男精品视频| 久久久久国产免费免费| 亚洲国内高清视频| 国产啪精品视频| 欧美激情免费观看| 久久精品国产亚洲5555| 亚洲免费播放| 你懂的国产精品永久在线| 午夜欧美大片免费观看 | 激情综合久久| 国产精品毛片高清在线完整版|