Шаг 43 - CWinApp::OnIdle

virtual BOOL OnIdle( LONG lCount );

Возвращаемое значение
Отличный от нуля для резервирования большего процессорного времени, 0 если нет больше необходимости в процессорном времени.

Параметры
lCount
Счетчик, увеличивающийся каждый раз при вызове OnIdle когда очередь сообщений приложения пуста. Этот счет сброшен к 0, каждый раз когда новое сообщение обработано. Вы можете использовать lCount параметр, чтобы определить относительный отрезок времени, когда приложение простаивает без обработки сообщений.

Замечания
Отмените этот метод, чтобы выполнить обработку времени простоя. OnIdle вызывает заданный по умолчанию цикл сообщения, когда очередь сообщений приложения пуста. Используйте вашу перегрузку, чтобы вызвать ваши собственные фоновые задачи с неактивным обработчиком.
OnIdle должен возвратиться 0, чтобы указать, что никакой обработки простоя не требуется. lCount параметр увеличен каждый раз при вызове OnIdle когда очередь сообщений пуста и сбрасывает к 0, каждый раз новое сообщение обработано. Вы можете называть ваши различные неактивные подпрограммы основанными на этом счете. Цикл обработки простоя сводиться к следующему:

1. Если цикл сообщения в MFC проверяет очередь сообщений и не находит никаких отложенных сообщений, вызывается OnIdle для объекта приложения и обеспечивает 0 как lCount параметр.

2. OnIdle выполняет некоторую обработку и возвращает значение отличное от нуля, чтобы указать, что нужно вызваться снова, чтобы делать обработку дальше.

3. Цикл сообщения проверяет очередь сообщений снова. Если никакие сообщения не отложены, функция OnIdle вызываеться снова, при приращении lCount параметра.

4. В конечном счете, OnIdle заканчивает обрабатывать все неактивные задачи и возвращается 0. Это сообщает, чтобы цикл сообщения прекратил вызывать OnIdle, пока следующее сообщение не получено от очереди сообщений и цикл обработки простоя не будет перезапущен с параметром 0.

Не выполняйте длинные задачи в течение OnIdle, потому что ваше приложение не может обрабатывать ввод пользователя до возврата OnIdle.

Обратите внимание, что заданная по умолчанию реализация OnIdle модифицирует объекты интерфейса пользователя типа пунктов меню и кнопок панели инструментов , и выполняет внутреннюю очистку структур данных. Следовательно, если Вы отменяете OnIdle, Вы должны вызвать CWinApp:: OnIdle с lCount установленным Вами. Сначала вызовете функцию простоя базового класса, обрабатывающим простой (то есть пока OnIdle базового класс не вернет 0). Если Вы должны выполнить работу прежде, чем обработка базового класса завершается, посмотрите реализацию базового класса, чтобы выбрать соответствующий lCount, чтобы делать вашу работу.

Пример
Следующие два примера показывают, как использовать OnIdle. Первый пример обрабатывает две неактивных задачи, использующие параметр lCount, чтобы расположить по приоритетам задачи. Первая задача - высокий приоритет, и Вы должны делать это всякий раз, когда возможно. Вторая задача менее важна и должна быть выполнена только, когда имеется длинная пауза во вводе пользователя. Обратите внимание на обращение к OnIdle базового класса. Второй пример управляет группой неактивных задач с различными приоритетами.

BOOL CMyApp::OnIdle(LONG lCount)
{
	BOOL bMore = CWinApp::OnIdle(lCount);

	if (lCount == 0)
	{
		TRACE("App idle for short period of time\n");
		bMore = TRUE;
	}
	else if (lCount == 10)
	{
		TRACE("App idle for longer amount of time\n");
		bMore = TRUE;
	}
	else if (lCount == 100)
	{
		TRACE("App idle for even longer amount of time\n");
		bMore = TRUE;
	}
	else if (lCount == 1000)
	{
		TRACE("App idle for quite a long period of time\n");
		// Если  bMore не установлен в TRUE, нет больше потребности в простое
		// ВАЖНО: bMore не установлен в FALSE, так как CWINAPP:: OnIdle может
		// иметь незавершенные задачи.
	}

	return bMore;
	// Возвратите TRUE пока имеются неактивные задачи
}

Второй пример:

// В этом примере, четыреv неактивныv задачам даны различные
// возможности выполняться: 
// Task1 всегда дана возможность, чтобы выполниться в течение времени простоя, если
// никакое сообщение не поставилено в очередь,  в то время как каркас обрабатывал
// собственные неактивные задачи цикла (в lCount выравниваются 0 и 1).
// Task2 дана возможность, чтобы выполниться только, если Task1 уже выполнился,
// если никакое сообщение не поставлено в очередь, в то время как Task1 выполнялся.
// Task3 и Task4 дана возможность, чтобы выполниться только, если и Task1 и
// Task2 уже выполнились, и никакое сообщение не поставило в очередь в данное 
// время. Если Task3 получает возможность, чтобы выполниться, то Task4 всегда получает
// возможность, чтобы выполниться немедленно после Task3.
BOOL CMyApp::OnIdle(LONG lCount) 
{ 
	// В этом примере, как в большинстве приложений, Вы должны позволить 
	// базовому классу CWinApp:: OnIdle, завершить обработку прежде, чем Вы 
	// делаете попытку любой дополнительной неактивной обработки цикла.
	if (CWinApp::OnIdle(lCount)) return TRUE; 
	// Базовый класс CWinApp:: OnIdle резервирует lCount, оценивает 0 
	// и 1 для собственной неактивной обработки каркаса. Если Вы желаете  
	// совместно использовать простой, обрабатывающий время в паре(равном
	// по положению), уровень с каркасом, затем заменяет вышеупомянутый
	// условный оператор на прямое обращение к CWinApp:: OnIdle; и затем
	// добавьте, что оператор выбора для lCount оценивает 0 и-или 1.
	// Исследуйте реализацию базового класса сначала к, пониманию, как ваши
	// неактивные задачи цикла конкурируют с неактивной обработкой цикла каркаса.

	case 2: Task1(); 
		return TRUE; 
		// В следующий раз дайте Task2 возможность
	case 3: Task2(); return TRUE; 
		// В следующий раз дайте Task3 и Task4 возможность
	case 4: Task3(); Task4(); 
		return FALSE; // Циклически пройти неактивные задачи цикла снова
	} 
	return FALSE; 
}

Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 20.12.2001