
SetConsoleTextAttribute
Установить цвет выводимых букв можно с помощью функции SetConsoleTextAttribute. Первым параметром этой функции является дескриптор выходного буфера консоли, а вторым - цвет букв и фона. Цвет получается путем комбинации (сумма или операция "ИЛИ") двух или более из представленных ниже констант. Причем возможна "смесь" не только цвета и интенсивности, но и цветов (см. программа ниже).
FOREGROUND_BLUE equ 1h; синий цвет букв FOREGROUND_GREEN equ 2h; зеленый цвет букв FOREGROUND_RED equ 4h; красный цвет букв FOREGROUND_INTENSITY equ 8h; повышенная интенсивность BACKGROUND_BLUE equ 10h; синий свет фона BACKGROUND_GREEN equ 20h; зеленый цвет фонаBACKGROUND_RED equ 40h; красный цвет фона BACKGROUND_INTENSITY equ 80h ; повышенная интенсивность
SetConsoleScreenBufferSize
Функция SetConsoleScreenBufferSize устанавливает размер буфера окна консоли. Этот размер не может уменьшить уже существующий буфер (существующее окно), а может только его увеличить.
1-й, дескриптор входного буфера консоли.
2-й, структура COORD:
COORD STRUC
Х WORD ?
Y WORD ?
COORD ENDS
Заключение
В ходе выполнения курсовой работы были изучены функции Microsoft API для работы с консольными приложениями. Также я ознакомился со средой разработки masm32 V10. Была написана консольная программа с аппаратным вводом от мыши и клавиатуры, обработка сигналов от которых производилась по средствам API функций.
Список используемой литературы
Изучение операционной системы WINDOWS: метод. указания для выполнения курсовой работы по курсу «Операционные системы» / сост. Е. А. Вахрушева. – Ижевск: ИжГТУ, кафедра «Вычислительная техника», 2013. – 55 с.
Пирогов В. Ю. Ассемблер для Windows. — СПб.: - Петербург, 2002 г.
Пирогов В. Ю. Ассемблер. Учебный курс. — СПб.: БХВ-Петербург, 2003 г.
Приложение
Листинг программы
.386P
; плоская модель
.MODEL FLAT, stdcall
; константы
STD_OUTPUT_HANDLE equ -11
STD_INPUT_HANDLE equ -10
; тип события
KEY_EV equ 1h
MOUSE_EV equ 2h
; константы - состояния клавиатуры
RIGHT_ALT_PRESSED equ 1h
LEFT_ALT_PRESSED equ 2h
RIGHT_CTRL_PRESSED equ 4h
LEFT_CTRL_PRESSED equ 8h
SHIFT_PRESSED equ 10h
NUMLOCK_ON equ 20h
SCROLLLOCK_ON equ 40h
CAPSLOCK_ON equ 80h
ENHANCED_KEY equ 100h
; прототипы внешних процедур
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 SetConsoleTextAttribute@8:NEAR
EXTERN ReadConsoleInputA@16:NEAR
EXTERN SetConsoleScreenBufferSize@8:NEAR
EXTERN ExitProcess@4:NEAR
; директивы компоновщику для подключения библиотек
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
;-------------------------------------------------
; структура для определения событий
COOR STRUC
X WORD ?
Y WORD ?
COOR ENDS
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
HANDL DWORD ?
HANDL1 DWORD ?
TITL DB "Обработка событий мыши",0
BUF DB 200 dup (?)
LENS DWORD ? ; количество выведенных символов
C0 DWORD ?
FORM1 DB "%c",0
FORM DB "Координаты: %u %u ",0
CRD COOR <?>
STR_EXIT DB "Для выхода нажмите ESC",10,13,0
STR_CHERTA DB "______________________________",10,13,0
STR_PEN DB "*"
STR_PEN0 DB " "
STR_PEN_INDIKATOR DB "Перо: ",10,13,0
MOUS_KEY WORD 9 dup (?)
_DATA ENDS
; сегмент кода
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
START:
; образовать консоль
; вначале освободить уже существующую
CALL FreeConsole@0
CALL AllocConsole@0
; получить HANDL1 ввода
PUSH STD_INPUT_HANDLE
CALL GetStdHandle@4
MOV HANDL1,EAX
; получить HANDL вывода
PUSH STD_OUTPUT_HANDLE
CALL GetStdHandle@4
MOV HANDL,EAX
; установить новый размер окна консоли
MOV CRD.X, 80
MOV CRD.Y, 25
PUSH CRD
PUSH EAX
CALL SetConsoleScreenBufferSize@8
; перекодировка строки
PUSH OFFSET TITL
PUSH OFFSET TITL
CALL CharToOemA@8
; задать заголовок окна консоли
PUSH OFFSET TITL
CALL SetConsoleTitleA@4
;**********************************
; перекодировка строки
PUSH OFFSET STR_EXIT
PUSH OFFSET STR_EXIT
CALL CharToOemA@8
; длина строки
PUSH OFFSET STR_EXIT
CALL LENSTR
; вывести строку
PUSH 0
PUSH OFFSET LENS
PUSH EBX
PUSH OFFSET STR_EXIT
PUSH HANDL
CALL WriteConsoleA@20
; вывести индикатор пера
PUSH OFFSET STR_PEN_INDIKATOR
PUSH OFFSET STR_PEN_INDIKATOR
CALL CharToOemA@8
PUSH OFFSET STR_PEN_INDIKATOR
CALL LENSTR
PUSH 0
PUSH OFFSET LENS
PUSH EBX
PUSH OFFSET STR_PEN_INDIKATOR
PUSH HANDL
CALL WriteConsoleA@20
; вывести разделители
PUSH 0
PUSH OFFSET LENS
PUSH 30
PUSH OFFSET STR_CHERTA
PUSH HANDL
CALL WriteConsoleA@20
MOV CRD.X,0
MOV CRD.Y,23
PUSH CRD
PUSH HANDL
CALL SetConsoleCursorPosition@8
PUSH 0
PUSH OFFSET LENS
PUSH 30
PUSH OFFSET STR_CHERTA
PUSH HANDL
CALL WriteConsoleA@20
; цикл ожиданий: движение мыши или двойной щелчок
L00:
; прочитать одну запись о событии
PUSH OFFSET C0
PUSH 1
PUSH OFFSET MOUS_KEY
PUSH HANDL1
CALL ReadConsoleInputA@16
; проверим, не с мышью ли что?
CMP WORD PTR MOUS_KEY, MOUSE_EV
JNE L001
; есть, какое?
CMP BYTE PTR MOUS_KEY+8, 1h ;нажата левая кнопка
JE L03
CMP BYTE PTR MOUS_KEY+8, 2h ;нажата правая кнопка
JNE L02
L03:
MOV AX, WORD PTR MOUS_KEY+6
CMP AX,3
JLE L02
CMP AX,23
JGE L02
MOV CRD.Y, AX
MOV AX, WORD PTR MOUS_KEY+4
MOV CRD.X, AX
PUSH CRD
PUSH HANDL
CALL SetConsoleCursorPosition@8
PUSH 0
PUSH OFFSET LENS
PUSH 1
CMP BYTE PTR MOUS_KEY+8, 1h ;нажата левая кнопка
JNE L04
PUSH OFFSET STR_PEN
JMP L05
L04:
PUSH OFFSET STR_PEN0
L05:
PUSH HANDL
CALL WriteConsoleA@20
L02:
; координаты курсора
MOV CRD.X,0
MOV CRD.Y,24
PUSH CRD
PUSH HANDL
CALL SetConsoleCursorPosition@8
; здесь преобразуем координаты мыши в строку
MOV AX, WORD PTR MOUS_KEY+6 ; Y-мышь
; копирование с обнулением старших битов
MOVZX EAX,AX
PUSH EAX
MOV AX, WORD PTR MOUS_KEY+4 ; Х-мышь
; копирование с обнулением старших битов
MOVZX EAX,AX
PUSH EAX
PUSH OFFSET FORM
PUSH OFFSET BUF
CALL wsprintfA
; восстановить стек
ADD ESP,16
; перекодировать строку для вывода
PUSH OFFSET BUF
PUSH OFFSET BUF
CALL CharToOemA@8
; длина строки
PUSH OFFSET BUF
CALL LENSTR
; вывести на экран координаты курсора
PUSH 0
PUSH OFFSET LENS
PUSH EBX
PUSH OFFSET BUF
PUSH HANDL
CALL WriteConsoleA@20
JMP L00 ; к началу цикла
L001:
; нет ли события от клавиатуры?
CMP WORD PTR MOUS_KEY,KEY_EV
JNE L00
; есть, какое?
CMP BYTE PTR MOUS_KEY+14,27
JE L_EXIT
;замена пера
MOV ECX, DWORD PTR MOUS_KEY+14
PUSH ECX
PUSH OFFSET FORM1
PUSH OFFSET STR_PEN
CALL wsprintfA
PUSH OFFSET STR_PEN
PUSH OFFSET STR_PEN
CALL CharToOemA@8
;вывод индикатора пера
MOV CRD.Y, 1
MOV CRD.X, 6
PUSH CRD
PUSH HANDL
CALL SetConsoleCursorPosition@8
PUSH 0
PUSH OFFSET LENS
PUSH 1
PUSH OFFSET STR_PEN
PUSH HANDL
CALL WriteConsoleA@20
JMP L00
;********************************
L_EXIT:
; закрыть консоль
CALL FreeConsole@0
PUSH 0
CALL ExitProcess@4
RET
; процедура определения длины строки
; строка - [EBP+08Н]
; длина в EBX
LENSTR PROC
ENTER 0,0
PUSH EAX
CLD
MOV EDI, DWORD PTR [EBP+08H]
MOV EBX, EDI
MOV ECX, 100 ; ограничить длину строки
XOR AL,AL
REPNE SCASB ; найти символ 0
SUB EDI, EBX ; длина строки, включая 0
MOV EBX, EDI
DEC EBX
POP EAX
LEAVE
RET 4
LENSTR ENDP
_TEXT ENDS
END START