Кроме хэндла для указания консольного буфера ввода (в частности хэндла стандартного файла ввода) эта функция содержит адрес буфера, который представляет собой в общем случае массив записей типа 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