SB: array[0..255] of Byte;
i: integer;

n: DWORD; begin

S := 'Это передаваемый текст'; for i:=l to Length (S) do

SB[i-1] := Byte (S [i]) ;
FlushFileBuffers (port);

WriteFile (port, SB, Length (S), n, Overlapp); if GetLastError ERROR_IO_PENDING

then ShowMessage('Ошибка') else Timerl.Enabled := true;
end;
procedure TForml.Button3Click(Sender: TObject);
// процедура чтения var n: DWORD;

i: integer; begin for i:= 0 to 127 do

buf[i] := 0;
FlushFileBuffers (port);
ReadFile(port, buf, 128, n, Overlapp);
if GetLastError ERROR_IO_PENDING then ShowMessage('Ошибка') else Timer1.Enabled := true;
end;

Рассмотренная организация асинхронной записи и чтения работает в Windows NT\2000\XP. Если требуется создать приложение, которое работает также в Windows 98 и 95, то организовывать запись и чтение надо несколько иначе. В поле hEvent записи типа TOverlapped надо заносить результат, возвращаемый функцией CreateEvent:

в VCL Win32

function CreateEvent(IpEventAttributes: PSecurityAttributes;
bManualReset, blnitialState: BOOL;
lpName: PChar): THandle;

в VCL .NET

function CreateEvent (const IpEventAttributes: TSecurityAttributes;
bManualReset, blnitialState: BOOL;
lpName: string): THandle;
external;

Эта функция создает объект события и возвращает его дескриптор. Не будем вдаваться в детали этой функции. Для нашей задачи параметры IpEventAttributes и lpName надо задавать равными nil (в VCL .NET lpName - пустая строка), а параметры bManualReset и blnitialState равными false. Так что в приведенный выше код надо в процедурах записи и чтения добавить перед вызовами функций WriteFile и ReadFile операторы:

Overlapp.hEvent := CreateEvent(nil, false, false, nil); // VCL Win32

или

Overlapp.hEvent := CreateEvent (nil, false, false, ''); // VCL .NET

Это единственное изменение, которое над сделать в первых процедурах приведенного выше примера. А вот процедуру TimerlTimer надо изменить более существенно. Опрос в данном случае надо делать функцией WaitForSingleObject:

function WaitForSingleObject(hHandle: THandle;
dwMilliseconds: DWORD): DWORD;

Параметр hHandle является дескриптором ожидаемого события, а параметр dwMilliseconds указывает в миллисекундах максимальное время ожидания события. Если задать dwMilliseconds = 0, функция вернется немедленно. А если задать dwMilliseconds = INFINITE, ожидание будет бесконечным (аналог синхронной операции). Функция возвращает значение WAIT_OBJECT_0, если событие произошло, WAIT_TIMEOUT, если истекло заданное время ожидания, WAITJFAILED в случае ошибки.

В нашем примере, очевидно, имеет смысл задать dwMilliseconds = 0, чтобы приложение могла нормально выполняться, пока не произошло событие. Так что процедура TimerlTimer может иметь вид:

procedure TForml.TimerlTimer(Sender: TObject);
var n: DWORD;

begin

if(WaitForSingleObject(Overlapp.hEvent,0) = WAIT_OBJECT_0) then begin

if GetOverlappedResult(port, Overlapp, n, false) then begin

Labell.Caption := ' Получены/переданы новые данные - '

+ IntToStr(n) + ' байт'; Timerl.Enabled := false; CloseHandle(Overlapp.hEvent); end end

else Labell.Caption := 'Новых данных нет';
end;

Обратите внимание на необходимость закрыть дескриптор объекта события функцией CloseHandle после того, как событие произошло.

Рассмотренный способ организации асинхронной работы с портами с помощью объектов событий годится для любых версий Windows.

На этом приходится закончить рассмотрение способов работы с портами. Конечно, рассмотрено далеко не все. Я не останавливался на особенностях низкоуровневой настройки портов, на асинхронном режиме с одновременным доступом к порту нескольких приложений, на работе с модемом и на многом другом. Если вам все это потребуется, придется изучить соответствующий материал самостоятельно с помощью справок или иной литературы. Но думаю, что для большинства задач, требующих использования портов, будет достаточно рассмотренных основных приемов организации передачи и приема данных.

Глава 12

Некоторые приемы программирования приложений Windows

В данной главе собраны приемы программирования самых различных задач, встречающихся при проектировании приложений Windows. Пояснение того, откуда взяты эти задачи, вы можете найти в первых строках гл. 10.

11.18.2 Синхронный режим работы || Оглавление || 12.1 Оконные компоненты и формы


⇐ Предыдущая страница|

Приемы программирования в Delphi на основе VCL



Новости за месяц

  • Май
    2020
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс