Windows98+ReadConsoleInput

Здесь обсуждаются темы, косвенно связанные с Far.
stabud
Posts: 8
Joined: Mon 27 Feb, 2023 10:13
Been thanked: 2 times

Windows98+ReadConsoleInput

Post by stabud »

Добрый день!

Может кто-нибудь из старожил (разработчиков) FAR проявит снисхождение ко мне кодеру/лузеру и подскажет , почему у меня проблемы с функцией ReadConsoleInput на Win9x. Почему обратился к вам? FAR не имеет этих проблем , но я не вижу в исходном коде FAR что-то, что могло бы подсказать мне и изменить поведение. Проблема в том , что на Win9x рандомно возникают фризы. То есть , функция ReadConsoleInput при удержании клавиши (например стрелок) может 10-20 раз выполниться за 30-100мс , а потом резкий тормоз до 500-600мс , потом опять 30-80мс и так далее. Когда функция возвращается за время от 250 и больше , то консоль на короткое время как будто застывает.

Что я пробовал:

1) Менять ReadConsoleInput на PeekConsoleInput+FlushConsoleInputBuffer
2) Добавлять просто дополнительно в начало и/или в конец FlushConsoleInputBuffer для дополнительной очистки буфера
3) Ставить кол-во получаемых записей не 128 , а больше или меньше вплоть до одной
4) Добавлял WaitForSingleObject , чтобы срабатывало событие по нему
5) Добавлял GetNumberOfConsoleInputEvents , чтобы знать сколько событий в буфере и именно столько вызовов делал ReadConsoleInput
6) Менял создание хендла GetStdHandle на CreateFile , хендлы создавал и для OUTPUT выводя через WriteConsole, думая что может встроенный рантайм мозги пудрит

Все это проделывал в разных комбинациях , но все тщетно.

Но если взять FAR версии 1.65-1.70 , то там в редакторе нет фризов.

Подскажите пожалуйста, в чем секрет?

Вот простой исходный код:

Code: Select all

#include <windows.h>
#include <stdio.h>

int main(void)
{
	HANDLE hStdInput,hStdOutput;
	INPUT_RECORD ir[128];
	DWORD nRead;
	int blnLoop=1;
	int iCount;
	
hStdInput=GetStdHandle(STD_INPUT_HANDLE);
hStdOutput=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleMode(hStdInput , ENABLE_WINDOW_INPUT);
FlushConsoleInputBuffer(hStdInput);

do
{
	iCount = GetTickCount();
	if (ReadConsoleInput(hStdInput,ir,128,&nRead))
	{
		iCount = GetTickCount()-iCount;
		if (iCount>100)
		{
			printf("Slow = %d\r\n", iCount);
		}
		else
		{
			printf("%d\r\n", iCount);
		}
		
		if (ir[0].EventType ==KEY_EVENT && ir[0].Event.KeyEvent.wVirtualKeyCode==VK_ESCAPE)
			blnLoop=0;
	};
}
while (blnLoop==1);

return 0;
}
User avatar
HaRT
Moderator
Posts: 10823
Joined: Tue 30 Aug, 2005 17:21
Has thanked: 221 times
Been thanked: 358 times

Windows98+ReadConsoleInput

Post by HaRT »

 ! Message from: HaRT
Тема перенесена
Фар есть инструмент, а не нянька. © 2009 DrKnS
2useven10
Posts: 5210
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 18 times
Been thanked: 310 times

Windows98+ReadConsoleInput

Post by 2useven10 »

А если просто Sleep(0) внутрь цикла добавить?
stabud
Posts: 8
Joined: Mon 27 Feb, 2023 10:13
Been thanked: 2 times

Windows98+ReadConsoleInput

Post by stabud »

2useven10 wrote: Mon 27 Feb, 2023 13:22 А если просто Sleep(0) внутрь цикла добавить?
Я пробовал с разными таймингами в sleep, это ничего не давало.
2useven10
Posts: 5210
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 18 times
Been thanked: 310 times

Windows98+ReadConsoleInput

Post by 2useven10 »

В фар, скорее всего, ReadConsoleInput() вызывается только если PeekConsoleInput() покажет наличие данных. Из вашего текста неясно пробовали ли вы такой вариант.
Last edited by 2useven10 on Mon 27 Feb, 2023 15:59, edited 1 time in total.
stabud
Posts: 8
Joined: Mon 27 Feb, 2023 10:13
Been thanked: 2 times

Windows98+ReadConsoleInput

Post by stabud »

Я пробовал вызывать PeekConsoleInput и далее удалял присланные данные из очереди с помощью ReadConsoleInput или FlushConsoleInputBuffer.
Пробовал так же перед ReadConsoleInput или PeekConsoleInput ставить WaitForSingleObject и GetNumberOfConsoleInputEvents.
Пробовал ставить разные режимы с помощью SetConsoleMode , в том числе просто обнулять
Я бы не обратился за помощью , пока все что мог не попробовал.
Я запускаю разные варианты исходника (со всеми перечисленными функциями) и при любом раскладе возникают эти фризы на Win9x. Если взять Windows 2000 и выше , то там никаких проблем нет.
Однако , когда запускаю FAR (редактор) на Win9x, то там никаких фризов нет , сколько бы я не удерживал клавишу нажатой , когда прокручиваю текст.
Просто магия какая-то!
2useven10
Posts: 5210
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 18 times
Been thanked: 310 times

Windows98+ReadConsoleInput

Post by 2useven10 »

