Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [c++, WinAPI]перенаправить вывод 
:(
    Опции темы
ИванМ
Дата 22.11.2010, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 13
Всего: 23



Нужно сделать так, чтобы выводимая информация из запускаемых программы из моей программы (консоль) выводились не стандартными средствами, а проходила через мои обработчики.
Пытался делать через перенаправление вывода (вроде system("prog.exe > 1.txt")), читать из файла, а потом выводить. 
Так работает, но только для тех программ, где не надо ничего вводить. Например, для system("pause") не работает. Сначала идет ожидание нажатия клавиши, потом уже текст.
Подскажите, пожалуйста, что делать, и, если можно, примерчик.
PM MAIL   Вверх
t_gran
  Дата 22.11.2010, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 33
Всего: 37



ИванМ, идея вообще-то следующая:
Код

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

int main(int argc, char **argv)
{
   if (argc != 2)
   {
      printf("Usage: %s COMMAND", argv[0]);
      return 1;
   }

   FILE *p = popen(argv[1], "rw");
   
   if (!p)
   {
      printf("Error: command '%s' not found ...", argv[0]);
      return 2;
   }
   
   char title[128];
   GetConsoleTitle(title, sizeof(title));
   HANDLE hwnd = FindWindow(NULL, title);
   if (hwnd)
   {
      SendMessage(hwnd, WM_KEYDOWN, VK_SPACE, 0);
   }

   char buff[128];
   while (fgets(buff, sizeof(buff), p))
   {
      printf("* %s", buff);
   }

   pclose(p);

   return 0;
}

Всё вроде верно, но сообщение не срабатывает. smile 
Я уже и так и эдак, но что-то так и не получилось. Попробуйте, может на базе этой идеи вы и найдёте верное решение.



Это сообщение отредактировал(а) t_gran - 22.11.2010, 08:52


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
ИванМ
Дата 22.11.2010, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 13
Всего: 23



t_gran, если честно, я вообще не понял вашу идею. Можете объяснить, что вы имели ввиду?
PM MAIL   Вверх
t_gran
Дата 23.11.2010, 03:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 33
Всего: 37



ИванМ, как вы уже должны были понять, работа ведётся естественно через pipes. Прокомментированный код (test.c):
Код

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

int main(int argc, char **argv)
{
   if (argc != 2) // Без комментариев
   {
      printf("Usage: %s COMMAND", argv[0]);
      return 1;
   }
   FILE *p = popen(argv[1], "r"); // Запускаем процесс и открываем PIPE на чтение
   
   if (!p)  // PIPE не создан
   {
      printf("Error: command '%s' not found ...", argv[0]);
      return 2;
   }

   // Находим handle нашего консольного окна
   char title[128];
   GetConsoleTitle(title, sizeof(title));
   HANDLE hwnd = FindWindow(NULL, title);

   // Если handle найден отправляем ему сообщение,
   // что был нажат пробел
   if (hwnd)
      SendMessage(hwnd, WM_KEYDOWN, VK_SPACE, 0);

   // Ну а теперь, когда PAUSE подавили считываем
   // из канала всю пришлую информацию, с добавлением
   // в начало '*'
   char buff[128];
   while (fgets(buff, sizeof(buff), p))
   {
      printf("* %s", buff);
   }
   
   // Закрываем канал
   pclose(p);
   return 0;
}


И по идее при вводе:
Код

$ test pause

Должно без задержки вылезти следующее:
Код

* Для продолжения нажмите любую клавишу . . .

Но эта зараза не хочет глотать сообщение о нажатии клавиши SPACE!  smile 


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
mrbrooks
Дата 23.11.2010, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 16
Всего: 306



ИванМ, 
здесь есть еще два варианта решения проблемы:
1. Это воспользоваться специализированными API для работы с консолью. Console Function 
Понятно - копать надо в сторону ReadConsole и же с ней.

2. Это пайпы, т.е. Pipe Functions
Стартовать с CreatePipe или с CreateNamedPipe. Какой именно пайп выбрать - именованный или анонимный - на самопроработку через гугл.  smile 

Чисто мое мнение - конечно Console API будет по проще, однако пайпы более гибки.
PM MAIL   Вверх
ИванМ
Дата 23.11.2010, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 13
Всего: 23



t_gran, забыл уточнить, что ввод тоже должен происходить через мои обработчики. Так что отправка сообщений чтобы эмулировать ввод нельзя делать.

mrbrooks, можно пример с Console API?

Чтобы было понятнее, сформулирую задачу. Нужно сделать, что бы ввод и вывод на консоль происходил внутри ограниченной области.
Я сделал обертку WriteConsole и ReadConsole, все прекрасно работает, пока не происходит вызов других консольных приложений, которые не знают о моей ограниченной области.

Это сообщение отредактировал(а) ИванМ - 23.11.2010, 13:57
PM MAIL   Вверх
mrbrooks
Дата 23.11.2010, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 16
Всего: 306



Цитата(ИванМ @  23.11.2010,  13:55 Найти цитируемый пост)
mrbrooks, можно пример с Console API?

эм. ты думаешь это будет кардинально отличаться от:
Цитата(ИванМ @  23.11.2010,  13:55 Найти цитируемый пост)
Я сделал обертку WriteConsole и ReadConsole, все прекрасно работает

или может я не ясно выразился. Под Console API я понимал Console Function 

Цитата(ИванМ @  23.11.2010,  13:55 Найти цитируемый пост)
пока не происходит вызов других консольных приложений, которые не знают о моей ограниченной области.


о какой ограниченной области идет речь? о положении курсора?
PM MAIL   Вверх
ИванМ
Дата 23.11.2010, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 13
Всего: 23



Цитата(mrbrooks @  23.11.2010,  14:45 Найти цитируемый пост)
эм. ты думаешь это будет кардинально отличаться от:

Я сделал обертку над WriteConsole и ReadConsole только для ограничения пользовательского ввода/вывода моего приложения. А мне еще нужно также ограничивать ввод/вывод сторонних приложений, запускаемых из моей программы.

Цитата(mrbrooks @  23.11.2010,  14:45 Найти цитируемый пост)
о какой ограниченной области идет речь? о положении курсора? 

В окне есть прямоугольник, за границы которого ввод и вывод происходить не может. Иначе происходит внутренняя прокрутка (если по вертикали больше) либо перенос на новую строку (если по горизонтали). 

Это сообщение отредактировал(а) ИванМ - 23.11.2010, 21:30
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0534 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.