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

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匯編程語言序設計

導航

<2010年9月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

統計

留言簿(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>
            亚洲毛片一区二区| 欧美激情综合五月色丁香| 久久久九九九九| 久久久久久久综合狠狠综合| 亚洲欧美区自拍先锋| 午夜精品一区二区在线观看| 欧美一级成年大片在线观看| 久久国产主播| 欧美国产日产韩国视频| 亚洲精品免费在线播放| 美女久久一区| 亚洲日韩欧美视频一区| 亚洲影院在线观看| 久久久久88色偷偷免费| 欧美寡妇偷汉性猛交| 欧美午夜电影网| 国产在线观看精品一区二区三区| 亚洲福利在线观看| 亚洲特色特黄| 麻豆精品91| 中文在线不卡| 麻豆精品传媒视频| 亚洲国产欧美日韩另类综合| 国产精品久久久久一区二区三区共| 欧美精品日韩www.p站| 久久综合九色欧美综合狠狠| 久久亚洲美女| 久久久久久国产精品mv| 久久黄色网页| 国产精品久久久久aaaa九色| 国产综合香蕉五月婷在线| 国产精品乱码一区二区三区| 亚洲欧美日韩精品一区二区| 久久精品国产一区二区三区免费看| 免费看亚洲片| 国产日韩精品一区二区浪潮av| 一区二区三区自拍| 亚洲欧美中文在线视频| 亚洲电影观看| 香港成人在线视频| 欧美日韩亚洲三区| 最新国产乱人伦偷精品免费网站| 亚洲欧美影音先锋| 蘑菇福利视频一区播放| 国产手机视频精品| 亚洲欧美美女| 99视频国产精品免费观看| 美女999久久久精品视频| 国产欧美一区二区三区久久| 在线亚洲欧美| 亚洲激情网址| 美女亚洲精品| 亚洲黄网站在线观看| 久久久久女教师免费一区| 中文av一区二区| 欧美色视频在线| 一本久久综合| 亚洲精品一区二区三区不| 你懂的国产精品| 亚洲国产精品第一区二区三区| 久久这里只有精品视频首页| 欧美亚洲在线播放| 韩日欧美一区| 快播亚洲色图| 久久只精品国产| 亚洲国产精品成人精品| 亚洲黑丝在线| 欧美天天影院| 久久精品99久久香蕉国产色戒| 欧美一二区视频| 一区二区三区在线观看欧美 | 亚洲毛片一区二区| 欧美激情一区二区三区蜜桃视频| 亚洲一区二区成人在线观看| 你懂的成人av| 一本色道久久综合| 中国女人久久久| 国语自产精品视频在线看抢先版结局 | 亚洲视频综合在线| 国产精品影院在线观看| 欧美日韩另类字幕中文| 一区二区三区成人| 亚洲女爱视频在线| 一区二区亚洲精品国产| 亚洲国产一区二区三区在线播| 欧美日韩国产大片| 欧美一区二视频| 老牛嫩草一区二区三区日本| 一本久久a久久免费精品不卡| 午夜精品久久久久久| 在线国产欧美| 国产精品99久久不卡二区| 狠狠色伊人亚洲综合网站色| 最新国产の精品合集bt伙计| 国产精品日韩在线一区| 另类激情亚洲| 国产精品成人在线观看| 久久深夜福利| 国产精品国产三级国产a| 久久露脸国产精品| 欧美三级电影精品| 麻豆精品在线播放| 国产精品理论片在线观看| 久久综合九色综合欧美狠狠| 欧美日韩国产高清| 麻豆av一区二区三区| 欧美午夜视频在线| 欧美激情免费观看| 国产永久精品大片wwwapp| 日韩一级视频免费观看在线| 在线高清一区| 欧美一级大片在线免费观看| 亚洲婷婷国产精品电影人久久| 久久综合久久综合这里只有精品| 羞羞视频在线观看欧美| 欧美乱妇高清无乱码| 亚洲激情中文1区| 小辣椒精品导航| 亚洲免费在线观看视频| 欧美日韩mv| 亚洲国产乱码最新视频| 亚洲成人在线观看视频| 欧美在线视频不卡| 久久成人一区| 国产日韩欧美在线播放不卡| 亚洲色无码播放| 亚洲一区二区精品在线| 欧美另类videos死尸| 亚洲国产精品成人久久综合一区 | 亚洲视频国产视频| 亚洲人成欧美中文字幕| 久久先锋影音| 久久国产加勒比精品无码| 国产精品久久久久久户外露出 | 亚洲一区免费| 亚洲欧美日韩视频二区| 欧美视频观看一区| 亚洲精品国产精品乱码不99| 亚洲毛片在线| 欧美日韩黄视频| 日韩视频免费大全中文字幕| 中国日韩欧美久久久久久久久| 欧美日韩精品系列| 在线亚洲欧美专区二区| 午夜精品区一区二区三| 国产日韩欧美综合精品| 久久国产一区二区| 欧美成人自拍视频| 99精品99| 国产精品视频第一区| 欧美在线欧美在线| 欧美激情a∨在线视频播放| 日韩视频在线一区二区三区| 欧美午夜激情视频| 新片速递亚洲合集欧美合集| 久久久久久久久久码影片| 1024精品一区二区三区| 欧美精品在欧美一区二区少妇| 一区二区欧美在线观看| 久久精品一区二区三区不卡| 亚洲成色最大综合在线| 欧美日韩亚洲综合一区| 性欧美xxxx大乳国产app| 免费久久久一本精品久久区| 99精品国产99久久久久久福利| 国产精品自拍视频| 嫩草国产精品入口| 亚洲在线免费| 欧美激情一二三区| 午夜欧美不卡精品aaaaa| 黄色亚洲免费| 欧美视频官网| 欧美大片18| 欧美一区二区在线看| 亚洲三级毛片| 老色批av在线精品| 亚洲一区二区av电影| 亚洲国产成人午夜在线一区 | 亚洲精品欧美精品| 欧美在线观看视频在线| 欧美激情一区在线| 欧美一区在线直播| 亚洲精品久久久久久久久久久| 国产精品嫩草99a| 欧美成人国产va精品日本一级| 午夜精品在线观看| 亚洲毛片网站| 亚洲国产欧美一区二区三区同亚洲| 欧美一区免费| 亚洲在线视频观看| 亚洲精品婷婷| 狠狠色狠色综合曰曰| 国产精品久久久久99| 欧美啪啪一区| 欧美xxxx在线观看| 久久亚洲精品视频| 国产精品theporn| 亚洲区中文字幕| 免费人成精品欧美精品| 午夜精品久久久久久久99水蜜桃 |