Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.02.11;
Скачать: [xml.tar.bz2];

Вниз

Использование функции MsgWaitForMultipleObjects   Найти похожие ветки 

 
Riply ©   (2007-01-24 03:11) [0]

Здравствуйте !
Натолкнулась в одной из веток форума на сабжевую функцию
и очень обрадовалась. Оказывается можно одной функцией ждать
и событие и сообщение, а не извращаться как я с комбинированием
PeekMessage и WaitForMultipleObjects. Вот здорово !
Но не тут-то было.
Совершенно неожиданно оказалось, что чтобы наслаждаться преимуществами этой функции,
надо, сначала, научиться правильно ею пользоваться :)
А вот тут и вышла загвоздка.
Берем следующую функцию:
function MsgWaitThread(pParam: Pointer): DWord;
var
Msg: TMsg;
begin
Result := 0;
while MsgWaitForMultipleObjects(1, PDWord(pParam)^, False, 10000, QS_POSTMESSAGE) = WAIT_OBJECT_0 + 1 do
 while PeekMessage(Msg, INVALID_HANDLE_VALUE, 0, WAIT_MSG_BASE + 1, PM_REMOVE) do
  if Msg.message = WAIT_MSG_BASE then
   begin
    Sleep(1000);// что-то делаем
    SetErrorList(IntToStr(Msg.lParam)); // Сохраняет строку в файл
   end;
SetErrorList("End Thread");
end;

и начинаем ей посылать сообщения:
hStopEvent := CreateEvent(nil, True, False, nil);
hThread := BeginThread(nil, 0, @MsgWaitThread, @hStopEvent, 0, ThreadID);
//.....
PostThreadMessage(ThreadID, WAIT_MSG_BASE, WAIT_MSG_WORK, 1);
PostThreadMessage(ThreadID, WAIT_MSG_BASE, WAIT_MSG_WORK, 2);
PostThreadMessage(ThreadID, WAIT_MSG_BASE, WAIT_MSG_WORK, 3);
PostThreadMessage(ThreadID, WAIT_MSG_BASE, WAIT_MSG_WORK, 4);
SetEvent(hStopEvent);
PostThreadMessage(ThreadID, WAIT_MSG_BASE, WAIT_MSG_WORK, 5);

В данном варианте мы принимаем все сообщения (1,2,3,4,5), но крутимся в цикле
"while PeekMessage" и совершенно не реагируем на SetEvent(hStopEvent)
пока не выберем все из очереди, что не есть хорошо :).
Проверять внутри этого цикла hStopEvent - возвращаться к старым "извращениям"
Попытка заменить "while PeekMessage" на "if PeekMessage",
в надежне, что MsgWaitForMultipleObjects проверит состояние hStopEvent,
и мы вернемся к нашей обработке, приводит к потере сообщений от PostThreadMessage.
В зависимости от расположения звезд, получаем от одного до трех первых.
Как можно, спокойно напевая песенку и не торопясь, обрабатывать поступающие команды,
но при первой же опасности (hStopEvent) быстро убегать ?


 
Сергей М. ©   (2007-01-24 08:31) [1]

while True do
case MsgWaitForMultipleObjects(1, PDWord(pParam)^, False, 10000, QS_POSTMESSAGE) of
WAIT_OBJECT_0: Break; //дождались события
WAIT_OBJECT_0 + 1: //в очереди есть как минимум одно сообщение
  begin
    PeekMessage(...) ; //берем одно сообщение из головы очереди
    .. //и обрабатываем его
  end;
WAIT_TIMEOUT: Break; //не дождались события
end;


 
Игорь Шевченко ©   (2007-01-24 10:47) [2]

 while not FTerminated do begin
   WaitResult := MsgWaitForMultipleObjectsEx(1, FExternalControlEvent,
      INFINITE, QS_POSTMESSAGE, 0);
   if WaitResult = WAIT_OBJECT_0 then begin
     FTerminated := true;
     Break;
   end else
     while PeekMessage(AMsg, INVALID_HANDLE_VALUE, 0, 0, PM_REMOVE) and
         not FTerminated do
       if AMsg.message = UM_INCOMINGFILE then
         ProcessFile(PString(AMsg.lParam))
       else if AMsg.message = UM_ERROR then
         HandleError(PString(AMsg.lParam));
 end;


 
Riply ©   (2007-01-24 23:22) [3]

Спасибо всем! Вроде получилось разобраться.
P.S. Мне надо было внимательнее читать Help.
"Note MsgWaitForMultipleObjects does not return if there is unread input
of the specified type in the message queue after the thread has called a
function to check the queue. This is because functions such as PeekMessage,
GetMessage, GetQueueStatus, and WaitMessage check the queue and then change
the state information for the queue so that the input is no longer considered new.
A subsequent call to MsgWaitForMultipleObjects will not return until new input
of the specified type arrives. The existing unread input (received prior
to the last time the thread checked the queue) is ignored.
"
Который раз убеждаюсь, что "посылание в MSDN" - один из самых грамотных ответов :))
P.S.S. Правда не очень уютно, когда тебя туда посылают :))



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.02.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.46 MB
Время: 0.045 c
2-1168648733
Wind
2007-01-13 03:38
2007.02.11
ANSI >UNICODE


4-1159770751
Samurai Kruche chem Jakudza
2006-10-02 10:32
2007.02.11
EnumProcesses


15-1169204495
NeyroSpace
2007-01-19 14:01
2007.02.11
И все-таки нужна ли кому-нибудь правда в нашей стране?


4-1158081492
vidiv
2006-09-12 21:18
2007.02.11
Копирование выделенного текста с Активного окна.


3-1164029298
Ольга
2006-11-20 16:28
2007.02.11
Ошибка I/O Error 103 при работе с базой данных Paradox





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский