GIF для HTML в EXE

Есть программа на Delphi, котоpая отображает какой-то html. В html используется gif-файл. Как в Delphi-пpоекте указать, чтобы этот gif находился в exe как некий кусок кода. А когда надо будет, записать его обратно в gif-файл без изменений, выковырнув из exe?

Можно, используя RxLib. После его установки в меню View появится пунктик Project Resources. Hужно выбрать Project Resources->New->User Data и добавить нужный файл. В данном случае ресурс был назван «RCDATA_1».

Если RxLib нет, то нужно создать файл описания ресурсов:

=== Begin gifs.rc ===

mygif rcdata «имя_gif-файла.gif»

mygif1 rcdata «RCDATA_1»

=== End dots.rc ===

Потом скомпилировать его командой brcc32 gifs.rc и получить gifs.res В начало модуля добавь строчку {$R gifs.res}

В своей программе необходимо написать:

var

rs: TResourceStream;

a: Pointer;

begin

rs := TResourceStream.Create(hinstance, 'RCDATA_1', RT_RCDATA);

try

GetMem(a, rs.size);

rs.Read(a^, rs.size); {Теперь a - динамический указатель на код}

{ Здесь делается все, что необходимо с кодом, используя указатель a }

FreeMem(a);

finally

rs.Free;

end;

end;

 

А можно и так, если необходимо записать ресурс в файл:

var

rs: TResourceStream;

fs: TFileStream;

begin

rs := TResourceStream.Create(hInstance, 'mygif', RT_RCDATA);

fs := TFileStream.Create('имя_gif-файла.gif', fmCreate);

try

fs.CopyFrom(rs, rs.Size);

finally

fs.Free;

rs.Free;

end;

end;

Что такое порт (правила работы с портами)

Известно что в компьютере очень много собрано различных устройств , возникает вопрос как операционная система общается с ними. Для этого и служит порт, то есть эта «дверь» через которую программа (операционная система) может управлять данным устройством (считывать данные, заносить их).Причем я разделяю порты на две категории (это чисто мое разделение) — порты общеизвестные (COM LPT) и порты внутренние ,служащие для связи с внутренними устройствами ЭВМ.

2.Некоторые правила для работы с портами

Следует иметь в виду что при разработке программ имеющих дело работы с портами следует учитывать следующие факторы :

а) Стараться использовать функции высокого уровня для доступа к портам (в частности WinAPI) и не прибегать к низкоуровневым операциям чтения/записи портов. Если вы все-таки решили писать низкоуровневое чтение то эти процедуры нужно выносить в отдельную DLL или VXD, по следующим причинам — известно, что операционная система Windows95/98 а особенно NT являются по своей сути многозадачными системами. То есть если ваша программа обращается конкретно к порту не через динамический вызов функции DLL или VXD ( использования механизма DLL) а напрямую то это может сказаться на корректной работе системы или даже завалить ее. И даже если в Windows95/98 такой подход вполне может работать то в Windows NT вследствие его архитектуры не разрешит непосредственное чтение/запись напрямую, а использование механизма DLL или VXD позволяет обойти эту проблему.

б)Если вы работаете с каким-то нестандартным портом ввода-вывода (например портом хранящим состояние кнопок пульта ДУ TVTunera то наверняка в комплекте поставки родного софта найдется DLL или VXD для управления этим устройством и отпадет нужда писать код, так я при работе с пультом ДУ TVTunerа использую стандартную DLL поставляемую в комплекте, это сразу решило вопросы связанные с управлением портами данного тюнера)

Итак, отступление — немного практики

Маленький пример для работы с портами (первый пример был уже опубликован в королевстве Дельфи и представлял собой пример работы с весами ПетрВес)

function PortInit : boolean; //инициализация

var f: THandle;

ct: TCommTimeouts;

dcb: TDCB;

begin

f := Windows.CreateFile(PChar('COM1'), GENERIC_READ or

GENERIC_WRITE,

FILE_SHARE_READ or FILE_SHARE_WRITE,

nil, OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL, 0);

if (f < 0) or not Windows.SetupComm(f, 2048, 2048)or not

Windows.GetCommState(f, dcb) then exit; //init error

dcb.BaudRate := скоpость;

dcb.StopBits := стоп-биты;

dcb.Parity := четность;

dcb.ByteSize := 8;

if not Windows.SetCommState(f, dcb)

or not Windows.GetCommTimeouts(f, ct) then exit; //error

ct.ReadTotalTimeoutConstant := 50;

ct.ReadIntervalTimeout := 50;

ct.ReadTotalTimeoutMultiplier := 1;

ct.WriteTotalTimeoutMultiplier := 0;

ct.WriteTotalTimeoutConstant := 10;

if not Windows.SetCommTimeouts(f, ct)

or not Windows.SetCommMask(f, EV_RING EV_RXCHAR EV_RXFLAG EV_TXEMPTY)

then exit; //error

result := true;

end;

function DoneComm: boolean; //закpыть поpт

begin

result := Windows.CloseHandle(f);

end;

function PostComm(var Buf; size: word): integer; //пеpедача в поpт

var p: pointer; i: integer;

begin

p := @Buf;

result := 0;

while size > 0 do begin

if not WriteFile(f, p^, 1, i, nil) then exit;

inc(result, i); inc(integer(p)); dec(size);

Application.ProcessMessages;

end;

end;

function ReadComm(var Buf; size: word): integer; //пpием из поpта

var i: integer; ovr: TOverlapped;

begin

fillChar(buf, size, 0);

fillChar(ovr, sizeOf(ovr), 0); i := 0; result := -1;

if not windows.ReadFile(f, buf, size, i, @ovr) then exit;

result := i;

end;

 

Данный пример был взят мной из многочисленный FAQ посвященных в DELPHI в сети ФИДО Итак,для работы с портами COM и LPT нам понадобится знание функций Windows API.

Вот подробное описание функций, которые нам нужны (в эквиваленте C) для работы с портами. (извините за возможный местами неточный перевод ,если что поправьте меня если что не так перевел)

CreateFile

HANDLE CreateFile(

LPCTSTR lpFileName, // указатель на строку PCHAR с именем файла

DWORD dwDesiredAccess, // режим доступа

DWORD dwShareMode, // share mode

LPSECURITY_ATTRIBUTES lpSecurityAttributes, // указатель на атрибуты

DWORD dwCreationDistribution, // how to create

DWORD dwFlagsAndAttributes, // атрибуты файла

HANDLE hTemplateFile // хендл на temp файл

);

 

// Пример кода на Дельфи

CommPort := 'COM2';

hCommFile := CreateFile(Pchar(CommPort),

GENERIC_WRITE, 0, nil,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,

0);

Параметры

LpFileName — Указатель на строку с нулевым символом в конце (PCHAR) , которая определяет название создаваемого объекта (файл, канал, почтовый слот, ресурс связи (в данном случае порты), дисковое устройство, приставка, или каталог)

DwDesiredAccess — Указывает тип доступа к объекту ,принимает значение

GENERIC_READ — для чтения

GENERIC_WRITE — для записи (смешивание с GENERIC_READ операцией GENERIC_READ and GENERIC_WRITE предостовляет полный доступ )

dwShareMode — Набор разрядных флагов, которые определяют как объект может быть разделен по доступу к нему. Если dwShareMode — 0, объект не может быть разделен. Последовательные операции открытия объекта будут терпеть неудачу, пока маркер(дескриптор) открытого объекта не будет закрыт. Фактически предоставляется монопольный доступ.

Чтобы разделять объект(цель), используйте комбинацию одних или большее количество следующих значений:

FILE_SHARE_DELETE (Только для Windows NT)

FILE_SHARE_READ

FILE_SHARE_WRITE

LpSecurityAttributes — Указатель на структуру SECURITY_ATTRIBUTES, которая определяет может ли возвращенный дескриптор быть унаследован дочерними процессами. Если lpSecurityAttributes НУЛЕВОЙ, маркер не может быть унаследован. Используется только в windows NT.

dwCreationDistribution — Определяет поведение функции если объект уже существует и как он будет открыт в этом случае Принимает одно из следующих значений :

CREATE_NEW — Создает новый объект (файл) Выдает ошибку если указанный объект (файл) уже существует.

CREATE_ALWAYS — Создает новый объект (файл) Функция перезаписывает существующий объект (файл)

OPEN_EXISTING — Открывает объект (файл) Выдает ошибку если указанный объект (файл) не существует.(Для более детального смотрите SDK)

OPEN_ALWAYS — Открывает объект (файл), если он существует. Если объект (файл) не существует, функция создает его, как будто dwCreationDistribution были CREATE_NEW.

TRUNCATE_EXISTING — Открывает объект (файл). После этого объект (файл) будет усечен до нулевого размера.Выдает ошибку если указанный объект (файл) не существует.

DwFlagsAndAttributes — Атрибуты объекта (файла) , атрибуты могут комбинироваться

FILE_ATTRIBUTE_ARCHIVE

FILE_ATTRIBUTE_COMPRESSED

FILE_ATTRIBUTE_HIDDEN

FILE_ATTRIBUTE_NORMAL

FILE_ATTRIBUTE_OFFLINE

FILE_ATTRIBUTE_READONLY

FILE_ATTRIBUTE_SYSTEM

FILE_ATTRIBUTE_TEMPORARY

HTemplateFile — Определяет дескриптор с GENERIC_READ доступом к временному объекту(файлу). Временный объект(файл)поставляет атрибуты файла и расширенные атрибуты для создаваемого объекта (файла) ИСПОЛЬЗУЕТСЯ ТОЛЬКО В WINDOWS NT Windows 95: Это значение должно быть установлено в Nil. Возвращаемые значения

Если функция преуспевает, возвращаемое значение — открытый дескриптор к указанному объекту(файлу). Если файл не существует — 0. Если произошли функциональные сбои, возвращаемое значение — INVALID_HANDLE_VALUE. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Обратите внимание!

Для портов, dwCreationDistribution параметр должен быть OPEN_EXISTING, и hTemplate должен быть Nil. Доступ для чтения-записи должен быть определен явно.

SECURITY_ATTRIBUTES

Структура содержит описание защиты для объекта и определяет, может ли дескриптор быть унаследован дочерними процессами.

typedef struct _SECURITY_ATTRIBUTES

{ DWORD nLength;

LPVOID lpSecurityDescriptor;

BOOL bInheritHandle;

} SECURITY_ATTRIBUTES;

Параметры

NLength — Определяет размер, в байтах, этой структуры. Набор это значение к размеру структуры SECURITY_ATTRIBUTES В Windows NT функции которые используют структуру SECURITY_ATTRIBUTES, не

LpSecurityDescriptor — Дескриптор указывающий на описатель защиты для объекта, Если дескриптор ПУСТОЙ объект может быть назначен в наследование дочерними процессами.

BInheritHandle — Определяет, унаследован ли возвращенный дескриптор, когда новый дескриптор, создан. Если это значение принимает ИСТИНУ новый дескриптор наследует от головного.

Замечания

Указатель на структуру SECURITY_ATTRIBUTES используется как параметр в большинстве функций работы с окнами в Win32 API.

Структура DCB

Структура DCB определяет установку управления для последовательного порта ввода-вывода (нам она понадобится для разбора примера с программой управления весами ПетрВес)

Примечание : В местах где нельзя дать точный перевод будет дано определение на английском из MSDK и приблизительный его перевод Описание в эквиваленте C

typedef struct _DCB { // dcb

DWORD DCBlength; // Размер DCB

DWORD BaudRate; // Скорость пересылки данных в бодах;

// текущая скорость в бодах

DWORD fBinary: 1; // binary mode, no EOF check

// двоичный режим , не проверять конец

// данных (по умолчанию значение = 1)

DWORD fParity: 1; // Включить проверку четность (по умолчанию

// значение = 1)

DWORD fOutxCtsFlow:1; // CTS управление потоком выхода

DWORD fOutxDsrFlow:1; // DSR управление потоком выхода

DWORD fDtrControl:2; // DTR Тип управления потоком скорости

// передачи данных

DWORD fDsrSensitivity:1; // DSR sensitivity (чувствительность)

DWORD fTXContinueOnXoff:1; // XOFF continues Tx (стоп-сигнал

// продалжает выполнение)

DWORD fOutX: 1; // XON/XOFF out flow control (СТАРТ-

// СИГНАЛ / СТОП-СИГНАЛ для управления

// выходящим потоком (по умолчанию

// значение = 1)

DWORD fInX: 1; // XON/XOFF in flow control (СТАРТ-

// СИГНАЛ / СТОП-СИГНАЛ для управления

// входящим потоком (по умолчанию

// значение = 1)

DWORD fErrorChar: 1; // enable error replacement (включить

// проверку погрешностей по умолчанию=1)

DWORD fNull: 1; // enable null stripping (отвергать

// пустой поток данных (по умолчанию=1))

DWORD fRtsControl:2; // RTS управление потоком данных

DWORD fAbortOnError:1; // abort reads/writes on error

// (проверять операции чтения/записи

// по умолчанию=1)

DWORD fDummy2:17; // reserved ЗАРЕЗЕРВИРОВАНО

WORD wReserved; // not currently used НЕ ДЛЯ

// ИСПОЛЬЗОВАНИЯ

WORD XonLim; // transmit XON threshold (порог

// чувствительности старт-сигнала)

WORD XoffLim; // transmit XOFF threshold (порог

// чувствительности стоп-сигнала)

BYTE ByteSize; // Бит в байте (обычно 8)

BYTE Parity; // 0-4=no,odd,even,mark,space

// (четность байта)

BYTE StopBits; // 0,1,2 = 1, 1.5, 2 (стоповые биты)

char XonChar; // Tx and Rx XON character (вид

// старт сигнал в потоке)

char XoffChar; // Tx and Rx XOFF character (вид

// стоп сигнал в потоке)

char ErrorChar; // error replacement character (какой

// сигнал погрешности,его вид)

char EofChar; // end of input character (сигнал

// окончания потока)

char EvtChar; // received event character РЕЗЕРВ

WORD wReserved1; // reserved; do not use НЕ ДЛЯ

// ИСПОЛЬЗОВАНИЯ

} DCB;

Пример:

with Mode do

Begin

BaudRate := 9600;

ByteSize := 8;

Parity := NOPARITY;

StopBits := ONESTOPBIT; // одиночный стоп-бит

Flags := EV_RXCHAR EV_EVENT2;

End;

Параметры :

DCBlength — Размер DCB структуры.

BaudRate — Определяет скорость в бодах, в которых порт оперирует. Этот параметр может принимать фактическое значение скорости в бодах, или один из следующих стандартных индексов скорости в бодах:

CBR_110 CBR_19200

CBR_300 CBR_38400

CBR_600 CBR_56000

CBR_1200 CBR_57600

CBR_2400 CBR_115200

CBR_4800 CBR_128000

CBR_9600 CBR_256000

CBR_14400

fBinary — Определяет, допускается ли двоичный (бинарный) способ передачи данных. Win32 API не поддерживает недвоичные (небинарные) способы передачи данных в потоке порта, так что этот параметр должен быть всегда ИСТИНЕН. Попытка использовать ЛОЖЬ в этом параметре не будет работать.

Примечание :

Под Windows 3.1 небинарный способ передачи допускается, но для работы данного способа необходимо заполнит параметр EofChar который будет восприниматься конец данных.

fParity — Определяет, допускается ли проверка четности. Если этот параметр ИСТИНЕН, проверка четности допускается

fOutxCtsFlow — CTS (clear-to-send) управление потоком выхода

fOutxDsrFlow — DSR (data-set-ready) управление потоком выхода

fDtrControl — DTR (data-terminal-ready) управление потоком выхода

Принимает следующие значения :

DTR_CONTROL_DISABLE — Отключает линию передачи дынных

DTR_CONTROL_ENABLE — Включает линию передачи дынных

DTR_CONTROL_HANDSHAKE — Enables DTR handshaking. If handshaking is enabled, it is an error for the application to adjust the line by using the EscapeCommFunction function.

Допускает подтверждению связи передачи данных Если подтверждение связи допускается, это — погрешность для того чтобы регулировать(корректировать) линию связи, используя функцию EscapeCommFunction.

fDsrSensitivity — Specifies whether the communications driver is sensitive to the state of the DSR signal. If this member is TRUE, the driver ignores any bytes received, unless the DSR modem input line is high. Определяет возможна ли по порту двухсторонняя передача в ту и в другую сторону сигнала.

fTXContinueOnXoff — Определяет, останавливается ли передача потока , когда входной буфер становится полный, и драйвер передает сигнал XoffChar. Если этот параметр ИСТИНЕН, передача продолжается после того, как входной буфер становится в пределах XoffLim байтов, и драйвер передает сигнал XoffChar, чтобы прекратить прием байтов из потока . Если этот параметр ЛОЖНЫЙ, передача не продолжается до тех пор , пока входной буфер не в пределах XonLim байтов, и пока не получен сигнал XonChar, для возобновления приема .

fOutX — Определяет, используется ли управление потоком СТАРТ-СИГНАЛА / СТОП-СИГНАЛА в течение передачи потока порту. Если этот параметр ИСТИНЕН, передача останавливается, когда получен сигнал XoffChar и начинается снова, когда получен сигнал XonChar.

fInX — Specifies whether XON/XOFF flow control is used during reception. If this member is TRUE, the XoffChar character is sent when the input buffer comes within XoffLim bytes of being full, and the XonChar character is sent when the input buffer comes within XonLim bytes of being empty. Определяет, используется ли управление потоком СТАРТ-СИГНАЛА / СТОП-СИГНАЛА в течение приема потока портом. Если этот параметр ИСТИНЕН,сигнал XoffChar посылается , когда входной буфер находится в пределах XoffLim байтов, а сигнал XonChar посылается тогда когда входной буфер находится в пределах XonLim байтов или является пустым

fErrorChar — Определяет, заменены ли байты, полученные с ошибками четности особенностью, указанной параметром ErrorChar Если этот параметр ИСТИНЕН, и fParity ИСТИНЕН, замена происходит.

fNull — Определяет, отвергнуты ли нулевые(пустые) байты. Если этот параметр ИСТИНЕН, нулевые(пустые) байты, будут отвергнуты при получении их.

fRtsControl — RTS управление потоком » запрос пересылки » . Если это значение нулевое, то по умолчанию устанавливается RTS_CONTROL_HANDSHAKE. Принимает одно из следующих значений:

RTS_CONTROL_DISABLE — Отключает строку RTS, когда устройство открыто

RTS_CONTROL_ENABLE — Включает строку RTS

RTS_CONTROL_HANDSHAKE — Enables RTS handshaking. The driver raises the RTS line when the » type-ahead» (input) buffer is less than one-half full and lowers the RTS line when the buffer is more than three-quarters full. If handshaking is enabled, it is an error for the application to adjust the line by using the EscapeCommFunction function.

