Шрифт:
Интервал:
Закладка:
• DATABITS_5 — 5 бит
• DATABITS_6 — 6 бит
• DATABITS_7 — 7 бит
• DATABITS_8 — 8 бит
• DATABITS_16 — 16 бит
• DATABITS_16Х — Специальный широкий канал через аппаратную последовательную линию.
∙ wSettableStop Parity
Битовая маска. Определяет допустимое количество стоповых бит и режимы четности. Возможны следующие значения:
• STOPBITS_10 — Один стоповый бит
• STOPBITS_15 — Полтора стоповых бита
• STOPBITS_20 — Два стоповых бита
• PARITY_NONE — Без четности
• PARITY_ODD — Дополнение до нечетности
• PARITY_EVEN — Дополнение до четности
• PARITY_MARK — Бит четности всегда "1"
• PARITY_SPACE — Бит четности всегда "0"
∙ dwCurrentTxQueue
Определяет текущий размер, в байтах, внутренней очереди передачи драйвера. Нулевое значение свидетельствует о недоступности данного параметра.
∙ dwCurrentRxQueue
Определяет текущий размер, в байтах, внутренней очереди приема драйвера. Нулевое значение свидетельствует о недоступности данного параметра.
∙ dwProvSped
Устройство-зависимые данные. Программа должна игнорировать содержимое данного поля, за исключением случаев, когда Вы точно знаете формат этих данных. Занесите в данное поле значение COMMPROP_INITIALIZED, если поле wPacketLength уже содержит правильное значение.
∙ dwProvSpec2
Устройство-зависимые данные. Программа должна игнорировать содержимое данного поля, за исключением случаев, когда Вы точно знаете формат этих данных.
∙ wcProvChar
Устройство-зависимые данные. Программа должна игнорировать содержимое данного поля, за исключением случаев, когда Вы точно знаете формат этих данных.
Информация хранящаяся в структуре COMMPROP требуется редко, так как чаще всего точно известно с каким типом портов будет работать программа.
Остановлюсь чуть подробнее на описании некоторых полей. Поле wPacketLength играет несколько иную роль, чем поле DCBlength структуры DCB, хотя из его описания это не следует. Секрет прост. Поле wcProvChar, расположенное в конце структуры, может содержать, а может и не содержать, данных. Вы не в состоянии это узнать не запросив информацию. В свою очередь, перед запросом информации Вы должны выделить (и обнулить) память под структуру COMMPROP. Поэтому последовательность шагов для получения всей информации следующая:
• Выделить память под структуру COMMPROP.
• Запросить информацию у системы вызвав функцию GetCommProperties.
• Если поле wPacketLength содержит значение большее sizeof(COMMPROP), то имеется дополнительная информация. Для ее получения измените размер ранее выделенного блока памяти, новый размер должен быть равен значению занесенному системой в поле wPacketLength. Установите в поле wProvSpecl значение COMMPROP INITIALIZED, это будет означать, что выделен достаточный блок памяти для получения дополнительной информации. Повторно вызовите функцию GetCommProperties.
Чаще всего дополнительная информация представлена в виде структуры MODEMDEVCAPS, которая размещается на месте поля wcProvChar, если поле dwProvSubType содержит значение PST MODEM.
Получить информацию об устройстве в виде структуры COMMPROP можно уже упоминавшейся функцией GetCommProperies. Вот как выглядит ее прототип:
BOOL GetCommProperties(
HANDLE hFile,
LPCOMMPROP lpCommProp
);
Запросить информацию можно только об уже открытом устройстве. При этом для структуры, адресуемой вторым параметром, должна быть выделена память. Приведу пример получения информации о коммуникационном устройстве:
#include <windows.h>
…
HANDLE port;
COMMPROP *pr;
…
port=CreateFile("COM2",GENERIC_READ|GENERIC_WRIТЕ,0,NULL,OPEN_EXISTING,0,NULL);
pr=(COMMPROP*)HeapAlloc(GetProcessHeapO,HEAP_ZERO_MEMORY,sizeof(COMMPROP));
GetCommProperties(port,pr);
if(pr->wPacketLength!= sizeof(COMMPROP)) {{
pr=(COMMPROP*)HeapRealloc(GetProcessHeap(),HEAP_ZERO_MEMORY,pr,pr- >wPacketLength);
pr->wProvSpecl=COMMPROP_INITIALIZED;
GetCommProperties(port,pr);
}
…
HeapFree(GetProcessHeap(),0,pr);
CloseHandle(port);
…
He всегда настройку порта можно жестко зашить в код программы. Внешние устройства могут позволять изменять параметры линии связи, чаще всего скорость обмена, которая зависит от длины соединительного кабеля. В таких случаях разумно предоставить пользователю самому задавать режимы обмена. Можно самому разработать соответствующий настроечный диалог, а можно воспользоваться стандартным, предоставляемым операционной системой, а точнее, производителем порта. Стандартный диалог выводится функцией CommConfigDialog, которая работает со структурой COMMCONFIG. Как и в случае со структурой DCB, заполнять структуру COMMCONFIG можно вручную или вызовом соответствующих функций.
Структура COMMCONFIG
Начнем с самой структуры COMMCONFIG:
typedef struct _COMM_CONFIG {{
DWORD dwSize;
WORD wVersion;
WORD wReserved;
DCB dсb;
DWORD dwProviderSubType;
DWORD dwProviderOffset;
DWORD dwProviderSize;
WCHAR wcProviderData[1];
} COMMCONFIG, *LPCOMMCONFIG;
Основной частью этой структуры является уже знакомый нам DCB. Остальные поля содержат вспомогательную информацию, которая, для наших целей, не представляет особого интереса (однако эта информация может быть полезной для получения дополнительных данных о порте). Познакомимся поближе с полями:
∙ dwSize
Задает размер структуры COMMCONFIG в байтах
∙ wVersion
Задает номер версии структуры COMMCONFIG. Должен быть равным 1.
∙ wReserved
Зарезервировано и не используется
∙ dcb
Блок управления устройством (DCB) для порта RS-232.
∙ dwProviderSubType
Задает тип устройства и формат устройство-зависимого блока информации. Фактически это тип порта. Конкретные значения данного поля приведены в описании структуры COMMPROP выше.
∙ dwProviderOffset
Смещение, в байтах, до устройство-зависимого блока информации от начала структуры.
∙ dwProviderSize
Размер, в байтах, устройство-зависимого блока информации.
∙ wcProviderData
Устройство-зависимый блок информации. Это поле может быть любого размера или вообще отсутствовать. Поскольку структура COMMCONFIG может быть в дальнейшем расширена, для определения положения данного поля следует использовать dwProviderOffset. Если dwProviderSubType PST_RS232 или PST_PARALLELPORT, то данное поле отсутствует. Если dwProviderSubType PST_MODEM, то данное поле содержит структуру MODEMSETTINGS.
Функция GetCommConfig
Несмотря на то, что нам нужен только DCB, приходится иметь дело со всеми полями. Заполнение данной структуры противоречивыми данными может привести к неправильной настройке порта, поэтому следует пользоваться функцией GetCommConfig:
BOOL GetCommConfig(
HANDLE hCommDev,
LPCOMMCONFIG lpCC,
LPDWORD lpdwSize
);
Параметры функции следующие:
∙ hCommDev
Описатель открытого коммуникационного порта.
∙ IpCC
Адрес выделенного и заполненного нулями, кроме поля dwSize, блока памяти под структуру COMMCONFIG. В поле dwSize нужно занести размер структуры COMMCONFIG. После вызова функции все поля структуры будут содержать информацию о текущих параметрах порта.
∙ IpdwSize
Адрес двойного слова, которое после возврата из функции будет содержать число фактически переданных в структуру байт.
В случае успешного завершения функция возвращает ненулевое значение.
Как всегда не обошлось без тонкостей. Структура COMMPROP имеет переменную длину, поэтому затруднительно сразу выделить требуемый блок памяти. Как и в случае с функцией GetCommProperties, функцию GetCommConfig придется вызывать дважды: