Низькорівневі функції вводу

Лабораторна робота № 1

(4 години)

Тема: Консольні Win32-програми для Windows.

Мета: Ознайомитися із принципами і засобами створення консольних програм для Windows. Навчитися використовувати функції Win32 API для роботи з консоллю.

Короткі теоретичні відомості

Створення консолі

Microsoft Windows створює нову консоль, коли вона запускає процес символьного режиму. Наприклад, Windows створює нову консоль, коли вона запускає командний процесор cmd.exe. Коли командний процесор запускає новий процес консолі, користувач може визначити чи система створює нову консоль для нового процесу чи вона успадковує консоль командного процесора.

Якщо запустити консольний додаток із командного рядка, то додаток використовує "чужу" консоль. Для створення своєї консолі потрібно від'єднатися від чужої консолі і створити свою. Для цього використовуються наступні функції:

BOOL FreeConsole(VOID) - від'єднує процес від консолі.

BOOL AllocConsole(VOID) - виділяє нову консоль для процесу.

 

Для роботи із консоллю потрібно одержати дескриптор консолі:

HANDLE GetStdHandle(DWORD nStdHandle);

де nStdHandle визначає пристрій, для якого одержують дескриптор:

STD_INPUT_HANDLE (-10) Стандартний пристрій вводу

STD_OUTPUT_HANDLE (-11) Стандартний пристрій виводу

STD_ERROR_HANDLE (-12) Стандартний пристрій помилок

 

Наприклад: hStdIn = GetStdHandle(STD_INPUT_HANDLE);

hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

 

Після цього усі операції із консоллю здійснюються через її дескриптор. Якщо функція завершується фатально, то вона повертає значення INVALID_HANDLE_VALUE.

Настройка консолі

Для настройки параметрів консолі використовують такі функції:

 

Функція API Коментарі
DWORD GetConsoleTitle( LPTSTR lpConsoleTitle, DWORD nSize); Одержати заголовок вікна консолі адреса буфера розмір буфера
BOOL SetConsoleTitle( LPCTSTR lpConsoleTitle); Встановити заголовок вікна консолі адреса нового заголовка
BOOL SetConsoleMode( HANDLE hConsoleHandle, DWORD dwMode); Встановити режим консолі дескриптор вхідного або екранного буфера вхідний або вихідний режим
BOOL SetConsoleCursorPosition( HANDLE hConsoleOutput, COORD dwCursorPosition); Встановити нові координати курсору дескриптор екранного буфера нові координати курсору
BOOL SetConsoleTextAttribute( HANDLE hConsoleOutput, WORD wAttributes); Встановити атрибути тексту консолі дескриптор екранного буфера кольори тексту і фону

Закрити консоль можна за допомогою функції FreeConsole. Якщо інші процеси підключені до консолі, вона зберігається. Коли останній процес від'єднується від консолі, вона закривається.

Функції для роботи з консоллю

Функції Win32 API допускають два рівні доступу до консолі: високорівневий і низькорівневий.

Високорівневі вхідні функції фільтрують вміст вхідного буфера і повертають лише потік символів з клавіатури, відкидаючи службову інформацію та інші події.

Високорівневі функції виведення записують потік символів у буфер екрану, які відображаються в поточному розташуванні курсора.

Високорівневі функції також підтримують перепризначення стандартних дескрипторів і керують режимами консолі.

Повний перелік функцій для роботи з консоллю можна знайти в довідковій системі Microsoft Win32 Programmer's Reference у розділі Consoles and Character-Mode Support ® Console Functions.

Високорівневі функції

Програма може використовувати файлові функції вводу/виводу ReadFile і WriteFile, ф також спеціалізовані консольні функції ReadConsole і WriteConsole, для високорівневого I/O, який надає непрямий доступ до вхідного і екранного буферів.

 

BOOL ReadConsole(

HANDLE hConsoleInput, // дескриптор вхідного буфера консолі

LPVOID lpBuffer, // адреса буфера прийому даних

DWORD nNumberOfCharsToRead, // кількість символів для читання

LPDWORD lpNumberOfCharsRead, // адреса числа прочитаних символів

LPVOID lpReserved ); // зарезервовано, завжди NULL

BOOLWriteConsole(

HANDLE hConsoleOutput, // дескриптор екранного буфера консолі

CONST VOID *lpBuffer, // адреса буфера даних для виводу

DWORD nNumberOfCharsToWrite, // кількість символів для запису

LPDWORD lpNumberOfCharsWritten, // вказівник числа прочитаних символів

LPVOID lpReserved); // зарезервовано, завжди NULL

Функції ReadConsole, WriteConsole оперують з текстовими рядками. При підготовці текстових рядків для цих функцій корисною може бути функція Win API wsprintf.

Ця функція призначена для форматованого виведення послідовності символів і значень у текстовий буфер. Дія функції схожа на функцію printf, але вона виводить не на екран, а в текстовий буфер. Функція автоматично додає кінцевий нуль, хоча він не входить у число виведених символів, яке повертає функція по завершенні своєї роботи.

 

Параметри

lpOut вказівник на буфер для прийому символів.

lpFmt вказівник на рядок форматування із кінцевим нулем.

Після цього йдуть значення, тип і кількість яких відповідає рядку форматування.

Функція повертає кількість виведених у буфер символів (за винятком кінцевого нуля).

Низькорівневі функції

Низькорівневі функції вводу забезпечують прямий доступ до вхідного буфера і дають можливість додаткам отримувати детальні дані про події клавіатури і миші, а також про події, що визначають взаємодію користувача із вікном консолі.

Низькорівневі функції виводу дають можливість додатку читати або записувати певну послідовність комірок символів у буфер екрану.

Високорівневі і низькорівневі методи I/O не взаємовиключні, і програма може використовувати будь-яку комбінацію цих функцій. Проте, зазвичай прикладні програми використовують або один підхід або інший.

 

Низькорівневі функції вводу

Win32 API надає п'ять низькорівневих функцій для доступу до вхідного буфера консолі:

ReadConsoleInput Читає і видаляє записи із вхідного буфера. Функція не повертається, поки є хоча б один запис, доступний для читання. Прочитані записи переміщаються в буфер викликаючого процесу. Непрочитані записи залишаються у вхідному буфері для наступної операції читання даних. Функція повідомляє загальне число записів, які були прочитані.
PeekConsoleInput Читає вхідні записи без видалення із вхідного буфера. Якщо жоден запис недоступний, функція повертається негайно. Функція повідомляє загальне число записів, які були прочитані.
GetNumberOfConsole­InputEvents Визначає число непрочитаних вхідних записів у вхідному буфері.
WriteConsoleInput Розміщує записи у вхідному буфері позаду наявних записів. Вхідний буфер зростає динамічно, якщо необхідно утримувати додаткові вхідні записи.
FlushConsoleInputBuffer Відкидає всі непрочитані події у вхідному буфері (очищає буфер).