Страница 2 из 2

Добавлено: 23 дек 2004, 11:46
Eugie
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);
}

Добавлено: 24 дек 2004, 11:29
pominub
Спасибо. С этим разобрался.
Теперь следующая проблема:

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

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

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

Как это сделать???
Спасибо.

Добавлено: 24 дек 2004, 12:57
Eugie
Заведи флажок, в OnTimer() добавляй строку в тот или другой ListBox, запускай таймер с соотв.таймаутом и меняй значение флага. Надеюсь, логика понятна ;)

Добавлено: 24 дек 2004, 13:37
pominub
2Eugie

Вобщем понятна.
Но, если не сложно, можно примерчик....
Спасибо

Добавлено: 24 дек 2004, 14:51
Romeo
Ввести переменную-флажок, которая будет отвечать была ли произведена уже запись в первый ListBox. Если да, то делать запись во второй, беря строку из первого, если нет то делать запись в первый, беря строку из файла. Затем инвертировать флажок.

Добавлено: 24 дек 2004, 16:16
Eugie
pominub, задача элементарная, сделай сам - будет польза :)

Добавлено: 25 дек 2004, 08:09
pominub
Спасибо. Разобрался. Всё работает.
Ещё такой вопрос:
Следующую программу мне предстоит делать тоже с использованием таймеров.
Только там будет ListCtrl и для каждой строки нужно будет делать таймер.
И на двойной клик по итему, нужно будет запускать таймер и тоже что-то выполнять.
Причём количество итемов в списке будет неограничено. Значит и кол-во таймеров тоже.
Можно ли такое будет реализовать с помощью такого таймера. Если нет, то какие средства
ещё существуют в MFC для работы со временем?
Спасибо...

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