С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.93
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
#1

Экранный буфер консоли, где я ошибаюсь? - C++

24.01.2011, 18:00. Просмотров 1952. Ответов 3
Метки нет (Все метки)

Вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <windows.h>
#include <iostream>
using namespace std;
 
HANDLE hStdin, hStdout,hNewScreenBuffer;//буфер экрана становится активным в конце InitSettings
COORD max_size_buffer;
SMALL_RECT srctWindow;
 
int InitSettings();
int ShowBackBuffer();
 
int main()
{    
    InitSettings();//выполняем инициализацию игровой консоли
    cout<<"------------ end InitSettings--------------"<<endl;
 
    cout<<"hStdout - "<<hStdout<<endl;
    cout<<"hNewScreenBuffer - "<<hNewScreenBuffer<<endl;
    getchar();    
    
    ShowBackBuffer();
    cout<<"----------------  end ferst ShowBackBuffer  --------------"<<endl<<endl;
    cout<<"----------------  To continue, click ENTER  --------- "<<endl;    
    getchar();
    return 0;
}//end main
 
//-----InitSettings----------------------------------------------------------------------------------------------------------------
int InitSettings()
{        
    if(!SetConsoleTitle("ASCII Paint"))    //установить заголовок
    {MessageBox(NULL, "ERROR in SetConsoleTitle", "Console Error", MB_OK); return 0;}
 
    hStdin = GetStdHandle(STD_INPUT_HANDLE);
    if (hStdin == INVALID_HANDLE_VALUE)
    {MessageBox(NULL, "ERROR in GetStdHandle STD_INPUT_HANDLE", "Console Error", MB_OK);  return 0;}
 
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hStdout == INVALID_HANDLE_VALUE)
    {MessageBox(NULL, "ERROR in GetStdHandle STD_OUTPUT_HANDLE", "Console Error", MB_OK); return 0;}    
 
    //новый экранный буфер
    hNewScreenBuffer = CreateConsoleScreenBuffer(  GENERIC_READ |               // доступ к чтению/записи
                                                   GENERIC_WRITE,
                                                   0,                           // совместно не используется
                                                   NULL,                        // атрибутов защиты нет
                                                   CONSOLE_TEXTMODE_BUFFER,       // должен быть TEXTMODE
                                                   NULL);                       // зарезервирован, должен быть NULL 
    if (hStdout == INVALID_HANDLE_VALUE || hNewScreenBuffer == INVALID_HANDLE_VALUE)
    {MessageBox(NULL, "ERROR in hNewScreenBuffer == INVALID_HANDLE_VALUE", "Console Error", MB_OK); return 0;}
    
    max_size_buffer = GetLargestConsoleWindowSize(hStdout);        // Получает размер самого большого возможного консольного окна
    srctWindow.Top = 0;
    srctWindow.Left = 0;
    srctWindow.Right = max_size_buffer.X-1;
    srctWindow.Bottom = max_size_buffer.Y-1;
 
    // изменяем размеры буферов консоли 
    if(!SetConsoleScreenBufferSize(hStdout, max_size_buffer))
        {MessageBox(NULL, "ERROR in SetConsoleScreenBufferSize hStdout", "Console Error", MB_OK); return 0;}
    if(!SetConsoleScreenBufferSize(hNewScreenBuffer, max_size_buffer))
        {MessageBox(NULL, "ERROR in SetConsoleScreenBufferSize hNewScreenBuffer", "Console Error", MB_OK); return 0;}
 
    //Устанавливаем текущий размер и позицию окна экранного буфера консоли
    if (! SetConsoleWindowInfo( hStdout,    // дескриптор экранного буфера
                                TRUE,                // Если TRUE, координаты устанавливают новые левый верхний и нижний правый углы окна. 
                                                    // Если FALSE, координаты являются смещениями текущих координат угла окна
                                &srctWindow))        // зададим новое место
    {MessageBox(NULL, "ERROR in SetConsoleWindowInfo", "Console Error", MB_OK); return 0;}
    //Первый вопрос, почему в этом месте окно еще неизменилось?
 
    cout<<"max_size_buffer.X - "<<max_size_buffer.X<<endl;    
    cout<<"max_size_buffer.Y - "<<max_size_buffer.Y<<endl;
    cout<<"hStdout - "<<hStdout<<endl;
    cout<<"hNewScreenBuffer - "<<hNewScreenBuffer<<endl;
    cout<<endl<<"----------------  To continue, click ENTER  --------- "<<endl;
        
    getchar();    //первая остановка
 
    //Сделаем новый экранный буфер активным экранным буфером.
    if (! SetConsoleActiveScreenBuffer(hNewScreenBuffer) )
    {MessageBox(NULL, "ERROR in SetConsoleActiveScreenBuffer(hNewScreenBuffer)", "Console Error", MB_OK); return 0;}
 
    //Устанавливаем текущий размер и позицию окна экранного буфера консоли
    if (! SetConsoleWindowInfo( hNewScreenBuffer,    // дескриптор экранного буфера
                                TRUE,                // Если TRUE, координаты устанавливают новые левый верхний и нижний правый углы окна. 
                                                    // Если FALSE, координаты являются смещениями текущих координат угла окна
                                &srctWindow))        // зададим новое место
    {MessageBox(NULL, "ERROR in SetConsoleWindowInfo", "Console Error", MB_OK); return 0;}
    
    return 0;
}//END----InitSettings-------------------------------------------------------------------------------------------------------------
 
