The Timer in a Console Application

In the last section of this chapter, I'll consider an aspect rarely covered in programming literaturetimers in console applications. It should be pointed out that, by doing so, I am rushing slightly ahead, because I consider timers in console applications before timers in GUI applications.

The main method of creating a timer is by using the SetTimer function. Later, I'll cover this function in more detail. There are two modes for setting a timer. The first mode is the one in which the last function parameter is zero. In this case, the current window (or, to be more precise, its function) will receive the WM_TIMER message with a predefined time period defined by the third parameter. When operating in the second mode, the last parameter will point to the function that will be called with the predefined periodicity. However, this function isn't suitable for a console application, because the WM_TIMER message is dispatched to a window by the DispatchMessage function employed in the message-processing loop. This, the use of this function for console applications is problematic .

For console applications, it is expedient to use the timeSetEvent function, the parameters of which are briefly outlined here:

  • First parameterTimer delay (from your viewpoint, this time is the same as the period between two timer calls)

  • Second parameterTimer precision (the priority of message sending)

  • Third parameterAddress of the procedure being called'

  • Fourth parameterAddress sent to the procedure

  • Fifth parameterType of the procedure call: one time or periodic

If the function has completed successfully, then the timer identifier will be returned into EAX .

The calling procedure itself receives the following five parameters:

  • First parameterTimer identifier

  • Second parameterNot used

  • Third parameter Dat (see the description of the timeSetEvent function)

  • Fourth and fifth parametersNot used

To remove the timer, use the timeKillEvent function that receives the timer identifier as its parameter.

Listing 8.5: A timer in the console mode
image from book
 .586P ; Flat memory model .MODEL FLAT, stdcall ; Constants STD_OUTPUT_HANDLE      equ -11 STD_INPUT_HANDLE       equ -10 TIME_PERIODIC          equ 1 ; Type of the timer call ; Color attributes FOREGROUND_BLUE        equ 1h ; Blue foreground color FOREGROUND_GREEN       equ 2h ; Green foreground color FOREGROUND_RED         equ 4h ; Red foreground color FOREGROUND_INTENSITY   equ 8h ; Increased intensity BACKGROUND_BLUE        equ 10h ; Blue background color BACKGROUND_GREEN       equ 20h ; Green background color BACKGROUND_RED         equ 40h ; Red background color BACKGROUND_INTENSITY   equ 80h ; Increased intensity COLl = 2h+8h ; Color of the displayed text ; Prototypes of external procedures EXTERN  wsprintfA:NEAR EXTERN  GetStdHandle@4:NEAR EXTERN  WriteConsoleA@20:NEAR EXTERN  SetConsoleCursorPosition@8:NEAR EXTERN  SetConsoleTitleA@4:NEAR EXTERN  FreeConsole@0:NEAR EXTERN  AllocConsole@0:NEAR EXTERN  CharToOemA@8:NEAR EXTERN  SetConsoleCursorPosition@8:NEAR EXTERN  SetConsoleTextAttribute@8:NEAR EXTERN  ReadConsoleA@20:NEAR EXTERN  timeSetEvent@20:NEAR EXTERN  timeKillEvent@4:NEAR EXTERN  ExitProcess@4:NEAR ; INCLUDELIB directives for the linker includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib includelib c:\masm32\lib\winmm.lib ;----------------------------------------------- COOR STRUC X  WORD ? Y  WORD ? COOR  ENDS ; Data segment _DATA SEGMENT     HANDL  DWORD ?     HANDL1 DWORD ?     STR2   DB "Example of a timer in a console application", 0     STR3   DB 100 dup(0)     FORM   DB "Number of timer calls: %lu", 0     BUF    DB 200 dup(?)     NUM    DWORD 0     LENS   DWORD ? ; Number of displayed characters     CRD    COOR <?>     ID     DWORD ? ; Timer identifier     HWND   DWORD ? _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Create a console ; First, release the existing console     CALL  FreeConsole@0     CALL  AllocConsole@0 ; Get the HANDL1 input handle     PUSH  STD_INPUT_HANDLE     CALL  GetStdHandle@4     MOV   HANDL1, EAX ; Get the HANDL output handle     PUSH  STD_OUTPUT_HANDLE     CALL  GetStdHandle@4     MOV   HANDL, EAX ; Specify the console window header     PUSH  OFFSET STR2     CALL  SetConsoleTitleA@4 ; Specify the color attributes for the output text     PUSH  COL1     PUSH  HANDL     CALL  SetConsoleTextAttribute@8 ; Set the timer     PUSH  TIME_PERIODIC  ; Periodic call     PUSH  0     PUSH  OFFSET TIME    ; Procedure being called by the timer     PUSH  0              ; Precision of the timer call     PUSH  1000           ; Calls per second     CALL  timeSetEvent@20     MOV   ID, EAX ; Wait for the string input     PUSH  0     PUSH  OFFSET LENS     PUSH  200     PUSH  OFFSET BUF     PUSH  HANDL1     CALL  ReadConsoleA@20 ; Close the timer     PUSH  ID     CALL  timeKillEvent@4 ; Close the console     CALL  FreeConsole@0     PUSH  0     CALL  ExitProcess@4 ; String - [EBP+08H] ; Length in EBX LENSTR    PROC     ENTER 0, 0     PUSH  EAX ;----------------------     CLD     MOV   EDI, DWORD PTR [EBP+08H]     MOV   EBX, EDI     MOV   ECX, 100 ; Limit the string length     XOR   AL, AL     REPNE SCASB ; Find the 0 character     SUB   EDI, EBX ; String length including 0     MOV   EBX, EDI     DEC   EBX ;----------------------     POP   EAX     LEAVE     RET 4 LENSTR ENDP ; Procedure called by the timer TIME  PROC     PUSHA ; Save all registers ; Set the cursor position     MOV   CRD.X, 0     MOV   CRD.Y, 10     PUSH  CRD     PUSH  HANDL     CALL  SetConsoleCursorPosition@8 ; Fill the STR3 string     PUSH  NUM     PUSH  OFFSET FORM     PUSH  OFFSET STR3     CALL  wsprintfA     ADD   ESP, 12 ; Restore the stack ; Reencode the STR3 string     PUSH  OFFSET STR3     PUSH  OFFSET STR3     CALL  CharToOemA@8 ; Display the string with the timer call number     PUSH  OFFSET STR3     CALL  LENSTR     PUSH  0     PUSH  OFFSET LENS     PUSH  EBX     PUSH  OFFSET STR3     PUSH  HANDL     CALL  WriteConsoleA@20     INC   NUM     POPA     RET   20 ; Exit and release the stack TIME ENDP _TEXT ENDS END START 
image from book
 

The program presented in Listing 8.5 will output the counter value into the window. This value will be incremented by one once per second.

This chapter was opened with considerations about the command line; however, until now, I haven't explained how to work with the command line. Well, everything is easy here. There is an API function called GetcommandLine , which returns the pointer to the command string. This function operates similarly both for console applications and for GUI applications. The program presented in Listing 8.6 prints the command-line parameters. As you may have guessed, the first parameter is the program's full name .

Listing 8.6: Working with the command-line parameters
image from book
 ; The program for the output of the command-line parameters .586P ; Flat memory model .MODEL FLAT, stdcall ; Constants CTL_OUTPUT_HANDLE equ -11 ; Prototypes of external procedures EXTERN GetStdHandle@4:NEAR EXTERN WriteConsoleA@20:NEAR EXTERN ExitProcess@4:NEAR EXTERN GetCommandLineA@0:NEAR ; Include directives for the linker includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ;------------------------------------- ; Data segment _DATA SEGMENT     BUF   DB 100 dup(0)     LENS  DWORD ? ; Number of displayed characters     NUM   DWORD ?     CNT   DWORD ?     HANDL DWORD ? _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the HANDLE output handle     PUSH  STD_OUTPUT_HANDLE     CALL  GetStdHandle@4     MOV   HANDL, EAX ; Get the number of parameters     CALL  NUMPAR     MOV   NUM, EAX     MOV   CNT, 0 ;------------------------------------- ; Output the command-line parameters LL1:     MOV   EDI, CNT     CMP   NUM, EDI     JE    LL2 ; Parameter number     INC   EDI     MOV   CNT, EDI ; Get the parameter number EDI     LEA   EBX, BUF     CALL  GETPAR ; Get the parameter length     PUSH  OFFSET BUF     CALL  LENSTR ; Line feed in the end     MOV   BYTE PTR [BUF+EBX], 13     MOV   BYTE PTR [BUF+EBX+1], 10     MOV   BYTE PTR [BUF+EBX+2], 0     ADD   EBX, 2 ; String output     PUSH  0     PUSH  OFFSET LENS     PUSH  EBX     PUSH  OFFSET BUF     PUSH  HANDL     CALL  WriteConsoleA@20     JMP   LL1 LL2:     PUSH  0     CALL  ExitProcess@4 ; String - [EBP+08H] ; Length in EBX LENSTR PROC     PUSH  EBP     MOV   EBP, ESP     PUSH  EAX ;---------------------     CLD     MOV   EDI, DWORD PTR [EBP+08H]     MOV   EBX, EDI     MOV   ECX, 100 ; Limit the string length     XOR   AL, AL     REPNE SCASB ; Find the 0 character     SUB   EDI, EBX ; String length including 0     MOV   EBX, EDI     DEC   EBX ;---------------------------     POP   EAX     POP   EBP     RET   4 LENSTR ENDP ; Define the number of parameters (   EAX) NUMPAR PROC     CALL  GetCommandLineA@0     MOV   ESI, EAX ; Pointer to the string     XOR   ECX, ECX ; Counter     MOV   EDX, 1 ; Indicator LI:     CMP   BYTE PTR [ESI], 0     JE    L4     CMP   BYTE PTR [ESI], 32     JE    L3     ADD   ECX, EDX ; Parameter number     MOV   EDX, 0     JMP   L2 L3:     OR    EDX, 1 L2:     INC   ESI     JMP   L1 L4:     MOV   EAX, ECX     RET NUMPAR ENDP ; Get the parameter ; EBXPoints to the buffer in which the parameter will be loaded ; Zero-terminated string is loaded into the buffer ; EDIParameter number GETPAR PROC     CALL  GetCommandLineA@0     MOV   ESI, EAX ; Pointer to the string     XOR   ECX, ECX ; Counter     MOV   EDX, 1 ; Indicator L1:     CMP   BYTE PTR [ESI], 0     JE    L4     CMP   BYTE PTR [ESI], 32     JE    L3     ADD   ECX, EDX ; Parameter number     MOV   EDX, 0     JMP   L2 L3:     OR    EDX, 1 L2:     CMP   ECX, EDI JNE L5     MOV   AL, BYTE PTR [ESI]     MOV   BYTE PTR [EBX], AL     INC   EBX L5:     INC   ESI     JMP   L1 L4:     MOV   BYTE PTR [EBX], 0     RET GETPAR ENDP _TEXT ENDS END START 
image from book
 

I strongly recommend that you make sure you understand the working algorithms of the NUMPAR and GETPAR procedures.

Note that to assemble and link the program from Listing 8.6 using TASM, in addition to the standard modifications that you know already, it is necessary to add the @@ locality prefix for matching labels and add the locals directive to the start of the program.



The Assembly Programming Master Book
The Assembly Programming Master Book
ISBN: 8170088178
EAN: 2147483647
Year: 2004
Pages: 140
Authors: Vlad Pirogov

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net