Вниз
Скачать: 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 вся ветка

Скачать: CL | DM;



Память: 0.46 MB
Время: 0.037 c
1-1165021404
allrussia
2006-12-02 04:03
2007.02.11
Закрепление и привязка компонентов на форме


15-1169475091
ert
2007-01-22 17:11
2007.02.11
У кого есть готовый программа


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


2-1169547358
Kymbat
2007-01-23 13:15
2007.02.11
Delphi i AdoConnection


15-1169457949
vitv
2007-01-22 12:25
2007.02.11
Сервер на Linux или Win2003




   Наверх