int ShowBackBuffer()
{
    CHAR_INFO chiBuffer[50000];
    COORD coordBufSize = {max_size_buffer.X, max_size_buffer.Y};
    COORD coordBufCoord = {0,0};    
 
    // Установим прямоугольник источника.
    SMALL_RECT srctReadRect = {0, 0, max_size_buffer.X-100, max_size_buffer.Y-2};
    
    //А если делать так 
    //SMALL_RECT srctReadRect = {0, 0, max_size_buffer.X-1, max_size_buffer.Y-1};
    //то выдает ошибку, почему?
 
    // Скопируем блок из экранного буфера во временный буфер.
    if(!ReadConsoleOutput(
       hStdout,            // экранный буфер, из которого читаем
       chiBuffer,          // буфер, в который копируем
       coordBufSize ,   // размер буфера в сроках колонок
       coordBufCoord,      // верхняя левая ячейка назначения в chiBuffer
       &srctReadRect))     // источниковый прямоугольник экранного буфера
 
       {MessageBox(NULL, "ERROR in ReadConsoleOutput", "Console Error", MB_OK); return 0;}
 
    
    // Установим прямоугольник назначения.
    SMALL_RECT srctWriteRect = {0, 0, max_size_buffer.X-1, max_size_buffer.Y-1};
 
    // Копируем из временного буфера в новый экранный буфер.
    if(!WriteConsoleOutput( 
                            hNewScreenBuffer,     // экранный буфер, в который будем записывать
                            chiBuffer,            // буфер, из которого копируем
                            coordBufSize,   // размер колонки/строки hStdin
                            coordBufCoord,  // верхняя левая ячейка источника в hStdin
                            &srctWriteRect))      // прямоугольник назначения экранного буфера
    {MessageBox(NULL, "ERROR in WriteConsoleOutput", "Console Error", MB_OK); return 0;}
    return 0;
}


Программа работает, но не так как я хочу
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.01.2011, 18:00
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Экранный буфер консоли, где я ошибаюсь? (C++):

