![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Messages & TThread [D6, Win2k]
Dynamit © (2002-07-25 14:01:00)Уважаемые Мастера, помогите: не обрабатываются сообщения, посланные потоку (ThreadID) командой PostThreadMessage.
Вот как тут не плакать :(
Digitman (2002-07-30 09:06:00) [21]Ну и ? Хочешь сказать, что брейкпойнт в теле обработчика PM_THREADCMD не "ловится" ?
Dynamit (2002-07-30 09:00:00) [22]Проверил. поле lpmsg.Message=1135
Вывел на экран константу PM_THREADCMD - тоже 1135
????
Digitman (2002-07-30 08:30:00) [23]То есть все же "1" возвращает ? Ну, значит, сообщение успешно получено и выбрано из очереди.
поставь брейкпойнт на строчке с Dispatch() и посмотри, чему равно значение поля lpmsg.Message. Это должно быть одно из значений , объявленных тобой в кач-ве констант PM_ENDTHREAD, PM_THREADCMD. Если ни то ни другое, тогда понятно, почему Dispatch() не отрабатывает ожидаемым образом.
Dynamit (2002-07-29 17:08:00) [24]Да нет же, я же писал в ответ на это:
> код возврата сообщит о "неполадках". См. описание GetMessage()
> в хэлпе
Digitman (2002-07-29 16:06:00) [25]Как это - "положительное" ??????????
Вот это
-1 !?!
я что ли написал ???????????
Dynamit (2002-07-29 15:46:00) [26]ThreadId - в порядке (т.е. равен GetCurrentThreadId).
Мало того, проверил по шагам выполнение цикла обработки сообщений потока (не в отладчике, а через вывод на экран), получилось, что сообщения приходят, а обработчики сообщений не запускаются :(
Может к методу Dispatch() нужно еще что-то выполнить?
Ошибки нет - т.к. GetMessage() возвращает положительное значение.
Digitman (2002-07-29 14:54:00) [27]hWnd д.б. равным 0 - поток получает только сообщения, адресованные ему и никому другому.
А что говорит GetLastError() ?
Вот это вот :
If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle.
наводит на подозрения, что у тебя не доп.поток, а основной ...
GetCurrentThreadId = ThreadId ?
Dynamit (2002-07-29 14:32:00) [28]Но из неполадок там всего лишь -1 !?!
Нет, неполадок вроде нет (не уверен). Провел множество экспериментов, а результат таков:
Цикл действительно бесконечен при отсутствии сообщений, но он не выполняет тело цикла (что плохо для программы), а ждет сообщение (хоть какое-нибудь). Т.е. GetMessage() - команда с ожиданием.
Попробовал все вернуть к старой конструкции - когда GetMessage() выполняется по If, но и тут меня постигла неудача.
Также протестировал PeekMessage(), но результата также не добился. Все время получал код возврата - 0. Не знаю, как объяснить мои неудачи, поэтому пишу все, что происходило.
Может еще как нибудь можно поотлаживать, я не знаю...
Сообщение потоку отсылается точно, но не приходит.
И вопрос в догонку: надо ли мне в параметрах Message идентифицировать запрос с помощью WParam или LParam, или поток получает только сообщения, посланные ему не смотря на то, что в параметрах GetMessage в качестве hWnd - 0?
Digitman (2002-07-29 12:07:00) [29]Что ж, будем учиться азам отладки)
Временно не посылай потоку никаких сообщений - поток с таким вот "пустым" циклом после старта должен "зависнуть" на GetMessage(). Если так, однозначно - GetMessage() вызывается корректно и ждет прихода сообщений. Если не ждет и сразу завершается , код возврата сообщит о "неполадках". См. описание GetMessage() в хэлпе
Dynamit (2002-07-29 08:59:00) [30]Ладно, по порядку:
Я набил в методе Execute основной цикл
While ((Not Terminated) And (GetMessage(lpmsg,0,0,0))) Do
Begin
{...}
End
И при первой же проверке он вылетел по проверке условия и естественно не выполнил свое тело, что привело к зацикливанию программы, т.к. дольнейшие действия определяются приходом сообщений от потока (успешно/неуспешно).
Свойство Terminated не может быть True - некому установить, поэтому все подозрения на GetMessage(lpmsg,0,0,0).
Почему, что и как - я пока не понимаю.
(P.S. Походы - великая вещь!!!)
Digitman (2002-07-26 16:32:00) [31]Черт с ним, с жаргоном. Но "не пашет" - это как минимум несерьезно для человека, воистину пытающегося разобраться до тонкостей в непонимаемом.
Давай говорить конкретными фактами.
Это дает и мне немалый стимул к профессиональному разговору, и тебе - гораздо больший шанс получить точную рекомендацию. Ок ?
Dynamit (2002-07-26 16:25:00) [32]Вообще-то странно, что в сети и без жаргона....
Меня как раз и считают отсталым за разговор без жаргона :)
Даллее, спасибо за помощь - она действительно пригодилась - но все же не повод обвинять в дилетанстве человека, не зная его в лицо!!! Я пытался сохранить разговор в духе доброго общения, но каждый раз вместе с помощью получаю подзатыльник - а разве это культурно? Это похуже жаргона - относиться ко всему человечеству как к умственно отсталым!!
Я ухожу в поход на выходные, так что досвиданья, и еще раз спасибо.
Тредсы я конечно добью... Если чего - можно по мылу - я люблю получать письма (без спама)
Не держи зла ;)
Dynamit :o)
Digitman (2002-07-26 15:53:00) [33]>Dynamit
Значит так, сударь :
Выражение "не пашет" - для меня ничего не значит, кроме поводов усомниться в твоем профессионализме ... Скорее это даже - признак откровенного дилетантства в программинге ... если я не прав - поставь меня на место КОНКРЕТНЫМИ аргументами, а не пустым трепом ! И без жаргона !
Dynamit (2002-07-26 15:23:00) [34]Зря меня в таком обвинять не стоит - не первый год в танке!
Вот как нибудь встретишь - всякое бывает - тогда и поговорим про каноны булевой арифметики (не алгебры).
А по поводу темы разговора - я же не просто так писал - оно действительно не пашет, причем даже при первом запуске!!
Кстати, прога на самом деле порождает по мере необходимости потоки с сокетами к DB400 и удерживает сессии, пока не кирдык!
Digitman (2002-07-26 14:53:00) [35]>>Нет, так не пойдет - если GetMessage вернет фальш, то цикл
>>закончится, а у меня он только по приходу месги должен
>>терминатиться.
"GetMessage вернет фальш", если кто-либо пошлет потоку сообщение WM_QUIT. Ты его посылаешь ? Нет. А за тебя никто этим не будет заниматься. Так что, в принципе, можешь даже свое PM_ENDTHREAD выкинуть - просто посылай WM_QUIT, и цикл прервется.
а по поводу этого :
>>If (A) And (B) Then
>> Cmd;
>>А и В - суть логические выражения.
>>Дк вот, если А - Истина, то выражение выполниться независимо >>от В (проверял в отладчике!!). Помогает только скобка:
>>If ((A) And (B)) Then
>> Cmd;
Полная чушь. Ты чего-то недоглядел, а пытаешься рушить все каноны булевой алгебры)))
Dynamit (2002-07-26 14:32:00) [36]Нет, так не пойдет - если GetMessage вернет фальш, то цикл закончится, а у меня он только по приходу месги должен терминатиться.
И еще, встретил я тут как-то один глюк:
If (A) And (B) Then
Cmd;
А и В - суть логические выражения.
Дк вот, если А - Истина, то выражение выполниться независимо от В (проверял в отладчике!!). Помогает только скобка:
If ((A) And (B)) Then
Cmd;
Так что... но это не по теме :)
Digitman (2002-07-26 13:59:00) [37]Ну, я бы сделал так (насколько я понял, чего ты вообще планировал сделать) :
Procedure TQueryThread.PMThreadCmd(var Msg: TMessage);
Begin
{...} // здесь - собственно исполнение некоей команды
End;
procedure TQueryThread.PMEndThread(var Msg: TMessage);
begin
Terminate; // взводим флаг терминирования
end;
procedure TQueryThread.Execute;
Var
lpmsg: MSG;
begin
try
Try
While (Not Terminated) and GetMessage(lpmsg,0,0,0) Do
Dispatch(lpmsg.Message);
Finally
{...}
End;
except
{...}
End;
end;
Dynamit (2002-07-26 13:27:00) [38]Дк все то же самое, только вот:
procedure TQueryThread.Execute;
Var
lpmsg: MSG;
begin
Try
with QueryForm do
begin
While (Not Terminated) Do
Begin
If UCmd=1 Then
Begin
{...}
UCmd:=0;
End Else
Begin
While Not GetMessage(lpmsg,0,0,0) Do
Dispatch(lpmsg.Message);
End;
End;
End;
Finally
{...}
End;
end;
Digitman (2002-07-26 12:39:00) [39]Ну, ты внес исправления-то ? Въехал в проблему ? Показывай код тогда)
Dynamit (2002-07-26 12:02:00) [40]Вот блин :3( Нифига не выходит - все равно не ловит месг, зараза такая!!!
Может еще чего??