Допускает RTS подтверждение связи. Драйвер управляет потоком пересылки. RTS выравнивается , когда входной буфер — меньше чем половина полного и понижается, когда буфер — больше 2/3 полного .Если подтверждение связи допускается, это используется для регулирования передачи данных EscapeCommFunction.

RTS_CONTROL_TOGGLE — Specifies that the RTS line will be high if bytes are available for transmission. After all buffered bytes have been sent, the RTS line will be low. Определяет, что буфер будет высокий при подготовке данных для передачи. После того, как все байты отосланы, буфер RTS будет низок.

FAbortOnError — Определяет, закончена ли операции чтения/записи, если происходит погрешность. Если этот параметр ИСТИНЕН, драйвер закрывает все операции чтения/записи с состоянием погрешности при возникновении оной.

Драйвер не будет принимать никакие дальнейшие действия, пока не дождется подтверждения погрешности в передоваемых (принимаемых) данных, вызывая функцию ClearCommError.

fDummy2 — ЗАРЕЗЕРВИРОВАНО Microsoft

wReserved — ЗАРЕЗЕРВИРОВАНО Microsoft

XonLim — Определяет минимальное число байтов, находящихся во в

XoffLim — Определяет максимальное число байтов, находящихся во входном буфере прежде, чем будет генерирована подача СТОП-СИГНАЛА. Максимальное число байтов, позволенных во входном буфере вычитается из размеров, в байтах, самого входного буфера.

ByteSize — Определяет число битов в байтах, переданных и полученных.

Parity — Определяет схему четности, которую нужно использовать. Этот параметр может быть одним из следующих значений:

EVENPARITY

MARKPARITY

NOPARITY

ODDPARITY

StopBits — Определяет число стоповых битов, которые нужно использовать. Этот параметр может быть одним из следующих значений:

ONESTOPBIT 1 stop bit

ONE5STOPBITS 1.5 stop bits

TWOSTOPBITS 2 stop bits

XonChar — Определяет значение СТАРТ-СИГНАЛА для передачи и приема.

XoffChar — Определяет значение СТОП-СИГНАЛА для передачи и приема.

ErrorChar — Определяет значение СИГНАЛА ОШИБКИ (генерируемого при ошибке четности) для передачи и приема.

EofChar — Определяет значение сигнала конца данных.

EvtChar — Определяет значение сигнала события.

wReserved1 — ЗАРЕЗЕРВИРОВАНО Microsoft

Дополнение :

Когда структура DCB использует «ручной» выбор конфигурации , следующие ограничения используются для ByteSize и StopBits параметров : Число информационных разрядов должно быть от 5 до 8 битов. Использование 5 информационных разрядов с 2 стоповыми битами — недопустимая комбинация, как — 6, 7, или 8 информационных разрядов с 1.5 стоповыми битами.

Установить флаг DTR и RTS в активное состояние для определённого COM-порта

После открытия com-порта через CreateFile() необходимо с помощью GetCommState() и SetCommState() установить параметры порта (в частности убрать автоуправление RTS и DTR). Затем для установки соответствующих сигналов используется функция EscapeCommFunction().

Procedure ControlRTS;

Var

S: String;

lDCB: TDCB;

fHandle: THandle;

Begin

S:=’COM1′;

// open port

fHandle:=CreateFile( Pchar(S), GENERIC_READ Or GENERIC_WRITE, 0,

Nil, OPEN_EXISTING, 0, 0);

If fHandle=INVALID_HANDLE_VALUE Then

Begin

// can’t open….

Exit;

End;

// read settings

If Not GetCommState( fHandle, lDCB) Then

Begin

// can’t read

Exit;

End;

// Fill dcb

lDCB.BaudRate:=CBR_2400;

lDCB.ByteSize:=8;

lDCB.Parity:=NOPARITY;

lDCB.StopBits:=ONESTOPBIT;

// !!! we will manage RTS ourself !!!

ldcb.Flags:=(ldcb.Flags And $FFFFC0FF) Or $00000100;

// set comm state

SetCommState( fHandle, ldcb);

// Here we can manage

// Reset RTS

EscapeCommFunction( fHandle, CLRRTS);

// Set RTS

EscapeCommFunction( fHandle, SETRTS);

// Close port

CloseHandle(fHandle);

fHandle:=0;

End;

P.S. Надо заметить, что все выходы com-порта являются инверсными. А это значит, что активным сосотоянием порта является 0, а неактивным 1.

Структура DCB

Структура DCB определяет установку управления для последовательного порта ввода-вывода (нам она понадобится для разбора примера с программой управления весами ПетрВес)

Примечание : В местах где нельзя дать точный перевод будет дано определение на английском из MSDK и приблизительный его перевод

Описание в эквиваленте C

typedef struct _DCB { // dcb

DWORD DCBlength; // Размер DCB

DWORD BaudRate; // Скорость пересылки данных в бодах;

// текущая скорость в бодах

DWORD fBinary: 1; // binary mode, no EOF check

// двоичный режим , не проверять конец

// данных (по умолчанию значение = 1)

DWORD fParity: 1; // Включить проверку четность (по умолчанию

// значение = 1)

DWORD fOutxCtsFlow:1; // CTS управление потоком выхода

DWORD fOutxDsrFlow:1; // DSR управление потоком выхода

DWORD fDtrControl:2; // DTR Тип управления потоком скорости

// передачи данных

DWORD fDsrSensitivity:1; // DSR sensitivity (чувствительность)

DWORD fTXContinueOnXoff:1; // XOFF continues Tx (стоп-сигнал

// продалжает выполнение)

DWORD fOutX: 1; // XON/XOFF out flow control (СТАРТ-

// СИГНАЛ / СТОП-СИГНАЛ для управления

// выходящим потоком (по умолчанию

// значение = 1)

DWORD fInX: 1; // XON/XOFF in flow control (СТАРТ-

// СИГНАЛ / СТОП-СИГНАЛ для управления

// входящим потоком (по умолчанию

// значение = 1)

DWORD fErrorChar: 1; // enable error replacement (включить

// проверку погрешностей по умолчанию=1)

DWORD fNull: 1; // enable null stripping (отвергать

// пустой поток данных (по умолчанию=1))

DWORD fRtsControl:2; // RTS управление потоком данных

DWORD fAbortOnError:1; // abort reads/writes on error

// (проверять операции чтения/записи

// по умолчанию=1)

DWORD fDummy2:17; // reserved ЗАРЕЗЕРВИРОВАНО

WORD wReserved; // not currently used НЕ ДЛЯ

// ИСПОЛЬЗОВАНИЯ

WORD XonLim; // transmit XON threshold (порог

// чувствительности старт-сигнала)

WORD XoffLim; // transmit XOFF threshold (порог

// чувствительности стоп-сигнала)

BYTE ByteSize; // Бит в байте (обычно 8)

BYTE Parity; // 0-4=no,odd,even,mark,space

// (четность байта)

BYTE StopBits; // 0,1,2 = 1, 1.5, 2 (стоповые биты)

char XonChar; // Tx and Rx XON character (вид

// старт сигнал в потоке)

char XoffChar; // Tx and Rx XOFF character (вид

// стоп сигнал в потоке)

char ErrorChar; // error replacement character (какой

// сигнал погрешности,его вид)

char EofChar; // end of input character (сигнал

// окончания потока)

char EvtChar; // received event character РЕЗЕРВ

WORD wReserved1; // reserved; do not use НЕ ДЛЯ

// ИСПОЛЬЗОВАНИЯ

} DCB;

