0%

MASM : MS-Windows Programming (3)

- Console Window Manipulation 大概分成這四種

  • Screen buffer
  • Console window
  • Controlling the cursor
  • Controlling the text color

The active screen buffer includes data displayed by the console window.

- SetConsoleTitle

SetConsoleTitle changes the console window’s title. Pass it a null-terminated string:

1
2
3
4
.data
titleStr BYTE "Console title",0
.code
INVOKE SetConsoleTitle, ADDR titleStr

- GetConsoleScreenBufferInfo

GetConsoleScreenBufferInfo returns information about the current state of the console window. It has two parameters: a handle to the console screen, and a pointer to a structure that is filled in by the function:

1
2
3
4
5
6
7
.data
outHandle DWORD ?
consoleInfo CONSOLE_SCREEN_BUFFER_INFO <>
.code
INVOKE GetConsoleScreenBufferInfo,
outHandle,
ADDR consoleInfo

- CONSOLE_SCREEN_BUFFER_INFO

1
2
3
4
5
6
7
CONSOLE_SCREEN_BUFFER_INFO STRUCT
dwSize COORD <>
dwCursorPos COORD <>
wAttributes WORD ?
srWindow SMALL_RECT <>
maxWinSize COORD <>
CONSOLE_SCREEN_BUFFER_INFO ENDS
  • dwSize -size of the screen buffer (char columns and rows)
  • dwCursorPos -cursor location
  • wAttributes -colors of characters in console buffer
  • srWindow -coords of console window relative to screen buffer
  • maxWinSize -maximum size of the console window

- COORD and SMALL_RECT

  • The COORD structure specifies X and Y screen coordinates in character measurements, which default to 0-79 and 0-24.
  • The SMALL_RECT structure specifies a window’s location in character measurements.
1
2
3
4
COORD STRUCT
X WORD ?
Y WORD ?
COORD ENDS
1
2
3
4
5
6
SMALL_RECT STRUCT
Left WORD ?
Top WORD ?
Right WORD ?
Bottom WORD ?
SMALL_RECT ENDS

- SetConsoleWindowInfo

  • SetConsoleWindowInfo lets you set the size and position of the console window relative to its screen buffer.
  • Prototype:
1
2
3
4
SetConsoleWindowInfo PROTO,
nStdHandle:DWORD,; screen buffer handle
bAbsolute:DWORD,; coordinate type
pConsoleRect:PTR SMALL_RECT; window rectangle

- SetConsoleScreenBufferSize

  • SetConsoleScreenBufferSize lets you set the screen buffer size to X columns by Y rows.
  • Prototype:
1
2
3
SetConsoleScreenBufferSize PROTO,
outHandle:DWORD,; handle to screen buffer
dwSize:COORD; new screen buffer size

- Controlling the Cursor

returns the size and visibility of the console cursor

1
GetConsoleCursorInfo PROTO, hConsoleOutput:HANDLE, lpConsoleCursorInfo: PTR CONSOLE_CURSOR_INFO

sets the size and visibility of the cursor

1
SetConsoleCursorInfo PROTO, hConsoleOutput:HANDLE, lpConsoleCursorInfo: PTR CONSOLE_CURSOR_INFO

sets the X, Y position of the cursor

1
SetConsoleCursorPosition PROTO, hConsoleOutput:HANDLE, dwCursorPosition:COORD

- CONSOLE_CURSOR_INFO

Structure containing information about the console’s cursor size and visibility:

1
2
3
4
CONSOLE_CURSOR_INFO STRUCT
dwSize DWORD ?
bVisible DWORD ?
CONSOLE_CURSOR_INFO ENDS

- SetConsoleTextAttribute

  • Sets the foreground and background colors of all subsequent text written to the console.
  • Prototype:
1
2
3
SetConsoleTextAttribute PROTO,
outHandle:DWORD,; console output handle
nColor:DWORD; color attribute

- WriteConsoleOutputAttribute

  • Copies an array of attribute values to consecutive cells of the console screen buffer, beginning at a specified location.
  • Prototype:
1
2
3
4
5
6
WriteConsoleOutputAttribute PROTO,
outHandle:DWORD,; output handle
pAttribute:PTR WORD,; write attributes
nLength:DWORD,; number of cells
xyCoord:COORD,; first cell coordinates
lpCount:PTR DWORD; number of cells written

- WriteConsoleOutputCharacter

  • Copy characters to consecutive cells of the console screen buffer, beginning at a specified location.
  • Prototype:
1
2
3
4
5
6
WriteConsoleOutputCharacter PROTO,
outHandle:DWORD,; output handle
ADDR pChar,; pointer to the character to be written
Width,; size of line
xyPosition,; coordinates of first char
ADDR count; output count

- Example : WriteColors Program

  • Creates an array of characters and an array of attributes, one for each character
  • Copies the attributes to the screen buffer
  • Copies the characters to the same screen buffer cells as the attributes
  • (starts in row 2, column 10)
WriteColors.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
INCLUDE Irvine32.inc
.data
outHandle HANDLE ?
cellsWritten DWORD ?
xyPos COORD <10,2>
; Array of character codes:
buffer BYTE 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
BYTE 16,17,18,19.20
BufSize DWORD ($ - buffer)
; Array of attributes:
attributes WORD 0Fh,0Eh,0Dh,0Ch,0Bh,0Ah,9,8,7,6
WORD 5,4,3,2,1,0F0h,0E0h,0D0h,0C0h,0B0h
.code
main PROC
; Get the Console standard output handle:
INVOKE GetStdHandle,STD_OUTPUT_HANDLE
mov outHandle,eax
; Set the colors from (10,2) to (30,2):
INVOKE WriteConsoleOutputAttribute,
outHandle, ADDR attributes,
BufSize, xyPos,
ADDR cellsWritten
; Write character codes 1 to 20:
INVOKE WriteConsoleOutputCharacter,
outHandle, ADDR buffer, BufSize,
xyPos, ADDR cellsWritten
call ReadChar
exit
main ENDP
END main

- GetLocalTime, SetLocalTime

  • GetLocalTime returns the date and current time of day, according to the system clock.
  • SetLocalTime sets the system’s local date and time.
1
2
3
4
5
GetLocalTime PROTO,
pSystemTime:PTR SYSTEMTIME
SetLocalTime PROTO,
pSystemTime:PTR SYSTEMTIME

- GetTickCount, Sleep

  • GetTickCountfunction returns the number of milliseconds that have elapsed since the system was started.
  • Sleep pauses the current program for a specified number of milliseconds.
1
2
3
4
GetTickCount PROTO; return value in EAX
Sleep PROTO,
dwMilliseconds:DWORD

- SYSTEMTIME Structure

  • SYSTEMTIME is used by date and time-related Windows API functions:
1
2
3
4
5
6
7
8
9
10
SYSTEMTIME STRUCT
wYear WORD ?; year (4 digits)
wMonth WORD ?; month (1-12)
wDayOfWeek WORD ?; day of week (0-6)
wDay WORD ?; day (1-31)
wHour WORD ?; hours (0-23)
wMinute WORD ?; minutes (0-59)
wSecond WORD ?; seconds (0-59)
wMilliseconds WORD ?; milliseconds (0-999)
SYSTEMTIME ENDS

- Example : Calculate Elapsed Time (Timer.asm)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
INCLUDE Irvine32.inc
INCLUDE macros.inc
.data
startTime DWORD ?
.code
main PROC
INVOKE GetTickCount ; get starting tick count
mov startTime,eax ; save it
; Create a useless calculation loop.
move cx,10000100h
L1:
imul ebx
imul ebx
imul ebx
Loop L1
INVOKE GetTickCount ; get new tick count
cmp eax,startTime ; lower than starting one?
jb error ; it wrapped around
sub eax,startTime ; get elapsed milliseconds
call WriteDec ; display it
mWrite <" milliseconds have elapsed",0dh,0ah>
jmp quit
error:
mWrite "Error: GetTickCount invalid--system has "
mWrite <"been active for more than 49.7 days",0dh,0ah>
quit:
exit
main ENDP
END main