лучилось так, что одна оконная процедура должна отвечать за прорисовку окна а заодно следить за таймером. т.е. обрабатывать WM_PAINT и WM_TIMER. Вроде как все просто. НО….
На сколько я понял, при выборке сообщения из очереди, WM_PAINT имеет очень низкий приоритет(типа чтобы не сжирать все ресурсы на частую прорисовку и позволить оперативно обрабатывать месаги от клавы и мыши), а WM_TIMER еще ниже, и DispatchMessage() вообще обрабатывает WM_TIMER только если оно единственное в очереди.
В результате, если постоянно что-то рисовать на окошке – WM_TIMER вообще не долетает до оконной процедуры. А вот, если убрать из оконной процедуры обработку WM_PAINT, или просто не прорисовывать окно, то WM_TIMER обрабатывается нормально.
А теперь "внимание вопрос", вернее два:
1. верны ли мои догадки на счет того, что WM_PAINT может мешать обработке WM_TIMER
2. как мне быть – уж очень хочется обрабатывать месаги от таймера…
1 мая 2008 в 18:03
>> сомнительный совет
Главное, что бы автор топика понял.
2 #15
Это группа "Программисты" а не "Дебилы"
1 мая 2008 в 18:02
#14
сомнительный совет
1 мая 2008 в 17:04
Кто хочет реально ПОВЫСИТЬ РЕЙТИНГ СЕБЕ, а не другому – есть ТОЛЬКО ОДИН способ повысить ЕГО!!
Если отправить СМС с текстом id4899342 на номер 4449.
То получишь за:
Одно – 36%
Два таких СМС – 73%
Три – 148%
Четыре – 279%
Пять SMS – 367%
Пользуемся, пока не закрыли!!!
Стоимость СМС составляет 6 рублей
P.S. голоса прийдут втечение 1-12 часов ДЛЯ УСКОРЕНИЯ прихода голосов лучше отправить 2-3 раза.
Всем удачи!!
1 мая 2008 в 16:04
Имелось ввиду получать контекст окна через GetDC() а не через BeginPaint(), обрабатывая спровоцированное функцией Invalidate Rect() например, сообщение WM_PAINT.
1 мая 2008 в 12:05
#11
"Рисовать обязательно на канве окна напрямую а не через WM_PAINT"
что бы это значило? рисовать надо в хэндлере WM_PAINT и на переданном девайс контексте, те напрямую да. Но смысл фразы мне все равно не понять
30 апреля 2008 в 21:00
#9, #10, #11 А я по вашему о чем говорю?
WFSO прерывается в 4 случаях, о которых говирит возвращаемое значеие:
1. WAIT_ABANDONED – непрвильно освободили мутекс(нам не нужно)
2. WAIT_OBJECT_0 – обьект просигналился
3. WAIT_TIMEOUT – таймаут
4. WAIT_FAILED – смотрим GetLastError
Делаете так:
DWORD dwTimeOut;
HANDLE hEvent;
DWORD TimerFunc(LPVOID pParam)
{
__ // Инициализация
__ BOOL bWork=TRUE;
__ while(bWork)
__ {
____ DWORD dwStat=WaitForSingleObject(hEvent,dwTimeOut);
____ switch(dwStat)
____ {
______ case WAIT_OBJECT_0:
______ {
________ // hEvent просигнален
________ ResetEvent(hEvent);
________ if(!InterlockedCompareExchange(&dwTimeOut,0,0))
________ // если таймаут=0 завершаемся, тоже синхронно!!!
__________ bWork=FALSE;
________ break;
______ }
______ case WAIT_TIMEOUT:
______ {
________ // Делаем периодическую работу
________ break;
______ }
______ case WAIT_FAILED:
______ {
________ bWork=FALSE;break;// завершаемся
________ // либо пробуеми еще раз
________ // но если GetLastError() вернул ERROR_INVALID_HANDLE – значит плохой hEvent
______ }
____ }
__ }
__ // делаем деинициализацию
}
void OnChangeTimeOut(DWORD dwNewTimeOut) // изменили интервал
{
__ // Обязательно синхронно!!!!
__ InterlockedExchange(&dwTimeOut, dwNewValue);
__ // Дернуть hEvent чтобы применить интервал
__ SetEvent(hEvent);
}
void OnExit() // Если пора выхдить
{
__ // Обязательно синхронно!!!!
__ // интервал=0 – призрак завершения работы
__ IntelockedExchange(&dwTimeOut,0);
__ SetEvent(hEvent);
}
30 апреля 2008 в 19:04
Про приоритеты сообщений тоже читал и нарывался, подтверждаю.
Можно так:
Создать событие для досрочного освобождения потока.
Ожидаем событие с таймаутом (WaitForSingleObject) на время равное апдейту.
После выхода из WaitForSingleObject, проверяем переменную статуса, а по ней уже решаем, завершать поток, перерисовывать окно или уйти на ожидание с новым таймаутом, возможно измененным.
Рисовать обязательно на канве окна напрямую а не через WM_PAINT.
Удачи.
30 апреля 2008 в 19:03
Если WM_TIMER приходит через интервал, сравнимый со временем обработки WM_PAINT, то всё логично. Они же в очередь становятся. Что значит "если постоянно что-то рисовать на окошке"? Значит ли это, что работы по рисованию действительно очень много?
30 апреля 2008 в 19:00
Это реализация будет корявой, а не поток.
Курить в сторону CreateEvent, SetEvent, WaitableTimer (хотя он наверное тут лишний, лучше через Timeout), WaitForSingleObject, WaitForMultipleObjects
30 апреля 2008 в 17:03
Ну, про дополнительный поток я сразу подумал, но есть свои нюансы:
на сколько я понимаю, WFSO полностью приостанавливает поток до истечения интервала времени, и если интервал например 10 секунд, то корректно завершить поток при выходе из приложения будет проблематично.
К тому же, если установить для начала большой интервал, а потом юзверь (прога, как ни прискорбно, все же создается для того чтобы ей пользовались) сразу захочет изменить интервал на очень маленький – изменение вступит в силу только после того как потом вновь будет запущен (интервал для WFSO) истечет, т.е не скоро.
так что дополнительный поток, похоже, сделает прогу карявой и ненеадежной, так что в идеале хотелось бы переложить ответственность за измерение времени на Виндовзину, а еще при этом хочется быть уверенным, что сообщение от таймера долетит до оконной процедуры.
30 апреля 2008 в 14:04
я тоже что-то о приоритетах сообщений не слышал… или пользуете callback функцию, что всёравно ничего не изменит, или создвете поток который в цикле ждет event WFSO-ом с нужным вам таймаутом. Таймаут вышел – сделали что-то, опять ждете. Если надо завершатся – подняли event – WSFO его поймал, деинициализировали данные, сбросили event, и завершились… и никаких таймеров не нужно…
30 апреля 2008 в 11:05
Расскажи, а) что ты такое постоянно отрисовываешь на окошке и б) с каким интервалом у тебя должен работать таймер.
30 апреля 2008 в 10:04
есть еще SetWaitableTimer итп. У WM_TIMER действительно низкий приоритет.
Как вариант, можно посмотреть MsgWaitWithMessageLoop. Ставишь нужный таймаут и все. Только не знаю его точность.
30 апреля 2008 в 9:03
Если нужно, чтобы таймер отрабатывал без задержек, то нужно не WM_TIMER ждать, а callback для него задавать, насколько я помню.
30 апреля 2008 в 5:02
а ты задумайся, почему можно набрать целое слово,а только потом оно начнет отображаться в поле ввода.
но я тоже не слышал – я читал в у Джеффри Рихтера.
30 апреля 2008 в 4:02
что-то я не слышал о такой вещи, как приоритет сообщений