Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.02.11;
Скачать: CL | DM;

Вниз

Использование функции 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;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.033 c
2-1169551622
Данилов Антон
2007-01-23 14:27
2007.02.11
Помогите разобраться с формой в дельфи.


15-1169440155
Zeqfreed
2007-01-22 07:29
2007.02.11
Виста это НЕ плагиат с МакОС!


15-1169092654
brother
2007-01-18 06:57
2007.02.11
для чего вообще нужно программировать под .net?


11-1147784447
chum
2006-05-16 17:00
2007.02.11
работа с кнопками в заголовках mdvXLGrid


6-1157706811
bober
2006-09-08 13:13
2007.02.11
сокеты