Клавиши F1-F12 в консоли, и работа с мышкой в консоли - C++
Я искал на сайте, но не нашел упоминания о том как обрабатывать и или узнавать где находится курсор мышки (и еще мне надо бы узнать нажатие...

считывание с консоли ( не с клавы, а именно с консоли) - C++
нужно написать функцию которая возвращает string в котором написано 500 символов которые были выведены в консоли от начала. среда :...

Где гарантии, что send передаст большой буфер целиком? - C++
Еще такой нюанс: если у меня буфер занимает пару мегабайт и я отправляю его не несколькими а одним вызовом send() то есть риск, что данные...

Поправьте где ошибаюсь - C#
Добрый день/вечер! Не могу понять в чем проблема, подскажите как решить using MySql.Data.MySqlClient; private DataTable...

Сессии. Где я ошибаюсь? - PHP
Начал разбираться с сессиями, кукисами. Планируется сделать 3 защищённых страницы, получается обрывочно. Вот файлы: index.php - для...

Подскажите, где в скрипте регистрационной формы я ошибаюсь! - PHP
Значит так. Имеется 3 файла: Это сама форма, которую я соответственно вставила в свою страницу: &lt;table&gt; &lt;form action=&quot;reg.php&quot;...

3
Andrew_Lvov
Эксперт С++
259 / 189 / 5
Регистрация: 19.08.2010
Сообщений: 760
Записей в блоге: 1
26.01.2011, 08:57 #2
Какой ожидаемый результат ?
Какой полученный результат ?
0
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
26.01.2011, 15:14  [ТС] #3
Да нужно было действительно описать проблему конкретнее а потом предоставить код. А то никто не отвечает.

Код строка 71 //Первый вопрос, почему в этом месте окно еще неизменилось?

У меня в программе вставлено несколько getchar(); //остановка. При первой остановке окно должно былобы увеличится по максимуму (значения max_size_buffer), но у меня окно увеличивается только после нажатия клавиши ENTER.

Код строки 101-106
C++
1
2
3
4
5
// Установим прямоугольник источника. 
SMALL_RECT srctReadRect = {0, 0, max_size_buffer.X-100, max_size_buffer.Y-2}; //
//А если делать так  
//SMALL_RECT srctReadRect = {0, 0, max_size_buffer.X-1, max_size_buffer.Y-1}; 
//то выдает ошибку, почему?
Почему я немогу скопировать весть буфер, а только часть.

Второй вопрос, конечно меня больше всего интересует.

Добавлено через 5 часов 0 минут
Все со вторым вопросом я разобрался. Вот описание функции из MSDN:
C++
1
BOOL WINAPI ReadConsoleOutput(   __in     HANDLE hConsoleOutput,   __out    PCHAR_INFO lpBuffer,   __in     COORD dwBufferSize,   __in     COORD dwBufferCoord,   __inout  PSMALL_RECT lpReadRegion );
lpBuffer [out] A pointer to a destination buffer that receives the data read from the console screen buffer. This pointer is treated as the origin of a two-dimensional array of CHAR_INFO structures whose size is specified by the dwBufferSize parameter. The total size of the array must be less than 64K.
А у меня было больше. Консольное приложение разворачивалось на 240 столбиков х 95 строчки.
И я хотел скопировать все.
0
accept
4828 / 3249 / 165
Регистрация: 10.12.2008
Сообщений: 10,569
27.01.2011, 07:24 #4
Цитата Сообщение от QWAN
У меня в программе вставлено несколько getchar(); //остановка. При первой остановке окно должно былобы увеличится по максимуму (значения max_size_buffer), но у меня окно увеличивается только после нажатия клавиши ENTER.
перенеси её в конец функции и посмотри
если окно изменится, поднимай выше
0
27.01.2011, 07:24
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.01.2011, 07:24
Привет! Вот еще темы с ответами:

emacs в консоли и буфер обмена - Софт
Доброго времени суток. Начинаю осваивать emacs, и возникла проблема с копированием текста из емакса в другие приложения и обратно. Для...

По какому адресу находится буфер консоли? - Assembler
Этот код позволяет под BC++ 3.1 выводить символ в заданную позицию экрана, но почему-то он не работает под MinGW GCC. С какого адреса...

Копирование набранной в консоли строки в буфер обмена Windows - Assembler
ассемблер под windows, задание такое: Копирование набранной в консоли строки в буфер обмена Windows. программа есть, только работает...

Полно-экранный режим = input not supported - Мониторы
Доброго дня. Не откажите в помощи. Ситуация такая: Купил вчера новый комп и монитор (монитор Acer V206HQLBb), при запуске всё было...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.