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

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>
            欧美一级播放| 午夜在线一区二区| 国产精品久久久久久福利一牛影视 | 久久精精品视频| 久久精品女人| 欧美jjzz| 国产精品社区| 亚洲高清激情| 亚洲少妇自拍| 久久久成人精品| 亚洲国产另类久久精品| 亚洲国产精品久久久久秋霞蜜臀 | 亚洲一区视频在线| 久久久久国产精品人| 欧美福利视频网站| 国产伦精品一区二区三区免费迷| 在线欧美日韩| 亚洲欧美日韩精品久久亚洲区| 久久久久中文| 日韩一区二区电影网| 欧美在线播放高清精品| 欧美日韩国产精品一卡| 韩日欧美一区二区| 亚洲一级黄色av| 欧美激情视频网站| 亚洲女ⅴideoshd黑人| 欧美在线日韩| 亚洲国产欧美日韩| 欧美亚洲一级| 欧美日韩中文字幕在线视频| 激情校园亚洲| 亚洲欧美第一页| 亚洲国产精品ⅴa在线观看| 午夜久久tv| 欧美三级网址| 亚洲精品在线三区| 免费观看成人网| 欧美一区二区三区视频免费播放 | 在线中文字幕不卡| 欧美大片在线观看一区| 一区二区三区在线不卡| 久久av一区二区三区| 中文精品视频| 国产精品二区在线| 亚洲一区二区在线看| 日韩天堂在线视频| 欧美国产精品劲爆| 亚洲级视频在线观看免费1级| 久久国产精品一区二区三区| 亚洲综合精品一区二区| 国产精品久久久久永久免费观看| 99国内精品| 亚洲精品美女免费| 欧美麻豆久久久久久中文| 最新中文字幕一区二区三区| 美国十次成人| 男人插女人欧美| 亚洲人成在线免费观看| 亚洲国产视频一区二区| 欧美人成在线视频| 中日韩高清电影网| 亚洲视频999| 国产亚洲电影| 美女爽到呻吟久久久久| 狼狼综合久久久久综合网 | 亚洲精品午夜精品| 亚洲激情专区| 国产精品vip| 欧美在线免费视频| 久久久水蜜桃| 洋洋av久久久久久久一区| 99精品国产高清一区二区| 国产精品美女999| 久久久久久一区| 女生裸体视频一区二区三区| 99精品国产高清一区二区| 一本色道久久综合亚洲精品小说 | 亚洲国产欧美日韩另类综合| 一本色道久久综合| 国产精品无人区| 久久久久国产精品午夜一区| 久久三级视频| 99人久久精品视频最新地址| 亚洲欧美日韩在线| 亚洲激情小视频| 亚洲午夜电影网| 精品av久久707| 亚洲理伦电影| 国产在线乱码一区二区三区| 亚洲国产高清在线| 国产精品免费在线| 模特精品在线| 国产精品激情偷乱一区二区∴| 久久精品国产清高在天天线| 蜜臀99久久精品久久久久久软件| 亚洲一区二区三区四区五区黄| 久久九九国产精品| 亚洲一区二区三区精品动漫| 久久午夜av| 欧美一区二区视频在线观看2020 | 久久激情视频| 欧美日韩成人综合| 美女精品在线观看| 国产精品亚发布| 亚洲美女免费视频| 亚洲国产女人aaa毛片在线| 亚洲女爱视频在线| 日韩视频三区| 久久综合国产精品台湾中文娱乐网| 亚洲一区欧美激情| 欧美激情黄色片| 欧美不卡福利| 国产在线视频欧美| 亚洲视频欧美视频| 亚洲久久视频| 欧美成人午夜免费视在线看片| 久久久久天天天天| 国产乱码精品一区二区三区忘忧草| 亚洲精品在线观看免费| 91久久午夜| 免费欧美日韩| 欧美高清hd18日本| 激情视频一区二区| 欧美专区在线播放| 久久精视频免费在线久久完整在线看| 国产精品免费在线| 亚洲一区尤物| 欧美亚洲综合网| 国产欧美日韩一区二区三区在线观看 | 亚洲欧洲一区| 亚洲国产婷婷综合在线精品| 久久美女艺术照精彩视频福利播放| 久久高清国产| 国产日韩欧美不卡在线| 午夜综合激情| 久久女同互慰一区二区三区| 国产资源精品在线观看| 欧美一级视频| 久久午夜精品| 亚洲大胆人体视频| 你懂的视频欧美| 亚洲精品中文字幕有码专区| 一区二区三区www| 国产精品成人aaaaa网站| 亚洲一区二区三区四区视频| 久久激情视频久久| 亚洲二区精品| 欧美日本国产| 亚洲欧美国产精品桃花| 久久五月天婷婷| 99av国产精品欲麻豆| 国产精品久久久久久五月尺| 欧美一区二区视频在线观看2020| 免费看精品久久片| 亚洲三级免费| 国产精品网站一区| 玖玖在线精品| 亚洲一区三区视频在线观看| 蜜臀91精品一区二区三区| 亚洲免费av观看| 国产日产欧美精品| 欧美.日韩.国产.一区.二区| 在线亚洲一区| 欧美激情一区二区三区在线视频观看| 一区二区欧美视频| 韩国三级电影一区二区| 欧美日韩国产va另类| 久久精品国产免费看久久精品| 亚洲激情偷拍| 久久精品国产99国产精品| 亚洲日本aⅴ片在线观看香蕉| 国产精品午夜电影| 欧美激情一区二区三区全黄 | 国产精品成人va在线观看| 久久久久久国产精品一区| 日韩午夜免费| 欧美大胆成人| 欧美在线综合| 亚洲网站视频福利| 亚洲国产精品黑人久久久| 国产美女精品| 欧美性视频网站| 欧美精品日日鲁夜夜添| 久久视频精品在线| 欧美一级片一区| 亚洲一区二区在线免费观看视频| 亚洲丰满在线| 免费成人性网站| 久久青草福利网站| 久久国产精品免费一区| 亚洲欧美日韩国产一区二区三区 | 亚洲图片你懂的| 最新中文字幕亚洲| 在线精品亚洲| 影音欧美亚洲| 亚洲第一伊人| 亚洲高清久久| 亚洲国产成人精品视频| 狠狠干成人综合网| 国模叶桐国产精品一区|