DWORD len, DWORD* actlen).

Кроме хэндла для указания консольного буфера ввода (в частности хэндла стандартного файла ввода) эта функция содержит адрес буфера, который представляет собой в общем случае массив записей типа INPUT_RECORD для размещения некоторого числа записей сообщений ввода. Размер массива выбирается программистом. Размер этого массива записей задается при вызове в параметре len. В простейших случаях массив buffer состоит из единственного элемента – для размещения единственного очередного сообщения, а параметр len берется поэтому равным 1. В общем случае, когда при вызове функции задается значение len, не равное 1, следует в программе после обращения к ReadConsoleInputA проверять, сколько записей о вводе было действительно получено (с помощью параметра actlen ). И принимать соответствующие действия с учетом этого фактического значения. Заметим, что функция возвращает управление в вызвавшую ее программу только после появления сообщения о вводе. До этого момента вычислительный процесс выполнения программы, содержащей такую функцию, приостановлен (блокирован).

Следующий пример демонстрирует применение функции ввода символа с клавиатуры

#include <windows.h>

#include <stdio.h>

void main()

{char prompt[]="Input any character:";

char text[]="\nInputing";

INPUT_RECORD charinfo;

DWORD actlen;

HANDLE hstdout,hstdin;

hstdout=GetStdHandle(STD_OUTPUT_HANDLE);

if(hstdout==INVALID_HANDLE_VALUE)

{printf("Error GetStdHandle\n");exit(-1);}

hstdin=GetStdHandle(STD_INPUT_HANDLE);

if(hstdin==INVALID_HANDLE_VALUE)

{printf("Error GetStdHandle\n");exit(-1);}

WriteConsoleA(hstdout,prompt,sizeof(prompt),&actlen,NULL);

do

{ReadConsoleInput(hstdin,&charinfo,1,&actlen);}

while(charinfo.EventType!=KEY_EVENT);

text[10]=charinfo.Event.KeyEvent.uChar.AsciiChar;

WriteConsoleA(hstdout,text,11,&actlen,NULL);

getchar();

CloseHandle(hstdout);

ExitProcess(0);

}

Если на нажатие клавиши появляются два символа, то это связано с автоматическим воспроизведением «эха» нажатой клавиши. Использование эха нажимаемой клавиши – стандартный прием, в большинстве ситуаций очень удобный и наглядный. Отказываться от него целесообразно достаточно редко, например во время ввода паролей. Но принципиально такую возможность надо иметь. Режим отображения эха символа задается для всей консоли и для его изменения служит функция SetConsoleMode с прототипом

BOOL SetConsoleMode(HANDLE hConsHandle, DWORD mode);

Параметр mode задает в ней новый режим управления вводом. Возможные режимы для буфера ввода с консоли задаются символическими константами ENABLE_PROCESSED_INPUT, ENABLE_LINE_INPUT, ENABLE_ECHO_INPUT, ENABLE_WINDOW_INPUT, ENABLE_MOUSE_INPUT. Отключив режим ENABLE_ECHO_INPUT, мы откажемся от использования эха символов, но следует это делать временно – с последующим восстановлением стандартного режима. Поэтому вначале целесообразно запомнить предыдущее значение режима для буфера консоли. Для этого действия предназначена функция

BOOL GetConsoleMode(HANDLE hConsHandle, DWORD* pmode),

в которой возвращаемое значение текущего режима передается через второй параметр ее вызова.

Применение изложенных возможностей демонстрируется следующим примером

#include <windows.h>

#include <stdio.h>

void main()

{char prompt[]="Input any character:";

char text[]="\nInputing:";

INPUT_RECORD charinfo;

DWORD actlen,fdwMode,fdwSaveOldMode;

HANDLE hstdout,hstdin;

hstdout=GetStdHandle(STD_OUTPUT_HANDLE);

if(hstdout==INVALID_HANDLE_VALUE)

{printf("Error GetStdHandle\n");exit(-1);}

hstdin=GetStdHandle(STD_INPUT_HANDLE);

if(hstdin==INVALID_HANDLE_VALUE)

{printf("Error GetStdHandle\n");exit(-1);}

WriteConsoleA(hstdout,prompt,sizeof(prompt),&actlen,NULL);

if(!GetConsoleMode(hstdin,&fdwSaveOldMode))

{printf("ErrorGetConsoleMode\n");exit(-1);}

fdwMode=fdwSaveOldMode&~ENABLE_MOUSE_INPUT&~ENABLE_ECHO_INPUT;

if(!SetConsoleMode(hstdin,fdwMode))

{printf("ErrorSetConsoleMode\n");exit(-1);}

printf("Input\n");

ReadConsoleInput(hstdin,&charinfo,1,&actlen);

printf("type=%d\n",charinfo.EventType);

text[10]=charinfo.Event.KeyEvent.uChar.AsciiChar;

WriteConsoleA(hstdout,text,11,&actlen,NULL);

getchar();

if(SetConsoleMode(hstdin,fdwSaveOldMode))

{printf("\nRestored ConsoleMode");}

getchar();

CloseHandle(hstdout);

ExitProcess(0);

}

Задание на лабораторную работу:

1. изучить системные функции ввода для консольных устройств MS Windows.

2. составить программу с использованием изученных функций по указанию преподавателя.

 

 

Лабораторная работа № 5