Пример :

with Mode do

begin

BaudRate := 9600;

ByteSize := 8;

Parity := NOPARITY;

StopBits := ONESTOPBIT; // одиночный стоп-бит

Flags := EV_RXCHAR EV_EVENT2;

end;

Параметры :

DCBlength

Размер DCB структуры.

BaudRate

Определяет скорость в бодах, в которых порт оперирует. Этот параметр может принимать фактическое значение скорости в бодах, или один из следующих стандартных индексов скорости в бодах:

CBR_110 CBR_19200

CBR_300 CBR_38400

CBR_600 CBR_56000

CBR_1200 CBR_57600

CBR_2400 CBR_115200

CBR_4800 CBR_128000

CBR_9600 CBR_256000

CBR_14400

fBinary

Определяет, допускается ли двоичный (бинарный) способ передачи данных. Win32 API не поддерживает недвоичные (небинарные) способы передачи данных в потоке порта, так что этот параметр должен быть всегда ИСТИНЕН. Попытка использовать ЛОЖЬ в этом параметре не будет работать.

Примечание:

Под Windows 3.1 небинарный способ передачи допускается,но для работы данного способа необходимо заполнит параметр EofChar который будет восприниматься конец данных.

fParity

Определяет, допускается ли проверка четности. Если этот параметр ИСТИНЕН, проверка четности допускается

fOutxCtsFlow

CTS (clear-to-send) управление потоком выхода

fOutxDsrFlow

DSR (data-set-ready) управление потоком выхода

fDtrControl

DTR (data-terminal-ready) управление потоком выхода

Принимает следующие значения :

DTR_CONTROL_DISABLE

Отключает линию передачи дынных

DTR_CONTROL_ENABLE

Включает линию передачи дынных

DTR_CONTROL_HANDSHAKE

Enables DTR handshaking. If handshaking is enabled, it is an error for the application to adjust the line by using the EscapeCommFunction function.

Допускает подтверждению связи передачи данных Если подтверждение связи допускается, это — погрешность для того чтобы регулировать(корректировать) линию связи, используя функцию EscapeCommFunction.

fDsrSensitivity

Specifies whether the communications driver is sensitive to the state of the DSR signal. If this member is TRUE, the driver ignores any bytes received, unless the DSR modem input line is high.

Определяет возможна ли по порту двухсторонняя передача в ту и в другую сторону сигнала.

fTXContinueOnXoff

Определяет, останавливается ли передача потока , когда входной буфер становится полный, и драйвер передает сигнал XoffChar. Если этот параметр ИСТИНЕН, передача продолжается после того, как входной буфер становится в пределах XoffLim байтов, и драйвер передает сигнал XoffChar, чтобы прекратить прием байтов из потока . Если этот параметр ЛОЖНЫЙ, передача не продолжается до тех пор , пока входной буфер не в пределах XonLim байтов, и пока не получен сигнал XonChar, для возобновления приема .

fOutX

Определяет, используется ли управление потоком СТАРТ-СИГНАЛА / СТОП-СИГНАЛА в течение передачи потока порту. Если этот параметр ИСТИНЕН, передача останавливается, когда получен сигнал XoffChar и начинается снова, когда получен сигнал XonChar.

fInX

Specifies whether XON/XOFF flow control is used during reception. If this member is TRUE, the XoffChar character is sent when the input buffer comes within XoffLim bytes of being full, and the XonChar character is sent when the input buffer comes within XonLim bytes of being empty. Определяет, используется ли управление потоком СТАРТ-СИГНАЛА / СТОП-СИГНАЛА в течение приема потока портом. Если этот параметр ИСТИНЕН,сигнал XoffChar посылается , когда входной буфер находится в пределах XoffLim байтов, а сигнал XonChar посылается тогда когда входной буфер находится в пределах XonLim байтов или является пустым

fErrorChar

Определяет, заменены ли байты, полученные с ошибками четности особенностью, указанной параметром ErrorChar Если этот параметр ИСТИНЕН, и fParity ИСТИНЕН, замена происходит.

fNull

Определяет, отвергнуты ли нулевые(пустые) байты. Если этот параметр ИСТИНЕН, нулевые(пустые) байты, будут отвергнуты при получении их.

fRtsControl

RTS управление потоком » запрос пересылки «. Если это значение нулевое, то по умолчанию устанавливается RTS_CONTROL_HANDSHAKE. Принимает одно из следующих значений:

RTS_CONTROL_DISABLE

Отключает строку RTS, когда устройство открыто

RTS_CONTROL_ENABLE

Включает строку RTS

RTS_CONTROL_HANDSHAKE

Enables RTS handshaking. The driver raises the RTS line when the «type-ahead» (input) buffer is less than one-half full and lowers the RTS line when the buffer is more than three-quarters full. If handshaking is enabled, it is an error for the application to adjust the line by using the EscapeCommFunction function.

Допускает RTS подтверждение связи. Драйвер управляет потоком пересылки.RTS выравнивается , когда входной буфер — меньше чем половина полного и понижается, когда буфер — больше 2/3 полного .Если подтверждение связи допускается, это используется для регулирования передачи данных EscapeCommFunction.

RTS_CONTROL_TOGGLE

