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

Вниз

Очередь сообщений   Найти похожие ветки 

 
Цукор5   (2009-12-24 15:48) [0]

Есть некоторый класс.
В одном из методов данного класса "крутится" очередь сообщений

while GetMessage(Msg,0,0,0) do
   begin
   ...
       case Msg.message of
         WM_USER+8: что-то
   ...
   end;


Также есть еще один метод, который должен послать сообщение в эту очередь. Очередь приняв эту сообщение должна что-то выполнить И РЕЗУЛЬТАТ ПЕРЕДАТЬ обратно.

Сделал для пробы так :

function TМойКласс.GetAny: String;
 FAny:=""; // FANy вынесен в private. Я знаю, что это от Лукавого
 PostThreadMessage(FMsgThreadID,WM_USER+8,0,0); // посылаем сообщение
 Sleep(100); // ждем
 Result:=FAny;


Но это, естественно, неверно. Как правильно дождаться того, что очередь выполнила что-то? И как это что-то(в моем случаи String) передать вызывающему методу ? Есть предположение создать TEvent и дожидаться его выполнения WaitFor - это для определения, что очередь выполнила нужные мне действия. Правильный ли ход моих домыслов ? Но как передать строку ?


 
Игорь Шевченко ©   (2009-12-24 16:23) [1]


> Очередь приняв эту сообщение должна что-то выполнить И РЕЗУЛЬТАТ
> ПЕРЕДАТЬ обратно.


Кому ?


 
Юрий Зотов ©   (2009-12-24 16:23) [2]

Сообщение WM_USER+8 обязательно должно пройти через очередь потока? Нельзя ли послать его через SendMessage какому-нибудь окну? Тогда вопрос решается автоматически.

Другой вариант - при отсылке сообщения его параметром передать Self и уйти в цикл типа этого:
while not Handled do Sleep(1)
где Handled - свойство Self.

После обработки сообщения поток выставляет это свойcтво в TRUE и цикл завершается.


 
Игорь Шевченко ©   (2009-12-24 16:24) [3]

Для обмена сообщениями с возвратом посылающему используется функция SendMessage, без всякой очереди.


 
Игорь Шевченко ©   (2009-12-24 16:28) [4]


> Но это, естественно, неверно. Как правильно дождаться того,
>  что очередь выполнила что-то?


если же нужно обязательно прорываться через PostThreadMessage, то тогда разумно поступить так:

1. создать событие с автоматическим сбросом
2. договориться с получателем, где будет лежать результат
3. послать сообщение
4. ждать на этом событии
5. прочитать результат из оговоренного места

получатель, приняв сообщение, кладет результат и устанавливает событие (это если он в отдельном потоке, разумеется :)


 
Цукор5   (2009-12-24 16:46) [5]

2 Игорь Шевченко ©   (24.12.09 16:28) [4]

НУ...вроде так и сделал. Только "оговоренное место" у меня в private класса определено.

Вот код:

WM_USER+10:
          begin
            PAny:=PMyAnyData(Msg.wParam);
            I:=LineOpen(FLineApp,PAny.ModemID,FLine,TApiV,0,DWord(Self),
              LINECALLPRIVILEGE_NONE, LINEMEDIAMODE_DATAMODEM,CallParams);
            if not TapiFailed(I) then
            begin
              VarStr := nil;
              try
                GetMem(VarStr, VarStrAllocSize);
                VarStr.dwTotalSize := VarStrAllocSize;
                I:=lineGetId(FLine, 0, 0, LINECALLSELECT_LINE, VarStr, "comm/datamodem/portname");
                if not TapiFailed(I) then
                begin
                  SetString(PortName, PChar(Cardinal(VarStr) + VarStr.dwStringOffset), VarStr.dwStringSize - 1);
                  FPortName:=PortName;
                end;
              finally
                FreeMem(VarStr);
              end;
            end;
            SetEvent(PAny.Event);
            Dispose(PAny);
          end;

