Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ожидание реакции пользователя 
:(
    Опции темы
Superklug
Дата 19.4.2009, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

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



Доброго времени суток!
Нарисовал на бумажке алгороитм, начал его реализовывать и столкнулся с такой проблемой: посреди рекурсии, мне нужно ждать пока пользователь нажмет на кнопку... 

На консоли все просто:
Код

for(int i=0; i<10; i++)
{
    ...
    cout<<"вопрос";   // Задали вопрос
    cin>>A;    // Получили ответ
    ...
}

А как сделать это под windows?

Пробовал вставлять вот это:
Код

flag=false;
do
{
    Sleep(100);
    Application->ProcessMessages();
}
while(!flag);

по нажатию пользователем на кнопку, flag присваивается true.
Но тогда не обрабатываются сообщения от окна (например о закрытии). Точнее они обрабатываются, но только по завершении цикла.


Как поступить в такой ситуации? Переделать алгоритм, чтобы он был ориентирован на события? Каким-то образом проверять нажал ли пользователь выход (или др.) во время цикла?
Еще есть вариант: использовать потоки. Но не уверен, что удобно будет. Мне надо постоянно взаимодействовать с компонентами формы и БД...

Это сообщение отредактировал(а) Superklug - 19.4.2009, 14:08
PM MAIL   Вверх
Superklug
Дата 19.4.2009, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

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



Сейчас решил попробовать с потоками. 
В нужном мне месте пишу Suspend(); Но поток не останавливается( В чем может быть дело?
PM MAIL   Вверх
Artemon
Дата 19.4.2009, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


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

Репутация: 7
Всего: 20



Перечитал раз 10 ваш вопрос, но не понял некоторых вещей:

1. Где вы здесь увидели рекурсию ? У вас ведь просто цикл.
2. Следующий код работает с рекурсией и задает вопрос:

Код

//---------------------------------------------------------------------------
  void TForm1::RecursionFunc( void )
{
  ShowMessage("Вопрос");

  RecursionFunc();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  RecursionFunc();
}
//---------------------------------------------------------------------------


данный код блокирует выполнение основного потока и ждет ответ на вопрос.
Зачем еще какой-то цикл ожидания нужен вообще не понятно.



Это сообщение отредактировал(а) Artemon - 19.4.2009, 20:10


--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
taiven
Дата 19.4.2009, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 302
Регистрация: 30.6.2008

Репутация: 3
Всего: 9



Цитата(Superklug @  19.4.2009,  13:02 Найти цитируемый пост)
по нажатию пользователем на кнопку, flag присваивается true.Но тогда не обрабатываются сообщения от окна (например о закрытии). Точнее они обрабатываются, но только по завершении цикла.

А если flag присвоить true в в событии OnClose формы?

Это сообщение отредактировал(а) taiven - 19.4.2009, 17:32
PM   Вверх
Лапоть
Дата 19.4.2009, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 3.4.2009

Репутация: 1
Всего: 2



Superklug,  а теперь, пожалуйста, члено и раздельно объясни свою задачу! Я ещё могу представить себе в консоли цикл вопросов-ответов для доступа куда-либо... Но дуплить такое в оконном режиме...
Цитата(Superklug @  19.4.2009,  15:02 Найти цитируемый пост)
мне нужно ждать пока пользователь нажмет на кнопку...

Не-а, судя по твоему же коду, тебе нужно получить ОТВЕТ!
PM MAIL   Вверх
artsb
Дата 19.4.2009, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 39
Всего: 64



Цитата(Лапоть @  19.4.2009,  21:54 Найти цитируемый пост)
судя по твоему же коду, тебе нужно получить ОТВЕТ! 

Мне кажется, Superklug просто привёл пример, как он это делает в консоле. Но это же не значит, что он кому-то задаёт вопросы в цикле...


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
nworm
Дата 20.4.2009, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 502
Регистрация: 22.10.2005

Репутация: 1
Всего: 8



Можно на события переделать. Если ответ пользователя означает нажатие кнопки.
Можно как-то так
Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 static int i=0;

 i++;
 switch (i) {
 case 1: Edit1->Text=Edit3->Text;//типа реакция
         break;
 case 2: Edit1->Text=Edit3->Text;
         break;
 case 3: Edit4->Text=Edit3->Text;
         break;
 default:
     ;
 }
}

PM MAIL WWW   Вверх
artsb
Дата 20.4.2009, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 39
Всего: 64



nworm, у Superklug цикл. И как я понял, нужно при некоторых условиях делать остановки и ждать действий пользователя. А в вашем случае, пользователю придётся много клацать smile


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
nworm
Дата 20.4.2009, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 502
Регистрация: 22.10.2005

Репутация: 1
Всего: 8



Схема может быть похожей и без кнопки. 

Код

void start()
{
 static int i=0;
 i++;
 switch (i) {
 case 1: Edit1->Text=Edit3->Text;//типа реакция
         break;
 case 2: Edit1->Text=Edit3->Text;
         break;
 case 3: Edit4->Text=Edit3->Text;
         break;
 default:
     ;
 }
}


И этот старт - реакция на нужное действие пользователя.

PM MAIL WWW   Вверх
Klin
Дата 20.4.2009, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1938
Регистрация: 7.10.2002
Где: Краснодар

Репутация: 20
Всего: 25



Народ, вы гадаете, пока автор не отпишется, трудно сказать, в каком направлении мыслить. ИМХО человек переходит с консоли на объекты, и еще не охватил все аспекты.


--------------------
Я человек - попробуйте обвинить меня за это.
PM MAIL   Вверх
artsb
Дата 20.4.2009, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 39
Всего: 64



Цитата(Klin @  20.4.2009,  18:20 Найти цитируемый пост)
ИМХО человек переходит с консоли на объекты, и еще не охватил все аспекты. 

Скорее всего так...


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Superklug
Дата 29.4.2009, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

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



Извините что долго не появлялся...
Цикл на консоле я привел просто как пример. 
У меня же есть рекурсивная функция.. Щас опишу подробней...
Рекурсия - это обход дерева. Листья дерева - это вопросы к пользователю. Ответ пользователя на вопрос может изменить ход рекурсии. В итоге имеем:

Код

int Func(int a)
{
    //...
    if(листок дерева)
    {
         Memo->Text=Вопрос;
         // Вот здесь надо ждать ответа пользователя.
        return Ответ;
    }
    else
        return Func(a);
}


В итоге ожидание я сделал так:
Код

while(Answer==-1)
{
    Sleep(10);
    Application->ProcessMessages();
    if(fmMain->Stop)
        return 0;
}


и обработчик события OnCloseQuery
Код

void __fastcall TfmMain::FormCloseQuery(TObject *Sender, bool &CanClose)
{
        Stop=true;
}


Вроде работает, но понимаю, что это очень корявое решение. Отсюда вопрос: как лучше реализовать такую задачу? Отказаться от рекурсии и изменить алгоритм?


P.S. с ShowMessage все будет работать как надо, однако реализован интерфейс. Т.е. вопрос должен выводиться в Memo, а ответ получаться после нажатия на Button

PM MAIL   Вверх
artsb
Дата 29.4.2009, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 39
Всего: 64



Superklug, пробуй так:
Код

AnsiString asResult;
HANDLE H;
//-------------------------------------------------
int Func(int a)
{
    //...
    if(листок дерева)
    {
         Memo->Text=Вопрос;
         H = CreateEvent(NULL, true, false, NULL);
         WaitForSingleObject(H, INFINITE); // либо вместо INFINITE количество миллисекунд
         CloseHandle(H);
        return asResult;
    }
    else
        return Func(a);
}
//--------------------------------------------------
void __fastcall TfmMain::Button1Click(TObject *Sender)
{
        asResult = Ответ;
        SetEvent(H);
}



--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Usper
Дата 30.4.2009, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 13.4.2007

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



Цитата(Superklug @  29.4.2009,  20:57 Найти цитируемый пост)
P.S. с ShowMessage все будет работать как надо, однако реализован интерфейс. Т.е. вопрос должен выводиться в Memo, а ответ получаться после нажатия на Button


А почему не использовать дополнительную форму вместо ShowMessage? На форму можно накидать всё что угодно. Вызывать её для остановки основного потока надо как модальное окно.



--------------------
На посохе волшебном нехилый набалдашник, большой такой, огромный, нехилый набалдашник.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


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

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


 




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


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

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