Specifies that the RTS line will be high if bytes are available for transmission. After all buffered bytes have been sent, the RTS line will be low. Определяет, что буфер будет высокий при подготовке данных для передачи. После того, как все байты отосланы, буфер RTS будет низок.

FAbortOnError

Определяет, закончена ли операции чтения/записи, если происходит погрешность.

Если этот параметр ИСТИНЕН, драйвер закрывает все операции чтения/записи с состоянием погрешности при возникновении оной.

Драйвер не будет принимать никакие дальнейшие действия, пока не дождется подтверждения погрешности в передоваемых (принимаемых) данных, вызывая функцию ClearCommError.

fDummy2

ЗАРЕЗЕРВИРОВАНО Microsoft

wReserved

ЗАРЕЗЕРВИРОВАНО Microsoft

XonLim

Определяет минимальное число байтов, находящихся во входном буфере прежде, чем будет генерирована подача СТАРТ-СИГНАЛА

XoffLim

Определяет максимальное число байтов, находящихся во входном буфере прежде, чем будет генерирована подача СТОП-СИГНАЛА. Максимальное число байтов, позволенных во входном буфере вычитается из размеров, в байтах, самого входного буфера.

ByteSize

Определяет число битов в байтах, переданных и полученных.

Parity

Определяет схему четности, которую нужно использовать. Этот параметр может быть одним из следующих значений:

EVENPARITY

MARKPARITY

NOPARITY

ODDPARITY

StopBits

Определяет число стоповых битов, которые нужно использовать.

Этот параметр может быть одним из следующих значений:

ONESTOPBIT 1 stop bit

ONE5STOPBITS 1.5 stop bits

TWOSTOPBITS 2 stop bits

XonChar

Определяет значение СТАРТ-СИГНАЛА для передачи и приема.

XoffChar

Определяет значение СТОП-СИГНАЛА для передачи и приема.

ErrorChar

Определяет значение СИГНАЛА ОШИБКИ (генерируемого при ошибке четности) для передачи и приема.

EofChar

Определяет значение сигнала конца данных.

EvtChar

Определяет значение сигнала события.

wReserved1

ЗАРЕЗЕРВИРОВАНО Microsoft

Дополнение:

Когда структура DCB использует «ручной» выбор конфигурации , следующие ограничения используются для ByteSize и StopBits параметров :

Число информационных разрядов должно быть от 5 до 8 битов.

Использование 5 информационных разрядов с 2 стоповыми битами — недопустимая комбинация, как — 6, 7, или 8 информационных разрядов с 1.5 стоповыми битами.

 

Работа с последовательными портами

//{$DEFINE COMM_UNIT}

//Простой пример работы с последовательными портами

//Код содержит интуитивно понятные комментарии и строки на шведском языке,

//нецелесообразные для перевода.

//Compiler maakt Simple_Comm.Dll of Simple_Com.Dcu afhankelijk van 1e Regel

(COMM_UNIT)

{$IFNDEF COMM_UNIT}

library Simple_Comm;

{$ELSE}

unit Simple_Comm;

interface

{$ENDIF}

uses Windows, Messages;

const

M_BaudRate = 1;

const

M_ByteSize = 2;

const

M_Parity = 4;

const

M_Stopbits = 8;

{$IFNDEF COMM_UNIT}

{$R Script2.Res} //versie informatie

{$ENDIF}

{$IFDEF COMM_UNIT}

function Simple_Comm_Info: PChar; StdCall;

function

Simple_Comm_Open(Port: PChar; BaudRate: DWORD; ByteSize, Parity, StopBits:

Byte; Mas

k: Integer; WndHandle: HWND; WndCommand: UINT; var Id: Integer): Integer;

StdCall;

function Simple_Comm_Close(Id: Integer): Integer; StdCall;

function

Simple_Comm_Write(Id: Integer; Buffer: PChar; Count: DWORD): Integer; StdCall;

function Simple_Comm_PortCount: DWORD; StdCall;

const

M_None = 0;

const

M_All = 15;

implementation

{$ENDIF}

const

InfoString = 'Simple_Comm.Dll (c) by E.L. Lagerburg 1997';

const

MaxPorts = 5;

const

bDoRun: array[0..MaxPorts - 1] of boolean

= (False, False, False, False, False);

const

hCommPort: array[0..MaxPorts - 1] of Integer = (0, 0, 0, 0, 0);

const

hThread: array[0..MaxPorts - 1] of Integer = (0, 0, 0, 0, 0);

const

dwThread: array[0..MaxPorts - 1] of Integer = (0, 0, 0, 0, 0);

const

hWndHandle: array[0..MaxPorts - 1] of Hwnd = (0, 0, 0, 0, 0);

const

hWndCommand: array[0..MaxPorts - 1] of UINT = (0, 0, 0, 0, 0);

const

PortCount: Integer = 0;

function Simple_Comm_Info: PChar; stdcall;

begin

Result := InfoString;

end;

//Thread functie voor lezen compoort

function Simple_Comm_Read(Param: Pointer): Longint; stdcall;

var

Count: Integer;

id: Integer;

ReadBuffer: array[0..127] of byte;

begin

Id := Integer(Param);

while bDoRun[id] do

begin

ReadFile(hCommPort[id], ReadBuffer, 1, Count, nil);

if (Count > 0) then

begin

if ((hWndHandle[id] 0) and

(hWndCommand[id] > WM_USER)) then

SendMessage(hWndHandle[id], hWndCommand[id], Count,

LPARAM(@ReadBuffer));

end;

end;

Result := 0;

end;

//Export functie voor sluiten compoort

function Simple_Comm_Close(Id: Integer): Integer; stdcall;

begin

if (ID MaxPorts - 1) or (not bDoRun[Id]) then

begin

Result := ERROR_INVALID_FUNCTION;

Exit;

end;

bDoRun[Id] := False;

Dec(PortCount);

FlushFileBuffers(hCommPort[Id]);

if not

PurgeComm(hCommPort[Id], PURGE_TXABORT PURGE_RXABORT PURGE_TXCLEAR

PURGE_RXCL

EAR) then

begin

Result := GetLastError;

Exit;

end;

if WaitForSingleObject(hThread[Id], 10000) = WAIT_TIMEOUT then

if not TerminateThread(hThread[Id], 1) then

begin

Result := GetLastError;

Exit;

end;

CloseHandle(hThread[Id]);

hWndHandle[Id] := 0;

hWndCommand[Id] := 0;

if not CloseHandle(hCommPort[Id]) then

begin

Result := GetLastError;

Exit;

end;

hCommPort[Id] := 0;

Result := NO_ERROR;

end;

procedure Simple_Comm_CloseAll; stdcall;

var

Teller: Integer;

begin

for Teller := 0 to MaxPorts - 1 do

begin

if bDoRun[Teller] then

Simple_Comm_Close(Teller);

end;

end;

function GetFirstFreeId: Integer; stdcall;

var

Teller: Integer;

begin

for Teller := 0 to MaxPorts - 1 do

begin

if not bDoRun[Teller] then

begin

Result := Teller;

Exit;

end;

end;

Result := -1;

end;

//Export functie voor openen compoort

function

Simple_Comm_Open(Port: PChar; BaudRate: DWORD; ByteSize, Parity, StopBits:

Byte; Mas

k: Integer; WndHandle: HWND; WndCommand: UINT; var Id: Integer): Integer;

stdcall;

var

PrevId: Integer;

ctmoCommPort: TCOMMTIMEOUTS; //Lees specificaties voor de compoort

dcbCommPort: TDCB;

begin

if (PortCount >= MaxPorts) or (PortCount < 0) then

begin

result := error_invalid_function;

exit;

end;

result := 0;

previd := id;

id := getfirstfreeid;

if id = -1 then

begin

id := previd;

result := error_invalid_function;

exit;

end;

hcommport[id] := createfile(port, generic_read or

generic_write, 0, nil, open_existing, file_attribute_normal, 0);

if hcommport[id] = invalid_handle_value then

begin

bdorun[id] := false;

id := previd;

result := getlasterror;

exit;

end;

//lees specificaties voor het comm bestand

ctmocommport.readintervaltimeout := maxdword;

ctmocommport.readtotaltimeoutmultiplier := maxdword;

ctmocommport.readtotaltimeoutconstant := maxdword;

ctmocommport.writetotaltimeoutmultiplier := 0;

ctmocommport.writetotaltimeoutconstant := 0;

//instellen specificaties voor het comm bestand

if not setcommtimeouts(hcommport[id], ctmocommport) then

begin

bdorun[id] := false;

closehandle(hcommport[id]);

id := previd;

result := getlasterror;

exit;

end;

//instellen communicatie

dcbcommport.dcblength := sizeof(tdcb);

if not getcommstate(hcommport[id], dcbcommport) then

begin

bdorun[id] := false;

closehandle(hcommport[id]);

id := previd;

result := getlasterror;

exit;

end;

if (mask and m_baudrate 0) then

dcbCommPort.BaudRate := BaudRate;

if (Mask and M_ByteSize 0) then

dcbCommPort.ByteSize := ByteSize;

if (Mask and M_Parity 0) then

dcbCommPort.Parity := Parity;

if (Mask and M_Stopbits 0) then

dcbCommPort.StopBits := StopBits;

if not SetCommState(hCommPort[Id], dcbCommPort) then

begin

bDoRun[Id] := FALSE;

CloseHandle(hCommPort[Id]);

Id := PrevId;

Result := GetLastError;

Exit;

end;

//Thread voor lezen compoort

bDoRun[Id] := TRUE;

hThread[Id] := CreateThread(nil, 0, @Simple_Comm_Read, Pointer(Id), 0,

dwThread[Id]

);

if hThread[Id] = 0 then

begin

bDoRun[Id] := FALSE;

CloseHandle(hCommPort[Id]);

Id := PrevId;

Result := GetLastError;

Exit;

end

else

begin

SetThreadPriority(hThread[Id], THREAD_PRIORITY_HIGHEST);

hWndHandle[Id] := WndHandle;

hWndCommand[Id] := WndCommand;

Inc(PortCount);

Result := NO_ERROR;

end;

end;

//Export functie voor schrijven naar compoort;

function

Simple_Comm_Write(Id: Integer; Buffer: PChar; Count: DWORD): Integer; stdcall;

var

Written: DWORD;

begin

if (Id Maxports - 1) or (not bDoRun[Id]) then

begin

Result := ERROR_INVALID_FUNCTION;

Exit;

end;

if not WriteFile(hCommPort[Id], Buffer, Count, Written, nil) then

begin

Result := GetLastError();

Exit;

end;

if (Count Written) then

Result := ERROR_WRITE_FAULT

else

Result := NO_ERROR;

end;

//Aantal geopende poorten voor aanroepende applicatie

function Simple_Comm_PortCount: DWORD; stdcall;

begin

Result := PortCount;

end;

{$IFNDEF COMM_UNIT}

exports

Simple_Comm_Info Index 1,

Simple_Comm_Open Index 2,

Simple_Comm_Close Index 3,

Simple_Comm_Write Index 4,

Simple_Comm_PortCount index 5;

procedure DLLMain(dwReason: DWORD);

begin

if dwReason = DLL_PROCESS_DETACH then

Simple_Comm_CloseAll;

end;

begin

DLLProc := @DLLMain;

DLLMain(DLL_PROCESS_ATTACH); //geen nut in dit geval

end.

{$ELSE}

initialization

finalization

Simple_Comm_CloseAll;

end.

{$ENDIF}

Другое решение: создание модуля I / O(ввода / вывода)под Windows 95 / NT.Вот он:

)

(с TDCB в SetCommStatus вы можете управлять DTR и т.д.)

(Примечание: XonLim и XoffLim не должны быть больше 600, иначе под NT это

работает неправильно)

unit My_IO;

interface

function OpenComm(InQueue, OutQueue, Baud: LongInt): Boolean;

function SetCommTiming: Boolean;

function SetCommBuffer(InQueue, OutQueue: LongInt): Boolean;

function SetCommStatus(Baud: Integer): Boolean;

function SendCommStr(S: string): Integer;

function ReadCommStr(var S: string): Integer;

procedure CloseComm;

var

ComPort: Word;

implementation

uses Windows, SysUtils;

const

CPort: array[1..4] of string = ('COM1', 'COM2', 'COM3', 'COM4');

var

Com: THandle = 0;

function OpenComm(InQueue, OutQueue, Baud: LongInt): Boolean;

begin

if Com > 0 then

CloseComm;

