Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > SynUniHighlighter и SynEdit > Windows консоль на базе SynEdit


Автор: Vit 9.8.2005, 20:33
Работая над GoldenPen решил прикрутить к нему виндовый терминал, получился компонент, основную функциональность cmd.exe вроде обеспечивает.

В прикреплённых файлах - полные тексты исходников

Автор: Vit 9.8.2005, 20:34
Вот пример exe с компонентом:


Автор: Vitalik 9.8.2005, 20:48
Прикольная вещь! smile
Только туда бы еще подсветку smile smile
Тогда бы было совсем супер! smile

Автор: Vit 9.8.2005, 20:49
Компонент ещё сыроват, но я в общем-то задавался целью не создать компонент на все случаи жизни, а обеспечить минимальные нужды для себя. Если есть желающие его отрехтовать - буду только рад. Вот перечень проблем которые мной не были решены:

1. Select/Paste - не решил из-за лени, сейчас компоеннт разрешает двигать курсор только в пределах текущей строки. Нужно добавить режим "селекта" когда разрешено выделение по всему тексту, возможно скрывать каретку на время этого режима

2. События на посылку команды и получение результатов - лень было возится, реализуется очень просто

3. Нет нормальной реализации Ctrl-C/Ctrl-Break - пока убиваю процесс, но это не корректно! Надо посылать терминалу контрол-событие, но с теми двумя API для этого с бубном попрыгал, с разгону не получилось, тратить время было жаль.

4. Свойство - Lines надо бы сделать Read-Only, но в SynEdit метод SetLines во-первых почему-то статический, а во вторых объявлен как Private... Блин, проще наверное разработчикам написать, иначе бубун нужен будет просто колласальных размеров

5. Теоретически если консольное приложение зависнет то и вся прога повиснет, что не есть хорошо... В thread что-ли его пустить?...

6. Нет нормального Completition - я основную функциональность сделал, но надо бы подточить.

7. Нет реакции на F2, F8 и т.п. как в cmd

8. Не пойму, почему странно ведут себя переносы строк. В cmd команды

Ping
и
Ping yahoo.com

Выглядят нормально, а у меня по разному.
9. По ходу дела так и не понял каким шрифтом рисуют в cmd - похоже чем-то самопальным, такого шрифта вообще в системе нет!

10. Как отличить консольное приложение от неконсольного. При запуске консольного его надо запускать скрытым и перехватывать вывод, а при запуске оконного - его просто запускать видимым и прекращать что-либо перехватывать. Тут бубун зарыт вот где: если определять консольность до запуска, то надо точно локализовать что именно будет запускаться, например на команду "notepad" реально запускается "c:\windows\notepad.exe", если же определять после запуска программы то надо по handle найти путь к программе или каким-то другим способом установить тип программы.

11. Ну и последнее - наверное нужен перехват и обработка входного канала тоже, например если консольная прога запросит чего-то, то сейчас это никак нельзя ввести.

Небольшой глюк: как правильно обработать запуск файлов по ассоциациям?

Автор: s-mike 9.8.2005, 21:09
Вот хороший компонент для перехвата консольного вывода, может пригодится smile

Автор: Vit 9.8.2005, 21:10
Сейчас посмотрим, может я велосипед изобретал smile
Добавлено @ 21:16
Нет, не велосипед, хотя кое что из этого компонента можно взять на вооружение. Спасибо, s-mike!

Автор: Петрович 19.9.2005, 12:40
Цитата(Vit @ 9.8.2005, 21:49)
5. Теоретически если консольное приложение зависнет то и вся прога повиснет, что не есть хорошо... В thread что-ли его пустить?...

Цитата(Vit @ 9.8.2005, 21:49)
11. Ну и последнее - наверное нужен перехват и обработка входного канала тоже, например если консольная прога запросит чего-то, то сейчас это никак нельзя ввести.

Тут наверное незачем изобретать велосипед. Есть вполне грамотные реализации функции запуска приложений, перехвата их вывода и подачи ввода на их вход. В качестве примера, могу привести компонент TVirtualRedirector из пакета http://www.mustangpeak.net/vstools.htm. Там грамотно реализована работа с отдельным потоком, обрабатывающем пайпы. Кроме того, он учитывает специфику Win9x/WinNT.
А вообще, попутно, в твоей реализации неправильно организуется работа с пайпами. Во первых, ты "закорачиваешь" вывод запускаемой программы на ее ввод, что естественно не правильно. Для ввода и вывода должны использоваться раздельные пайпы. Кроме того, нужен еще один пайп для стандартного потока ошибок (ErrorOut). Его тоже программы иногда используют для вывода сообщений об ошибках.

Цитата(Vit @ 9.8.2005, 21:49)
8. Не пойму, почему странно ведут себя переносы строк. В cmd команды

Ping
и
Ping yahoo.com

Выглядят нормально, а у меня по разному.

Проблема в том, что некоторые команды завершают строку последовательностью ^M^M^J. Для правильного терминала, любое число последовательных ^M эквивалентно единственному ^M. Т.к. ^M это всего навсего команда "переместить курсор в начало текущей строки". Соответственно, ^J, для правильного терминала, команда "переместить курсор на следующую строку, не изменяя позиции в строке".
Естественно, по логике надо полностью эмулировать работу терминала. Дело в том, что некоторые программы (например мои smile) иногда этим пользуются для вывода состояния выполнения операции. Например последовательно выводятся следующие строки:
Код

'Compile module xxx.pas'^M^J
^M'Compiled lines:  123'
^M'Compiled lines:  890'
^M'Compiled lines:  890'
^M'Compiled lines: 1234'
^M^J'Compile completed'^M^J
При правильной эмуляции, это будет выглядеть как обновление информации о процессе компиляции в одной строке.

Цитата(Vit @ 9.8.2005, 21:49)
9. По ходу дела так и не понял каким шрифтом рисуют в cmd - похоже чем-то самопальным, такого шрифта вообще в системе нет!

Кажется, cmd использует шрифт Terminal. Однако, не совсем понятно как он выбирает его размер, поскольку этот шрифт матричный, и имеет несколько размеров знакоместа.

Цитата(Vit @ 9.8.2005, 21:49)
10. Как отличить консольное приложение от неконсольного. При запуске консольного его надо запускать скрытым и перехватывать вывод, а при запуске оконного - его просто запускать видимым и прекращать что-либо перехватывать. Тут бубун зарыт вот где: если определять консольность до запуска, то надо точно локализовать что именно будет запускаться, например на команду "notepad" реально запускается "c:\windows\notepad.exe", если же определять после запуска программы то надо по handle найти путь к программе или каким-то другим способом установить тип программы.

Точно не помню, но в заголовке EXE-файла кажется есть битик, обозначающий консольное приложение. Насколько помню, где-то читал что система по нему определяет что при запуске такой программы, для нее необходимо создать консольное окно.
Правда, естественно можно предположить существование виндовых программ которые сами создают себе консольное окно. Я лично таких не встречал.

Добавлено @ 12:49
Да, забыл.
Еще, у тебя там не очень корректно отслеживается комманда cd и подобные.
В RunDosInMemo: pos('cd ', lowercase(CmdLine))>0 и т.п. Нельзя просто проверять на >0. Это приводит к ошибкам если в аргументах какой либо комманды встретится 'cd ' и т.п. Например Dir "cd 1"

Ну и большие проблемы с запуском DOS-приложений. Процессы ntvdm плодятся, а вывод не перехватывается!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)