function TDial.GetPortModem(ModemID: DWord): String;
 var FEvent:THandle;
 I:DWord;
 Q:PMyAnyData;
begin
 FPortName:="";
 //
 FEvent:=CreateEvent(nil,True,False,"");
 New(Q);
 Q^.ModemID:=ModemID;
 Q^.Event:=FEvent;
 PostThreadMessage(FMsgThreadID,WM_USER+10,wParam(Q),0);
 while True do
 begin
   I:=WaitForSingleObject(FEvent,100);
   if I=WAIT_OBJECT_0 then Break;
 end;
 ResetEvent(FEvent);
 CloseHandle(FEvent);
 //
 Result:=FPortName;
end;



 
Цукор5   (2009-12-24 16:47) [6]

Забыл это

type
 TMyAnyData = packed record
   ModemID:DWord;
   Event:THandle;
 end;
 PMyAnyData = ^TMyAnyData;


 
Игорь Шевченко ©   (2009-12-24 17:29) [7]


>  while True do
>  begin
>    I:=WaitForSingleObject(FEvent,100);
>    if I=WAIT_OBJECT_0 then Break;
>  end;


while True do
begin
  I := WaitForSingleObject(FEvent,100)
  if I = WAIT_OBJECT_0 then
    Break;
 else if I <> WAIT_TIMEOUT then
   RaiseLastOSError;
end;

иначе при ошибке так и будешь в цикле висеть


 
Игорь Шевченко ©   (2009-12-24 17:30) [8]


>  ResetEvent(FEvent);
>  CloseHandle(FEvent);


Reset не нужно


 
Игорь Шевченко ©   (2009-12-24 17:32) [9]

кстати, непонятно, зачем вообще нужен цикл для ожидания.
напиши тогда уж
WaitForSingleObject(..., INFINITE)


 
Цукор5   (2009-12-24 17:44) [10]

2 Игорь Шевченко ©   (24.12.09 17:32) [9]

Все дело в том, что этот метод GetPortModem я вызываю из главной формы.
INFINITE не поставил по причине боязни...а вдруг и вправду сообщение не дойдет или еще что. Я ж буду тогда висеть. Да и с циклом тоже буду висеть))

Даже не знаю что и делать. Но вроде все работает - что, собственно, радует.


 
Цукор5   (2009-12-24 17:46) [11]

2 Игорь Шевченко ©   (24.12.09 17:30) [8]

> Reset не нужно


Согласен. То "автоматом" случилось.


 
Игорь Шевченко ©   (2009-12-24 17:47) [12]


> INFINITE не поставил по причине боязни...а вдруг и вправду
> сообщение не дойдет или еще что


Тогда разумный интервал ожидания


 
Цукор5   (2009-12-24 17:54) [13]

2 Игорь Шевченко ©   (24.12.09 17:47) [12]


> Тогда разумный интервал ожидания


Да, так и сделал. Низкий Вам поклон !!!

 PostThreadMessage(FMsgThreadID,WM_USER+10,wParam(Q),0);
 WaitForSingleObject(FEvent,1000);
 // уже не важно WAIT_OBJECT_0 или WAIT_TIMEOUT все равно выйдет через 1 сек
 CloseHandle(FEvent);
 Result:=FPortName;



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

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

Наверх




Память: 0.49 MB
Время: 0.004 c
15-1260978929
AntonioBanderas
2009-12-16 18:55
2010.02.28
PDF


15-1260912620
Юрий
2009-12-16 00:30
2010.02.28
С днем рождения ! 16 декабря 2009 среда


11-1212303624
Сашик
2008-06-01 11:00
2010.02.28
Функция EncodeDate в KOL


1-1211311780
@!!ex
2008-05-20 23:29
2010.02.28
Перехват копирования в Clip Board


1-1226920476
Franzy
2008-11-17 14:14
2010.02.28
Out of Memory - непонятки





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский