Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.08.2015, 17:03   #1
ninja2
Форумчанин
 
Регистрация: 13.08.2015
Сообщений: 193
По умолчанию Почему не добавляется в очередь сообщение WM_TIMER????

Вот код кнопки которая создает таймер и в цикле мониторит сообщения
Код:
void Ctest_GetMessageDlg::OnBnClickedButton1()
{
	// TODO: добавьте свой код обработчика уведомлений
	SetTimer(1,1000,NULL);//установка таймера
//	::PostMessage(GetSafeHwnd(),WM_TIMER,0,0);
//	BOOL test(true);
	for(int i=0;i<1000000;i++)
	{
//		if(test){SetTimer(1,1000,NULL); test=false;}

		UpdateData(TRUE);
		m_iEdit=i;
		UpdateData(FALSE);
		TRACE("i=%d\n",i);
//		Sleep(1000);
		MSG message;
		if(::GetMessage(&message,NULL,0,0))
		{
			::TranslateMessage(&message);
			::DispatchMessage(&message);
		}
	}
}
вот OnTimer
Код:
void Ctest_GetMessageDlg::OnTimer(UINT_PTR nIDEvent)
{
//	AfxMessageBox(L"OnTimer");
	// TODO: добавьте свой код обработчика сообщений или вызов стандартного
	for(int i=0;i<100000;i++)
	{
		TRACE("--------------k=%d\n",i);
		if(m_iEdit==100) KillTimer(1);
	}
	CDialogEx::OnTimer(nIDEvent);
}
У меня не посылаются сообщения WM_TIMER, а почему? Они посылаются когда я закрываю приложение????

Если я вручную посылаю, тогда да WM_TIMER добавляется в очередь, а сама Windows его не добавляет почемуто???

Это я тестирую программку на зависание в обработчике сообщения, но ничего у меня не получается таймер вызывать. Я вообще подозреваю что сам обработчик кнопки не отпускает функцию SetTimer и получается что функция как бы не установлена, а будет она установлена только после того как обработчик кнопки завершится, это так да?

добавил в OnInitDialog
SetTimer(1,10000,NULL);//установка таймера
И все рамно не посылаются сообщения WM_TIMER?????

Последний раз редактировалось ninja2; 18.08.2015 в 17:14.
ninja2 вне форума Ответить с цитированием
Старый 18.08.2015, 17:54   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

WM_TIMER и WM_PAINT нельзя посылать вручную.
Зачем это надо - SetTimer пошлет когда надо.
waleri вне форума Ответить с цитированием
Старый 18.08.2015, 18:13   #3
ninja2
Форумчанин
 
Регистрация: 13.08.2015
Сообщений: 193
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
WM_TIMER и WM_PAINT нельзя посылать вручную.
Зачем это надо - SetTimer пошлет когда надо.
Так он не посылает, от эта функция запускает таймер
Код:
void Ctest_GetMessageDlg::OnBnClickedButton1()
{
	// TODO: добавьте свой код обработчика уведомлений
	SetTimer(1,500,NULL);//установка таймера
//	::PostMessage(GetSafeHwnd(),WM_TIMER,0,0);
	for(int i=0;i<1000000;i++)
	{
		UpdateData(TRUE);
		m_iEdit=i;
		UpdateData(FALSE);
		TRACE("i=%d\n",i);
		MSG message;
		if(::GetMessage(&message,NULL,0,0))
		{
			::TranslateMessage(&message);
			::DispatchMessage(&message);
		}
	}
}
и от сам таймер
Код:
void Ctest_GetMessageDlg::OnTimer(UINT_PTR nIDEvent)
{
	AfxMessageBox(L"OnTimer");
	// TODO: добавьте свой код обработчика сообщений или вызов стандартного
	for(int i=0;i<20;i++)
	{
		TRACE("--------------k=%d\n",i);
	//	if(m_iEdit==100) KillTimer(1);
	}
	CDialogEx::OnTimer(nIDEvent);
}
И я не получаю сообщения WM_TIMER. SetTimer их не посылает

Цитата:
Сообщение от waleri Посмотреть сообщение
WM_TIMER и WM_PAINT нельзя посылать вручную.
Зачем это надо - SetTimer пошлет когда надо.
Вот смотри простой тест на зависание окна с помощью обработчика сообщений, я делаю от так в обработчике кнопки
Код:
void Ctest_GetMessageDlg::OnBnClickedButton1()
{
	// TODO: добавьте свой код обработчика уведомлений
//	SetTimer(1,3000,NULL);//установка таймера
//	::PostMessage(GetSafeHwnd(),WM_TIMER,0,0);
	for(int i=0;i<1000000;i++)
	{
		UpdateData(TRUE);
		m_iEdit=i;
		UpdateData(FALSE);
		TRACE("i=%d\n",i);
		MSG message;
		int k=0;
		if(::GetMessage(&message,NULL,0,0))
		{
			k++;
			::TranslateMessage(&message);
			::DispatchMessage(&message);
		}
	}
}
Дальше добавляю обработчик нажатия левой клавиши мышки
Код:
void Ctest_GetMessageDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: добавьте свой код обработчика сообщений или вызов стандартного
	for(int i=0;i<1000000;i++)
	{
		TRACE("          d=%d\n",i);
	}
	CDialogEx::OnLButtonDown(nFlags, point);
}
Запускаю, все нормально работает, окошко не зависло, все отлично работает, сообщения все от windows норм обрабатываются. Кликаю левой клавишей мышки, у меня в очередь попадает сообщение от мышки, срабатывает обработчик и он загружает полностью процессор и кнопки недоступны становятся. Все отлично работает.

