Доброе время суток, уважаемые форумчане!!! столкнулся с одной задачей, в силу своего ламерства не могу придумать как ее решить. Суть следующая: имеется юнит работы с ком-портом, который содержит следующую функцию
| Код | //функция дочернего потока, обрабатывающего эвенты порта //параметр введен для того, чтобы каждый (их стартует два) //экземпляр работал с переменными "своего" порта function WorkComm(var Parms : TComVar) : longint; stdcall; var Kols,Mask,Trans,Errs : DWord; Ovr : TOverlapped; Buff : array [0..511] of byte; Modems, LenPacket : DWord; Reciv : pointer; begin Result := 0; //инициализируем TOverlapped структуру FillChar(Ovr,SizeOf(TOverlapped),0); Ovr.hEvent := CreateEvent(nil,TRUE,FALSE,#0); //стартуем бесконечный цикл while not Parms.Terminated do with Parms do begin if Terminated then break; Mask := 0; //запрашиваем (ожидаем) маску эвентов if not WaitCommEvent(cId,Mask,@Ovr) then begin //обрабатываем "отложенную" операцию ввода-вывода if (GetLastError() = ERROR_IO_PENDING) and (WaitForSingleObject(Ovr.hEvent,INFINITE)=Wait_Object_0) then GetOverlappedResult(cId,Ovr,Trans,False); end; //очищаем ошибки с получением статуса порта, обязательно!!! ClearCommError(cId,Errs,@Stat); if Terminated then break; if Mask = 0 then continue; if (Mask and EV_RXCHAR) = EV_RXCHAR then begin //если принят хотя бы один байт if Stat.cbInQue < 512 then Kols := Stat.cbInQue else Kols := 512; if Terminated then break; //пытаемся читать принятые байты ReadFile(cId,Buff,Kols,Kols,@Ovr); if Terminated then break; if Kols > 0 then begin //если хоть один байт считан - переносим в буфер накопления Move(Buff,RecivBuff[CntByte],Kols); inc(CntByte,Kols);
while CntByte >= 1 do begin // while CntByte >= sizeof(TPacketHeader) do begin //пока количество принятых байт больше длины синхрочасти преамбулы //пытаемся засинхронизоваться // if Cardinal((@RecivBuff[0])^) = Sync if RecivBuff[0] = Sync then begin if CntByte >= kols then begin //если синхропосылка стоит вначале накопленного буфера //и общая длина принятых байт больше или равна длине //преамбулы плюс количество байт, указанное в преамбуле LenPacket := kols;
//если этот экземпляр потока работает с СОМ1 //получаем указатель, переписываем туда все байты пакета GetMem(Reciv,LenPacket); Move(RecivBuff,Reciv^,LenPacket); //шлем сообщение основному потоку PostMessage(fmMain.Handle,cmRxByte,Integer(Reciv),LenPacket);
//удаляем из накопленного буфера байты обработанного выше пакета dec(CntByte,LenPacket); Move(RecivBuff[LenPacket],RecivBuff[0],CntByte); end //в случае неполного принятия пакета (синхропосылка вначале буфера) else break; end else begin //в случае, если начало накопленного буфера не содержит //синхропосылку, удаляем первый байт со сдвигом всего буфера dec(CntByte); Move(RecivBuff[1],RecivBuff[0],CntByte); end; // end; end; end; end; if ((Mask and EV_DSR) = EV_DSR) or ((Mask and EV_CTS) = EV_CTS) then begin //если случилось изменение модемных линий if Terminated then break; if Master then begin //если этот экземпляр потока работает с СОМ1 //запрашиваем текущее состояние модемных линий GetCommModemStatus(cId,Modems); //получаем указатель GetMem(Reciv,sizeof(TModems)); //заполняем указатеь TModems(Reciv^).DSR := (Modems and MS_DSR_ON) = MS_DSR_ON; TModems(Reciv^).CTS := (Modems and MS_CTS_ON) = MS_CTS_ON; //шлем сообщение основному потоку PostMessage(fmMain.Handle,cmModem,Integer(Reciv),0); end; end; end; CloseHandle(Ovr.hEvent); end;
|
как видно из описания в начале функции это функция дочернего потока, обрабатывающего эвенты порта, которая передает данные основному потоку через
| Код | PostMessage(fmMain.Handle,cmRxByte,Integer(Reciv),LenPacket);
|
и вроде все правильно и все работает. Но тут мне захотелось все это удовольствие запихнуть в длл, соответственно формы fmMain, которой передается сообщение нет!!! и тут загвоздка, как передать в основной поток (если я правильно выражаюсь) данные????
|