Выбрать главу

. . .

COMMCONFIG *cf;

DWORD sz;

HANDLE port;

. . .

cf = (COMMCONFIG*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(COMMCONFIG));

cf->dwSize = sizeof(COMMCONFIG);

GetCommConfig(port,cf,&sz);

if (sz > sizeof(COMMCONFIG)) {

 cf = (COMMCONFIG*)HeapRealloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cf, sz);

 cf->dwSize=sz;

 GetCommConfig(port, cf, &sz);

}

. . .

HeapFree(GetProcessHeap(),0,cf);

CloseHandle(port);

. . .

Теперь, имея заполненую корректной информацией структуру COMMCONFIG, можно позволить пользователю выполнить настройку параметров с помощью функции CommConfigDialog:

BOOL CommConfigDialog(LPTSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC);

Вызов этой функции приводит к отображению примерно такого диалогового окна:

Вид окна может отличаться от приведенного. Это зависит от операционной системы и динамической библиотеки, предоставленной производителем порта.

Познакомимся с параметрами функции CommConfigDialog:

lpszName

Указатель на строку с именем порта для которого отображается диалоговое окно. К реальному имени порта эта строка не имеет никакого отношения, она просто выводится в заголовке окна.

hWnd

Описатель окна, которое владеет данным диалоговым окном. Должен быть передан корректный описатель окна-владельца или NULL, если у диалогового окна нет владельца.

lpCC

Указатель на структуру COMMCONFIG. Эта структура содержит начальные установки используемые для отображения в диалоговом окне, и установленные пользователем изменения, при завершении диалога.

Как и большинство других функций Win32 API, функция CommConfigDialog возвращает отличное от нуля значение, в случае успешного завершения, и нуль, если возникла ошибочная ситуация.

Функция CommConfigDialog не выполняет настройки порта. Она все лишь позволяет пользователю изменить некоторые поля в блоке DCB, содержащемся в структуре COMMCONFIG. Разумеется, Вы можете изменить установленые пользователем некорректные значения или выполнить дополнительные настройки после вызова функции GetCommConfig. Фактическая настройка порта выполняется функцией SetCommConfig:

BOOL SetCommConfig(HANDLE hCommDev, LPCOMMCONFIG lpCC, DWORD dwSize);

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

Обратите внимание на кнопку "Restore Defaults". Вы в состоянии управлять ее поведением, правда опосредовано, с помощью функций GetDefaultCommConfig и SetDegaultCommConfig. Вот их прототипы:

BOOL GetDefaultCommConfig(LPCSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize);

BOOL SetDefaultCommConfig(LPCSTR lpszName, LPCOMMCONFIG lpCC, DWORD dwSize);

Эти функции очень похожи на GetCommConfig и SetCommConfig, но предназначены совсем для другой цели. Предположим, что Ваше устройство, по умолчанию, работает на скорости 175 бит в секунду и обменивается пятибитными символами. Системные же умолчания – 9600 бит в секунду и 8 бит в символе. Что бы пользователь, при нажатии на кнопку "Restore Defaults", получал не системные, а Ваши умолчания, воспользуйтесь функциями GetDefaultCommConfig и SetDefaultCommConfig. SetDefaultCommConfig не настраивает порт, это выполняется функцией SetCommConfig, а изменяет параметры во внутренней области коммуникационного драйвера.

Теперь познакомимся с функцией SetupComm, которая, на самом деле, совсем не то, что следует из названия.

BOOL SetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue);

Эту функцию скорее следовало назвать SetCommQueueSize, поскольку все, что она делает, это устанавливает размеры (в байтах) очередей приема и передачи. Причем размеры рекомендуемые. В общем случае, система сама в состоянии определить требуемый размер очередей, однако Вы можете вмешаться в этот процесс. Внутренние очереди драйвера позволяют избежать потери данных, если Ваша программа не успевает их считывать, и пауз в работе программы, если она передает данные слишком быстро. Размер очереди выбирается немного большим максимальной длины сообщения. Например, для протокола YMODEM, пакет данных которого имеет длину 1024 байт, разумным размером очереди будет 1200 байт.

Указаный Вами размер очереди будет принят драйвером к сведению. Но он оставляет за собой право внести коррективы или вообще отвергнуть устанавливаемое значение. В последнем случае функция завершится с ошибкой.

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