Почему такое я немогу сделать с помощью WM_TIMER??? получается WM_TIMER не посылается????

Можешь попробовать протестить, WM_TIMER не посылается в очередь.

И чем отличается функция PeekMessage от GetMessage ????

Последний раз редактировалось Stilet; 18.08.2015 в 21:26.
ninja2 вне форума Ответить с цитированием
Старый 18.08.2015, 19:53   #4
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

WM_TIMER WM_PAINT имеют "защиту" от зависания.
ВСЕ такие сообщения внутри очереди сообщений ДО передачи в программу собираются в ОДНО сообщение.
т.е. в любой момент времени вы очереди может быть НЕ более одного WM_PAINT WM_TIMER.
все "лишние" "пропадают".
по сути это флаги, которые многократно взводятся системой, и разово сбрасываются при выборке соответствующих сообщений приложением.
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 18.08.2015 в 19:57.
evg_m вне форума Ответить с цитированием
Старый 18.08.2015, 20:16   #5
ninja2
Форумчанин
 
Регистрация: 13.08.2015
Сообщений: 193
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
WM_TIMER WM_PAINT имеют "защиту" от зависания.
ВСЕ такие сообщения внутри очереди сообщений ДО передачи в программу собираются в ОДНО сообщение.
т.е. в любой момент времени вы очереди может быть НЕ более одного WM_PAINT WM_TIMER.
все "лишние" "пропадают".
по сути это флаги, которые многократно взводятся системой, и разово сбрасываются при выборке соответствующих сообщений приложением.
Нет там в коде не получается выловить сообщение WM_TIMER потому что функции UpdateData посылают свои сообщения, нужно два раза выбирать сообщения из очереди, тогда таймер попадает.

нипойму ниче чем функция PeekMessage отличается от GetMessage???
Вот код с функцией PeekMessage
Код:
void Ctest_GetMessageDlg::OnBnClickedButton1()
{
	// TODO: добавьте свой код обработчика уведомлений
//	m_nTimer=SetTimer(1,1000,NULL);//установка таймера
//	ASSERT(m_nTimer!=0);
//	::PostMessage(GetSafeHwnd(),WM_TIMER,0,0);
	MSG message;
	for(int i=0;i<1000000;i++)
	{
		UpdateData(TRUE);
		m_iEdit=i;
		UpdateData(FALSE);
		TRACE("i=%d\n",i);
//		if(::GetMessageA(&message,NULL,0,0);
		if(::PeekMessage(&message,NULL,0,0,PM_REMOVE))
		{
			::TranslateMessage(&message);
			::DispatchMessage(&message);
		}
	}
}
и код обработчик левой клавиши мышки
Код:
void Ctest_GetMessageDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: добавьте свой код обработчика сообщений или вызов стандартного
	for(int i=0;i<1000000;i++)
	{
		TRACE("          d=%d\n",i);
	}
	CDialogEx::OnLButtonDown(nFlags, point);
}
Кликаю по кнопке, затем кликаю по левой клавише мышки и у меня зависает программка, хотя пишут что эта функция вроде не должна блокировать или как она работает кто знает?

Последний раз редактировалось Stilet; 18.08.2015 в 21:26.
ninja2 вне форума Ответить с цитированием
Старый 18.08.2015, 20:31   #6
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
потому что функции UpdateData посылают свои сообщения,
Да и только когда очередь сообщений будет пуста, тогда и только тогда придет время отправки(получения) WM_PAINT WM_TIMER.
т.е. ПОСЛЕ обработки сообщений от UpdateData.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 18.08.2015, 20:43   #7
ninja2
Форумчанин
 
Регистрация: 13.08.2015
Сообщений: 193
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
Да и только когда очередь сообщений будет пуста, тогда и только тогда придет время отправки(получения) WM_PAINT WM_TIMER.
т.е. ПОСЛЕ обработки сообщений от UpdateData.
Ну ты видел у меня в коде перед выборкой сообщений идет UpdateData и хз. куда они добавляются, по идее должны в конец очереди добавлятся, а вдруг они добавляются в начало очереди тогда конечно у меня сообщения WM_TIMER не получается выбрать. Они добавляются это полюбом. Я от только разобрал что такое PeekMessage и GetMessage. От можно проверить есть ли в очереди WM_TIMER используя цыкл while(PeekMessage) щас проверю.

Только проверил с while(PeekMessage) все вызывается. Вообще походу если в одном потоке работаем то чтобы цыкл не зависал, нужно обрабатывать сообщения в цыкле. Даже обработчик один и тот может подвесить прогу если зацыкление сделать в нем. Тут походу Функции из обработчиков выполняются попорядку а не паралельно как я думал. Да в одном потоке функции походу не могут выполняться паралельно, просто эмитация получается или как????

Что вообще произойдет если я допустим вызвал из кнопки сообщение WM_TMER, а затем из обработчика WM_TIMER выловил снова это же сообщение WM_TIMER и обработал его?? Как вы думаете? Варианты: 1. вызовется функция как из функции. 2. эта функция прекратит свою работу и вызовется новая функция? Наверно вызовется функция как из функции да? Это можно проверить.

Да проверил, вроде получается вызов функции из функции, потом возврат и дальше продолжается функция которая вызвала. Да похоже работа в одном потоке она идет как в одном потоке, а то просто создается впечатление что оно работате в несколько патоках или паралельно. То что мы из фукнции работающей в данный момент вызываем функции мелкие обработчики и они что то делают, ну это как бы просто создает впечатление паралельной работы, а по ходу все оно идет по порядку как и в консоли?????. Да по порядку должно быть, потому что один поток, по другому не может быть. Идет один поток и вызовы функций наверно.

Цитата:
Сообщение от evg_m Посмотреть сообщение
Да и только когда очередь сообщений будет пуста, тогда и только тогда придет время отправки(получения) WM_PAINT WM_TIMER.
т.е. ПОСЛЕ обработки сообщений от UpdateData.
Это наверно не так. Одновременно не может быть вызвано с одной функции подрят два сообщения. Сначала должно сообщение доработать, затем идет вызов следующего сообщения, обработчик доработал вернул результат, идет снова следующее сообщение или функция эта получает возможность что то делать. Если все это так, то нам без разницы сколько в очереди будет сообщений WM_PAINT или WM_TIMER правильно? Просто по порядку одна за другой функции вызовутся например пять WM_TIMER и пять раз вызовется функция подрят onTimer. Это легко проверить сгенерировал 5 раз подряд WM_TIMER и в дебаге посмотреть. Я щас специально это проверю.

Проверил, отослал 5 WM_TIMER и 5 выловил в очереди, так что может быть сколько угодно в очереди .

Последний раз редактировалось ninja2; 18.08.2015 в 21:33.
ninja2 вне форума Ответить с цитированием
Старый 18.08.2015, 21:50   #8
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Вот вам "каноническое" Windows приложение - разберитесь сначала что к чему в нем, иначе вам будет трудно в дальнейшем.

http://blogs.msdn.com/b/oldnewthing/.../23/54576.aspx
waleri вне форума Ответить с цитированием
Старый 18.08.2015, 22:29   #9
ninja2
Форумчанин
 
Регистрация: 13.08.2015
Сообщений: 193
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Вот вам "каноническое" Windows приложение - разберитесь сначала что к чему в нем, иначе вам будет трудно в дальнейшем.

http://blogs.msdn.com/b/oldnewthing/.../23/54576.aspx
Я такое разбирал, только посложнее, там WndProc, только у меня там switch был побольше. Та это WinAPI чисты в нем разбираться смысла нету. Оно не поможет понять как в MFC работает. Я такую примерно программку разбирал на winapi и диалог с кнопками создавал, только это давно было, лучше MFC, тут все легче. Там чтобы диалог нарисовать нужно было потрудится в MFC без проблем.

От щас смотрю там цикл сообщений while(GetMessage), от я не помню в тех программах на WinApi что я разбирал был ли он, наверно ж был, просто я не обратил на него внимания , щас гляну.
Глянул я разбирал самый простой тип приложения на диалоговых окнах, там у меня небыло цикла сообщений. DialogBox в WinMain и функция Porc со свичь которая передается в DialogBox. Я за этот GetMessage первый раз слышу

Последний раз редактировалось ninja2; 18.08.2015 в 22:48.
ninja2 вне форума Ответить с цитированием
Старый 18.08.2015, 23:13   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Да, DialogBox делает обработку сама, но на этой функции далеко не уехать.

В MFC легче, потому что есть всякие wizards.
Если делать все самому руками то WINAPI проще.
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Подскажите пожалуйста почему добавляется всего одна буква из трех? Nata Golden rose Общие вопросы C/C++ 2 22.05.2014 05:29
вводим 15 элементов в очередь, затем выводим на экран эту очередь и добавил в очередь еще один элемент. Потом удаляем любой элемен Xumera C++ Builder 2 07.12.2013 13:56
Почему такое сообщение ГОСЕАН Помощь студентам 2 31.10.2011 10:21
Почему не выводится сообщение? [MI_nor] Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 8 10.04.2011 21:30
Не добавляется элемент в очередь Дырдин Общие вопросы C/C++ 2 22.04.2010 07:31