Модуль драйвера клавиатуры, cтирающий предыдущий символ при нажатии клавиш "win"

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by antojka, 4 Jan 2013.

  1. antojka

    antojka New Member

    Joined:
    19 Nov 2010
    Messages:
    18
    Likes Received:
    0
    Reputations:
    0
    Курсовая работа, задание следующее:

    Разработать модуль драйвера клавиатуры, работающий в реальном режиме (под DOS), выполняющий в соответствии с вариантом следующие действия:
    1. cтирающий предыдущий символ при нажатии клавиш "wn" (эти две буквы при этом на экран выводиться не должны
    2. издающий щелчок при вводе латинской буквы после буквы кириллицы.

    Вот листинг подобной программы:
    PHP:
    .486
    .model flat, stdcall
    ; Модуль клавиатуры, стирающий экран консоли по нажатию клавиши "End"
    ;
     
    ; 
    подключение файла определения констант, внешних вызовов и библиотек
    include         const.inc
     
    ; сегмент данных
    _DATA           SEGMENT
     
    ; принимает кол-во записанных символов
    written     dd 0    
    ; хэндлер буфера ввода
    inputH          dword 
    ?
    ; 
    хэндлер буфера вывода
    outputH         dword 
    ?
     
    ; 
    текст заголовка консоли
    con_title       db 
    "Обработка клавиатуры",0
    ; резервные данные
    c0              dword 
    ? 
    temp            dd ?
    ; 
    пояснительный текст в консоли
    str1            db 
    "Для стирания экрана консоли - клавиша End",0 
    ; буфер кодов клавиш
    keyboard_key    word 9 dup
    (0)   
    ; 
    клавиша "ENTER"
    key_ent1        db 00h              
    ; структура информации о консоли
    ; ее описание хранится в подключаемом файле windows.inc
    ; CONSOLE_SCREEN_BUFFER_INFO STRUCT
      
    ; dwSize                COORD <>
      ; 
    dwCursorPosition      COORD <>
      ; 
    wAttributes           WORD      ?
      ; 
    srWindow              SMALL_RECT <>
      ; 
    dwMaximumWindowSize   COORD <>
    ; 
    CONSOLE_SCREEN_BUFFER_INFO ENDS
     
    consoleInfo     CONSOLE_SCREEN_BUFFER_INFO 
    <>
    _DATA           ENDS
     
    ;сегмент кода
    _TEXT           SEGMENT
     
    start
    :
     
                    ; 
    освободить уже существующую консоль
                    call FreeConsole
    @0
                    
    ; создать консоль
                    call AllocConsole
    @0
                    
    ;получить хэндлер ввода
                    push STD_INPUT_HANDLE
                    call GetStdHandle
    @4
                    mov inputH
    ,eax
               
                    
    ;получить хэндлер вывода
                    push STD_OUTPUT_HANDLE
                    call GetStdHandle
    @4
                    mov outputH
    ,eax
     
                    
    ;задать заголовок окна консоли
                    push offset con_title
                    push offset con_title
                    call CharToOemA
    @8
                    push offset con_title
                    call SetConsoleTitleA
    @4
                    
    ;******************************
                    ;
    перекодировка строки
                    push offset str1
                    push offset str1
                    call CharToOemA
    @8
                    
    ;вывести верхнюю строку 
                    
    print offset str1,13,10
     
                    
    ; обработка нажатий клавиш
    loo
    :
                    ; 
    прочитать одну запись о событии
                    push offset c0
                    push 1
                    push offset keyboard_key
                    push inputH
                    call ReadConsoleInputA
    @16
                    
    ; нет ли события от клавиатуры?
                    
    cmp word ptr keyboard_key,KEY_EV
                    jne loo
                    
    ; нажата или отпущена?
                    
    cmp byte ptr keyboard_key+4,1
                    jne loo
                    
    ; вывести символ
                    push 0
                    push offset written
                    push 1
                    push offset byte ptr keyboard_key
    +14
                    push outputH
                    call WriteConsoleA
    @20
                    
    ; ENTER
                    cmp byte ptr keyboard_key
    +14,0Dh
                    je ent
                    
    ; клавиша ESC
                    cmp byte ptr keyboard_key
    +14,27
                    je exit_program
                    
    ; клавиша End
                    cmp byte ptr keyboard_key
    +12, 04fh
                    je con_clean
                    
                    jmp loo
                    
                    
    ; очистка консоли
    con_clean
    :                
                    ; 
    получаем информацию о консоли в структуру consoleInfo
                    invoke GetConsoleScreenBufferInfo
    , outputH, ADDR consoleInfo
                    
    ; обнуляем регистр eax
                    mov eax
    ,0
                    
    ; извлекаем из структуры информацию о ширине и высоте текущей консоли
                    mov ax
    , consoleInfo.dwSize.x
                    mov cx
    , consoleInfo.dwSize.y
                    
    ; перемножаем ширину и высоту консоли для получения общего числа ячеек, результат в регистре eax
                    mul cx
                    
    ; сохраняем регистр eax в стеке, так как он будет перезаписан вызовом следующей функции
                    push eax
                    
    ; заполняем консоль символом пробела с текущими атрибутами
                    invoke FillConsoleOutputCharacter
    , outputH, ' ', eax, 0, offset temp
                    
    ; восстанавливаем регистр eax с общим числом ячеек консоли
                    pop eax
                    
    ; обнуляем регистр ebx
                    mov ebx
    ,0
                    
    ; извлекаем из структуры два байта атрибутов текущей консоли
                    mov bx
    , consoleInfo.wAttributes
                    
    ; меняем атрибуты ячеек консоли с хэндлером вывода outputH, с атрибутом ebx, кол-вом eax, начиная с 0,0
                    invoke FillConsoleOutputAttribute
    , outputH, ebx, eax, 0, offset temp
                    
    ; устанавливаем позицию курсора вывода в консоль обратно на левый верхний угол
                    invoke SetConsoleCursorPosition
    , outputH, 0
                    
    ; печатаем заново приглашение-подсказку
                    
    print offset str1,13,10
                    
    ; возвратиться к обработке клавиатурного ввода
                    jmp loo
                    
    ; обработка ENTER
    ent
    :
                    ; 
    выводим управляющие символы LF(подача каретки) и CR(перевод строки)
                    print 
    offset key_ent1,10,13
                    jmp loo
     
    exit_program
    :
                    ; 
    закрыть консоль
                    call FreeConsole
    @0
                    
    ; завершить текущий процесс
                    invoke ExitProcess
    , 0
    _TEXT           ENDS
                    end start
    Заплачу 300 рублей кто сделает!