Изменение размеров буфера консольного окна
Привет! Это второй пост, который был потерян когда-то в июле в связи с переездом на другой хостинг.
Речь пойдёт о так называемом Screen Buffer.
Консольное окно само по себе имеет определенные размеры, обычно 24 на 80 символов.
Также справа есть полоса прокрутки, с помощью неё можно увидеть то, что вышло за рамки экрана, так как когда мы всё пишем и пишем, например с помощью процедуры writeln, доходим до строки номер 24 и пишем дальше, то всё сдвигается. Или когда с помощью api функции SetConsoleCursorPosition или через GotoXY из модуля crt для delphi ставим курсор на место, расположенное ниже досягаемого нами пространства.
Всё, что можно увидеть с помощью прокрутки, и есть Screen Buffer.
Чтобы поменять его размеры, нужно познакомиться с ним поближе.
Что нам о нём известно?
Его размеры можно получить с помощью api функции GetConsoleScreenBufferInfo, вот её синтаксис:
function GetConsoleScreenBufferInfo(hConsoleOutput: THandle; var lpConsoleScreenBufferInfo: TConsoleScreenBufferInfo): BOOL;
По порядку:
hConsoleOutput: THandle — handle вывода консольного окна, его нам вернёт api функция GetStdHandle с параметром STD_OUTPUT_HANDLE;
lpConsoleScreenBufferInfo: TConsoleScreenBufferInfo — сюда передаём объект типа TConsoleScreenBufferInfo
Структура CONSOLE_SCREEN_BUFFER_INFO, она же TConsoleScreenBufferInfo, она же _CONSOLE_SCREEN_BUFFER_INFO:
_CONSOLE_SCREEN_BUFFER_INFO = packed record dwSize: TCoord; dwCursorPosition: TCoord; wAttributes: Word; srWindow: TSmallRect; dwMaximumWindowSize: TCoord; end;
Функция GetConsoleScreenBufferInfo её нам заполнила, что мы получили:
dwSize: TCoord — размер буфера, вот он! (по умолчанию 80 на 300 символов)
dwCursorPosition: TCoord — положение курсора, тоже полезно, вполне заменит паскалевские WhereX и WhereY, они также реализованы в моём модуле crt
wAttributes: Word — не экспериментировал с этим, вроде цвета
srWindow: TSmallRect — тоже не экспериментировал, по msdn это координаты окна, уточни какого и напиши в комментарии, ок?
dwMaximumWindowSize: TCoord — максимальный размер буфера, в символах, естественно.
Меняем размер Screen Buffer
Ну и кульминация, функция SetConsoleScreenBufferSize:
SetConsoleScreenBufferSize(hConsoleOutput: THandle; dwSize: TCoord): BOOL;
Передаём тот же handle вывода, и структуру TCoord с нужным нам размером.
Как же без примера?
const NewSize: TCoord = (x: 80; y: 10000); ... SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), NewSize);
Здесь размер буфера окна стал 80 на 10000.
Постовой:
А тем временем Zdez Bil Ya в своём добром-добром блоге пишет про delphi и пароли в qip.
Эх помню писал когда-то на Delphi… но потом забил на кодинг и вообще считалось что Delphi скоро умрет. Ан нет — живее всех живых. Что не может не радовать.
Угу :) И сейчас идут холивары
А что думаешь по поводу изменения размеров буфера консольного окна? =D
Статья конечно ничего. Если бы не 2 НО.
1) В JCL есть прекрасный класс, инкапсулирующий работу с консолью
2) Само по себе изменение размера буфера собственно и не нужно, ну разве что для каких-то текстовых интерфейсов в стиле Turbo Vision. А для обычных программ с writeln обычного буфера хватает по уши.
1) Про JCL спасибо, нашел и посмотрел.
2) Но тем не менее этому нашлось применение :)
wAttributes — это цветовой атрибут, т.е. цвет символа плюс цвет фона. Для него в модуле windows.pas есть цветовые константы, с помощью которых легко составить свой цветовой атрибут, например:
wAttribute:=FOREGROUND_GREEN+BACKGROUND_BLUE //Зелёные буквы на синем фоне
Константами определены только цвета красный, зелёный, синий (RGB), остальные цвета составляются из комбинации этих самых RGB. :)
Спасибо, Вадим, так и думал, константы даже на слуху :)
Ну, в топ комментаторов не попаду :) Тема не та. Я в этом профан. А вот про автора хочется узнать поподробнее :)
Обязательно напишу :)
Руки еще не дошли, скоро обновлю страницу «Про автора» :)
Неплохой пример/перевод help’а win32, только есть риторический вопрос.
Зачем под Delphi Писать Консольное Приложение?
Просто интересно :)
Как по мне, так это удобно реализовать диалог с пользователем или поэтапный вывод информации.
А иногда, когда пишешь на коленке, не очень хочется заморачиваться с компонентами, хочется написать writeln и всё, но это другой случай :)
А если важен размер программы, то тут тоже выбор невелик — или на winapi делать форму, компоненты, или написать {$apptype console} и радоваться жизни
Если не секрет, зачем это надо?
Если подразумевается большой вывод в МОЕЙ программе — он идет в файл.
Если мне надо сохранить вывод ЧУЖОЙ программы — я его в файл перенаправляю.
Есть конкретный пример применения этой возможности?
Когда я копался с сокетами, я выводил ответ от сервера в консоль, а так как потом идёт html-код, то само тело ответа, которое перед ним, уходило в небытие. Конечно, я мог писать в файл, но так удобнее, так как и файл искать не нужно, и открывать лишний раз тоже.
А если глобально, то изначально я начал копать в эту сторону по просьбе одного человека, который делал то ли курсовую, то ли еще какую научную работу, в общем, требовалось вывести много строк. Кстати, по сравнению с TMemo это и быстрее и удобней.
Сразу видно большинство комментаторов очень юны. Все еще думают что есть только одно единственно-правильное решения — то что они используют, но как не обидно никто из нас не совершенство, да и путей решений редко бывает только одно единственное… Это так лирическое отступление.
Что касается буфера, помню обсуждали прошлой весной, по-моему. Я разрабатывал интерпретатор паскале-подобного языка. И нужно было выводить очень много статистической информации: результаты лексического и синтаксического анализов, кода виртуальной машины, результатов работы интерпретатора, хеш-таблицы переменных скрипта… И как понимаете стандартного размера буфера для этого не всегда хватает. Появилась необходимость увеличить размера буфера. Эта необходимость вылилась в беседу с crystalbit, а после в ту самую статью что вы только что прочитали.
Delphi вообще классная штука. Вот на пример приложение под ISAPI. http://dobrovestnik.ru
а вообще согласен с astako. У Вас все както по детски, не обижайтесь.
Учту, я не рассчитываю на статус серьёзного-серьёзного блога :)
Успешного развития Вашему проекту
а я не согласен, что всё по детски, блог мне нравится, очень толково написаны статьи, во всяком случае мне интересно(не все»серьёзные» блоги могут похвастаться таким интересом со стороны посетителей)