Модуль драйвера клавиатуры, 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 flatstdcall
    Модуль клавиатурыстирающий экран консоли по нажатию клавиши "End"
    ;
     
    подключение файла определения константвнешних вызовов и библиотек
    include         const.inc
     
    сегмент данных
    _DATA           SEGMENT
     
    принимает кол-во записанных символов
    written     dd 0    
    хэндлер буфера ввода
    inputH          dword 
    ?
    хэндлер буфера вывода
    outputH         dword 
    ?
     
    текст заголовка консоли
    con_title       db 
    "Обработка клавиатуры",0
    резервные данные
    c0              dword 

    temp            dd ?
    пояснительный текст в консоли
    str1            db 
    "Для стирания экрана консоли - клавиша End",
    буфер кодов клавиш
    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
    +1204fh
                    je con_clean
                    
                    jmp loo
                    
                    
    очистка консоли
    con_clean
    :                
                    ; 
    получаем информацию о консоли в структуру consoleInfo
                    invoke GetConsoleScreenBufferInfo
    outputHADDR consoleInfo
                    
    обнуляем регистр eax
                    mov eax
    ,0
                    
    извлекаем из структуры информацию о ширине и высоте текущей консоли
                    mov ax
    consoleInfo.dwSize.x
                    mov cx
    consoleInfo.dwSize.y
                    
    перемножаем ширину и высоту консоли для получения общего числа ячеекрезультат в регистре eax
                    mul cx
                    
    сохраняем регистр eax в стекетак как он будет перезаписан вызовом следующей функции
                    push eax
                    
    заполняем консоль символом пробела с текущими атрибутами
                    invoke FillConsoleOutputCharacter
    outputH' 'eax0offset temp
                    
    восстанавливаем регистр eax с общим числом ячеек консоли
                    pop eax
                    
    обнуляем регистр ebx
                    mov ebx
    ,0
                    
    извлекаем из структуры два байта атрибутов текущей консоли
                    mov bx
    consoleInfo.wAttributes
                    
    меняем атрибуты ячеек консоли с хэндлером вывода outputHс атрибутом ebxкол-вом eaxначиная с 0,0
                    invoke FillConsoleOutputAttribute
    outputHebxeax0offset temp
                    
    устанавливаем позицию курсора вывода в консоль обратно на левый верхний угол
                    invoke SetConsoleCursorPosition
    outputH0
                    
    печатаем заново приглашение-подсказку
                    
    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 рублей кто сделает!