Приложение не Unicode?
Т.е. вызываются ReadConsoleInputA, PeekConsoleInputA,...
stabud
Posts: 8
Joined: Mon 27 Feb, 2023 10:13
Been thanked: 2 times

Windows98+ReadConsoleInput

Post by stabud »

2useven10 wrote: Mon 27 Feb, 2023 16:18 Т.е. вызываются ReadConsoleInputA, PeekConsoleInputA,...
да
2useven10
Posts: 5210
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 18 times
Been thanked: 310 times

Windows98+ReadConsoleInput

Post by 2useven10 »

Ну, imho, тормоза в ReadConsoleInput() могут быть только при вызове ф-и, когда событий нет.
До появления следующего эвента, Peek... эту проблему решает.
Приведите ваш код с Peek и замерами времени задержки.
stabud
Posts: 8
Joined: Mon 27 Feb, 2023 10:13
Been thanked: 2 times

Windows98+ReadConsoleInput

Post by stabud »

Code: Select all

#include <windows.h>
#include <stdio.h>

int main(void)
{
	HANDLE hStdInput,hStdOutput;
	INPUT_RECORD ir[128];
	DWORD nRead;
	int blnLoop=1;
	int iCount;
	
hStdInput=GetStdHandle(STD_INPUT_HANDLE);
hStdOutput=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleMode(hStdInput , ENABLE_WINDOW_INPUT);
FlushConsoleInputBuffer(hStdInput);

do
{
	iCount = GetTickCount();
	
	if (PeekConsoleInput(hStdInput,ir,128,&nRead))
	{	
		if (nRead > 0)
		{
			if (ReadConsoleInput(hStdInput,ir,nRead,&nRead))
			{
				
				if (ir[0].EventType ==KEY_EVENT && ir[0].Event.KeyEvent.wVirtualKeyCode==VK_ESCAPE)
					blnLoop=0;
			};

		}
		else
			Sleep(15);
	};

	iCount = GetTickCount()-iCount;
	if (iCount>100)
	{
		printf("Slow = %d\r\n", iCount);
	}
	else
	{
		printf("%d\r\n", iCount);
	}
}
while (blnLoop==1);

return 0;
}
Так же коротенькое видео:
testwin9x.mkv.zip
(2.15 MiB) Downloaded 45 times
Я так же пробовал 3-им параметром у функции ReadConsoleInput ставить значение 128 , результат тот же.
2useven10
Posts: 5210
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 18 times
Been thanked: 310 times

Windows98+ReadConsoleInput

Post by 2useven10 »

Last edited by 2useven10 on Tue 28 Feb, 2023 01:16, edited 2 times in total.
stabud
Posts: 8
Joined: Mon 27 Feb, 2023 10:13
Been thanked: 2 times

Windows98+ReadConsoleInput

Post by stabud »

Компиль заругался на putc и nullptr , но это не суть.
Код работает еще медленнее и кол-во фризов только возросло. На какой-нибудь WinXP код будет работать и выводить одни точки , но на win9x кол-во точек и знаков вопроса почти одинаково, ну и консоль чаще тормозит/тупит перед выводом.

Я знаю только 2 консольные программы того времени FAR , HIEW.
Hiew так же фризит при прокрутке , но FAR нет. Опять же говорю: это магия какая-то.
Shmuel
Posts: 6820
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

Windows98+ReadConsoleInput

Post by Shmuel »

Исходники Фара на Гитхабе, начиная с версии 1.64, что мешает разобраться?
2useven10
Posts: 5210
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 18 times
Been thanked: 310 times

Windows98+ReadConsoleInput

Post by 2useven10 »

Там с Input вроде ничего особенного не делается...
Ну открывается "CONIN$", разрешается WINDOW (возможно MOUSE) INPUT.

Может причина тормозов не Input, а Output?
Там, возможно, буфер делают на размер экрана.

Но без проверки на 9x, это всё гадание на кофейной гуще.
stabud
Posts: 8
Joined: Mon 27 Feb, 2023 10:13
Been thanked: 2 times

Windows98+ReadConsoleInput

Post by stabud »

@2useven10

Спасибо , что вы попытались помочь!

@Shmuel

Конечно ничего не мешает. Ну разве только:
1) С/С++ не является языком , на котором я пишу. Это ведь я здесь выложил код на СИ , чтобы не пугать конструкциями другого ЯП.
2) придется хорошо вникать в особенности сборки компилятором от борланд (мой первый опыт был неудачным)
3) придется разгребать кучу кода , а это не 100 и даже не 1000 строк
4) для сборки надо еще по всему гитхабу (а может и не только по нему) лазить , чтобы найти батники, заголовки и утилиты. Ведь по умолчанию ничего не собрать , там много чего не хватает и сыплет ошибками. А потом , когда/если это удастся , начинать отрезать в коде все "лишнее" , и гонять исходник до посинения, чтобы наконец понять в чем дело. Просто читая исходники, я ничего не нашел такого, чтобы меня натолкнуло на правильный путь.

Конечно , я и не ждал , что кто-то будет все делать за меня. Я лишь надеялся , что у разрабов что-то сохранилось в памяти и они могли пнуть меня в нужном направлении. Вот похоже и пнули...
И да , я понимаю , что никто мне ничего не должен и это сугубо моя проблема.
Извиняюсь , что отнял у вас время и создал может быть "левую" тему , не предназначенную для данного форума. Прощаюсь.
Post Reply

Return to “Операционные системы, командные оболочки и прочее”