Спасибо. Буду пробовать разбираться.
Я, кстати, времени не терял, а пытался писать в соответствии со статьей Paul Attryde.
Вот, что у меня получилось (естественно, здесь не весь код и опущены декларации всякие):
Код: Выделить всё
PortNumber=GETINI('Communications','PortNumber',4,'.\Wcomm.ini') !Читаем номер порта из ИНИ-файла
Loc:InBuffer=GETINI('Communications','InBuffer',1024,'.\Wcomm.ini') !Входной буфер
Loc:OutBuffer=GETINI('Communications','OutBuffer',4096,'.\Wcomm.ini') !Выходной буфер
DCB:BaudRate=GETINI('Communications','BaudRate',57600,'.\Wcomm.ini') !Скорость
DCB:Parity=GETINI('Communications','Parity',0,'.\Wcomm.ini') !Четность в виде числа
CASE DCB:Parity !Преобразование четности из числа в букву
OF 1
Loc:ParityS='Y'
ELSE
Loc:ParityS='N'
END
DCB:ByteSize=GETINI('Communications','ByteSize',8,'.\Wcomm.ini') !Размер байта
DCB:StopBits=GETINI('Communications','StopBits',1,'.\Wcomm.ini') !Стоповые биты
CTO:ReadIntervalTimeout=GETINI('Communications','TimeOut',5000,'.\Wcomm.ini') !Тайм-ауты - все по 5 секунд
CTO:ReadTotalTimeoutMultiplier=GETINI('Communications','TimeOut',5000,'.\Wcomm.ini')
CTO:ReadTotalTimeoutConstant=GETINI('Communications','TimeOut',5000,'.\Wcomm.ini')
CTO:WriteTotalTimeoutMultiplier=GETINI('Communications','TimeOut',5000,'.\Wcomm.ini')
CTO:WriteTotalTimeoutConstant=GETINI('Communications','TimeOut',5000,'.\Wcomm.ini')
Loc:PortString = 'COM' & CLIP(PortNumber) !Текстовое имя порта
IF Loc:PortHandle < 1
Loc:PortHandle = CreateFile(Address(Loc:PortString), GENERIC_READ + GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL)
END
IF Loc:PortHandle=-1
MESSAGE('Невозможно создать порт' & '<10,13>' & Loc:PortHandle)
RETURN
ELSE
!MESSAGE(Loc:PortHandle)
END
IF Loc:PortHandle <> -1
!Формируем строку порта вида "9600,N,8,1"
Loc:ControlString=DCB:BaudRate & ',' & Loc:ParityS & ',' & DCB:ByteSize & ',' & DCB:StopBits
MESSAGE('Loc:ControlString: ' & Loc:ControlString, 'ControlString')
IF BuildCommDCB(Address(Loc:ControlString), Address(DCB)) <> 0
Loc:ReturnCode=SetCommState(Loc:PortHandle, Address(DCB))
IF ~Loc:ReturnCode
MESSAGE(Loc:ReturnCode)
END
Loc:ReturnCode=SetCommTimeOuts(Loc:PortHandle,Address(COMMTIMEOUTS)) !Тайм-ауты. А надо ли их настраивать?
IF ~Loc:ReturnCode
MESSAGE(Loc:ReturnCode)
END
Loc:ReturnCode=SetupComm(Loc:PortHandle,Loc:InBuffer,Loc:OutBuffer)
IF ~Loc:ReturnCode
MESSAGE(Loc:ReturnCode)
END
ELSE
MESSAGE('ERROR')
END
END
Loc:ReturnCode=GetCommState(Loc:PortHandle,Address(DCB))
IF ~Loc:ReturnCode
MESSAGE('GetCommState: ' & Loc:ReturnCode,'GetCommState')
ELSE
MESSAGE( !
'BaudRate: ' & DCB:BaudRate & '<13,10>' & !
'Parity: ' & DCB:Parity & '<13,10>' & !
'ByteSize: ' & DCB:ByteSize & '<13,10>' & !
'StopBits: ' & DCB:StopBits !
,'GetCommState' )
END
Loc:OutString='AT +MPBR=?'
Loc:Len=LEN(Clip(Loc:OutString))
Loc:ReturnCode = WriteFile(Loc:PortHandle, Address(Loc:OutString), Loc:Len, Address(Loc:BytesWritten), NULL)
IF Loc:Len <> Loc:BytesWritten
MESSAGE('Не записали все байты, которые хотели...')
ELSE
!MESSAGE('Записано байт: ' & Loc:BytesWritten & ', код возврата: ' & Loc:ReturnCode, 'WriteFile')
END
Loc:ReturnCode=SetCommMask(Loc:PortHandle, !
EV_RXCHAR + !
EV_RXFLAG + !
EV_TXEMPTY + !
EV_CTS + !
EV_DSR + !
EV_RLSD + !
EV_BREAK + !
EV_ERR + !
EV_RING + !
EV_PERR + !
EV_RX80FULL + !
EV_EVENT1 + !
EV_EVENT2 ) !Устанавливаем маску на все события
IF ~Loc:ReturnCode
MESSAGE('SetCommMask: ' & Loc:ReturnCode,'SetCommMask')
END
Loc:ReturnCode = WaitCommEvent(Loc:PortHandle, Address(COMMMASK), NULL) !возвращает не ноль, если все нормально
IF ~Loc:ReturnCode
MESSAGE('WaitCommEvent: ' & Loc:ReturnCode,'WaitCommEvent')
END
Loc:ReturnCode = ClearCommError(Loc:PortHandle, Address(Loc:PortErrorCode), Address(ComStat))
IF ~Loc:ReturnCode
MESSAGE('ClearCommError: ' & Loc:ReturnCode,'ClearCommError')
END
MESSAGE('InQue: ' & CS:InQue & '<13,10>OutQue: ' & CS:OutQue)
Loc:BytesToRead=CS:InQue
Loc:ReturnCode = ReadFile(Loc:PortHandle, Address(Loc:TempInString), Loc:BytesToRead, Address(Loc:BytesRead), NULL)
IF ~Loc:ReturnCode
MESSAGE('Loc:ReturnCode: ' & Loc:ReturnCode,'ReadFile')
ELSE
IF ~Loc:BytesRead
MESSAGE('Loc:BytesRead: ' & Loc:BytesRead,'ReadFile')
ELSE
Loc:InString = Loc:InString & Loc:TempInString & '<13,10,13,10>' !Дописывание двойного перевода строки
END
DISPLAY()
Вот у меня почему-то GetCommState возвращает StopBits=0, хотя я задаю 1
И самое главное - WaitCommEvent выдает 0.
Кстати, WriteFile работает нормально - это было проверено утилитой мониторинга порта.
И кроме того, несмотря на то, что эта программа не возвращает отклик от модема, этот отклик "застревает" в модеме. Ибо можно после посыла строки вфйти из программы, а потом запустить другую программу эмуляции терминала (не мою), и там на команду 'AT' получить отклик на ту команду, что посылал я из своей программы.
Я подозреваю, что у меня функции вызываются не в том порядке. Или какие-то пропущены.
Написал: Booroondook(77)