Проблемы с таймером в MFC.

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

pominub, на будущее - пользуйся тегами code и /code (ессно, в квадратных скобках) для выделения кода - plain text тяжело читать.

По вопросу тебе совершенно верно ответили на форуме. На всякий случай повторю, для ленивых :) : при нажатии на кнопку ты сразу пытаешься прочитать весь файл в цикле while(File.ReadString(str)!=FALSE). При этом никакие сообщения Windows не обрабатываются, в т.ч. и таймерные. Если же добавить вызов AfxMessageBox(), то создается модальное диалоговое окно со своим циклом сообщений, в котором и обрабатываются таймерные сообщения.

Вот пример как следовало бы сделать:

Код: Выделить всё

void CMy1Dlg::OnButton1() 
{
  // Заблокирум кнопку пока читаем из файла
  m_ReadBtn.EnableWindow(FALSE);
  // Открываем файл в режиме 'текстовый/только_на_чтение/разделяемый доступ'
  // Режим 'разделяемый доступ' (CFile::shareDenyNone) позволяет 2 копиям
  // программы одновременно работать с одним файлом.
  m_pFile.Open("readme.txt", CFile::modeRead|CFile::typeText|CFile::shareDenyNone);
  // Запускаем таймер.
  SetTimer(ID_TIMER, m_Timeout, NULL);
}

void CMy1Dlg::OnTimer(UINT nIDEvent) 
{
  CString s;
  // Остановим таймер
  KillTimer(ID_TIMER);
  // Читаем очередную строку
  if (m_pFile.ReadString(s))
  {
    // и добавляем ее в список
    m_List.AddString((LPCTSTR) s);
    // Задаем новый таймаут (здесь для примера - инкрементом)
    // и перезапускаем таймер.
    SetTimer(ID_TIMER, (m_Timeout+=1000), NULL);
  }
  // Достигли конца файла
  else
  {
    // Закрываем файл
    m_pFile.Close();
    // и разблокируем кнопку
    m_ReadBtn.EnableWindow(TRUE);
  }
  // Вызов стандартного обработчика родительского класса
  CDialog::OnTimer(nIDEvent);
}
pominub
Сообщения: 24
Зарегистрирован: 16 ноя 2004, 09:35
Откуда: Spb

Спасибо. С этим разобрался.
Теперь следующая проблема:

Нужно по истечении времени таймера добавить эту же строку во второй ListBox.
То есть раньше я просто читал строки из файла и выводил их
в список (интервал каждый раз разный), а теперь нужно:

1. Считать строку из файла и записать её в ListBox1
2. Подождать указанное время
3. Записать эту же строку в ListBox2
И так, пока строки в файле не закончатся.

То есть раньше выполнялось одно действие через определённый интервал
(всегда разный), а сейчас нужно выполнить первое действие (прочитать
строку из файла и добавить её в ListBox1, подождать указанный промежуток
времени (тоже всегда разный), и выполнить второе действие (записать эту же
строку в ListBox2). И так в цикле, пока строки не кончатся.

Как это сделать???
Спасибо.
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

Заведи флажок, в OnTimer() добавляй строку в тот или другой ListBox, запускай таймер с соотв.таймаутом и меняй значение флага. Надеюсь, логика понятна ;)
pominub
Сообщения: 24
Зарегистрирован: 16 ноя 2004, 09:35
Откуда: Spb

2Eugie

Вобщем понятна.
Но, если не сложно, можно примерчик....
Спасибо
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Ввести переменную-флажок, которая будет отвечать была ли произведена уже запись в первый ListBox. Если да, то делать запись во второй, беря строку из первого, если нет то делать запись в первый, беря строку из файла. Затем инвертировать флажок.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

pominub, задача элементарная, сделай сам - будет польза :)
pominub
Сообщения: 24
Зарегистрирован: 16 ноя 2004, 09:35
Откуда: Spb

Спасибо. Разобрался. Всё работает.
Ещё такой вопрос:
Следующую программу мне предстоит делать тоже с использованием таймеров.
Только там будет ListCtrl и для каждой строки нужно будет делать таймер.
И на двойной клик по итему, нужно будет запускать таймер и тоже что-то выполнять.
Причём количество итемов в списке будет неограничено. Значит и кол-во таймеров тоже.
Можно ли такое будет реализовать с помощью такого таймера. Если нет, то какие средства
ещё существуют в MFC для работы со временем?
Спасибо...
Tima
Сообщения: 43
Зарегистрирован: 23 сен 2004, 11:17
Откуда: Харьков
Контактная информация:

Есть альтернатива, - но это не MFC, а Win32 - через обьект ядра waitable timer и функцию CreateWaitableTimer. Если ты будешь использовать обычные таймеры это сильно подгрузит систему. Тема эта хорошо рассматривается у Рихтера.
Ответить