Com := CreateFile(PChar(CPort[ComPort]),

GENERIC_READ or GENERIC_WRITE,

0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

Result := (Com > 0) and SetCommTiming and

SetCommBuffer(InQueue, OutQueue) and

SetCommStatus(Baud);

end;

function SetCommTiming: Boolean;

var

Timeouts: TCommTimeOuts;

begin

with TimeOuts do

begin

ReadIntervalTimeout := 1;

ReadTotalTimeoutMultiplier := 0;

ReadTotalTimeoutConstant := 1;

WriteTotalTimeoutMultiplier := 2;

WriteTotalTimeoutConstant := 2;

end;

Result := SetCommTimeouts(Com, Timeouts);

end;

function SetCommBuffer(InQueue, OutQueue: LongInt): Boolean;

begin

Result := SetupComm(Com, InQueue, OutQueue);

end;

function SetCommStatus(Baud: Integer): Boolean;

var

DCB: TDCB;

begin

with DCB do

begin

DCBlength := SizeOf(Tdcb);

BaudRate := Baud;

Flags := 12305;

wReserved := 0;

XonLim := 600;

XoffLim := 150;

ByteSize := 8;

Parity := 0;

StopBits := 0;

XonChar := #17;

XoffChar := #19;

ErrorChar := #0;

EofChar := #0;

EvtChar := #0;

wReserved1 := 65;

end;

Result := SetCommState(Com, DCB);

end;

function SendCommStr(S: string): Integer;

var

TempArray: array[1..255] of Byte;

Count, TX_Count: Integer;

begin

for Count := 1 to Length(S) do

TempArray[Count] := Ord(S[Count]);

WriteFile(Com, TempArray, Length(S), TX_Count, nil);

Result := TX_Count;

end;

function ReadCommStr(var S: string): Integer;

var

TempArray: array[1..255] of Byte;

Count, RX_Count: Integer;

begin

S := '';

ReadFile(Com, TempArray, 255, RX_Count, nil);

for Count := 1 to RX_Count do

S := S Chr(TempArray[Count]);

Result := RX_Count;

end;

procedure CloseComm;

begin

CloseHandle(Com);

Com := -1;

end;

end.

Печать Dos-файла в порт напрямую

При печати Dos-файла в порт напрямую можно это сделать.

Например, напечатать за 2 прохода:

ESC @ — инициализация принтера

ESC G — включение режима печати за 2 прохода

ESC H — выключение режима печати за 2 прохода

var

FileOut: TextFile;

filename: string[128];

....

Filename := 'PRN';

AssignFile(Fileout, Filename);

...

Write(FileOut, Chr(27) '@');

Str1 := AnToAs(chr(27) 'G' 'Double' chr(27) 'H');

Writeln(FileOut, Str1);

...

{преобразование Ansi to Ascii}

function AnToAs(s: string): string;

var

i, kod: Integer;

begin

Result := s;

for i := 1 to length(s) do

begin

kod := Ord(s[i]);

if kod 13 then

Result[i] := ' ';

if (kod >= 192) and (kod = 239) then

Result[i] := Chr(kod - 64);

if (kod >= 240) and (kod = 255) then

Result[i] := Chr(kod - 16);

if kod = 168 then

Result[i] := Chr(240);

if kod = 184 then

Result[i] := Chr(241);

end;

end;

Определяет наличие СОМ портов

{ **** UBPFD *********** by delphibase.endimus.com ****

>> Определяет наличие СОМ портов

Данная процедура позволяет определить наличие доступных СОМ-портов.

Список добавлятся в ComboBox. После этого можно выбирать нужный порт.

Зависимости: Windows, Messages, SysUtils, Variants, Classes,

Graphics, Controls, Forms, Dialogs, ComCtrls

 

unit SetComPort;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, ComCtrls, dfsStatusBar, ExtCtrls, StdCtrls, ImgList, Buttons,

ToolWin;

type

TForm1 = class(TForm)

StrNP: TRichEdit;

dfsStatusBar1: TdfsStatusBar;

ImageList1: TImageList;

CoolBar1: TCoolBar;

Panel1: TPanel;

LoadNP: TBitBtn;

Auto: TCheckBox;

SetRegim: TRadioGroup;

GroupBox1: TGroupBox;

ComPort: TComboBox;

BaudRate: TComboBox;

Label1: TLabel;

Label2: TLabel;

Label3: TLabel;

Label4: TLabel;

Label5: TLabel;

Parity: TComboBox;

ByteSize: TComboBox;

StopBits: TComboBox;

CloseItem: TBitBtn;

procedure InquiryPort(Sender: TObject); {опрос существующих портов}

procedure FormCreate(Sender: TObject);

procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure CloseItemClick(Sender: TObject);

procedure ComPortChange(Sender: TObject);

procedure BaudRateChange(Sender: TObject);

procedure ParityChange(Sender: TObject);

procedure ByteSizeChange(Sender: TObject);

procedure StopBitsChange(Sender: TObject);

procedure SetRegimClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

FHandl: THandle; {дескриптор порта}

DCB: TDCB; {ссылка на структуру настройки порта}

PortName: string; {имя порта, для дальнейшей работы}

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.InquiryPort(Sender: TObject);

var

i: integer;

begin {опрос существующих портов}

for i := 0 to 31 do {цикл опроса}

begin {пробуем получить дескриптор порта}

FHandl := CreateFile(PChar('COM' IntToStr(i 1)),

GENERIC_READ or GENERIC_WRITE,

0,

nil,

OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

if FHandl INVALID_HANDLE_VALUE then {если порт есть то добавить в список}

ComPort.Items.Add('COM' IntToStr(i 1));

CloseHandle(FHandl); {закрыть дескриптор}

end;

end;

Как читать-писать в I-O порты 2

В Delphi 1 записывать и считывать из портов можно через глобальный массив ‘ports’. Однако данная возможность отсутствует в ’32-битном’ Delphi.

Следующие две функции можно использовать в любой версии delphi:

function InPort(PortAddr:word): byte;

{$IFDEF WIN32}

assembler; stdcall;

asm

mov dx,PortAddr

in al,dx

end;

{$ELSE}

begin

Result := Port[PortAddr];

end;

{$ENDIF}

procedure OutPort(PortAddr:

word; Databyte: byte);

{$IFDEF WIN32}

assembler; stdcall;

asm

mov al,Databyte

mov dx,PortAddr

out dx,al

end;

{$ELSE}

begin

Port[PortAddr] := DataByte;

end;

{$ENDIF}