нкції CreateFile () особливого пояснення вимагає dwFlagsAndAttributes. Робота з портом може бути організована в синхронному (nonoverlapped) або асинхронному (overlapped) режимах обробки, що і задається цим прапором. При синхронному режимі (коли параметр dwFlagsAndAttributes = 0) тільки один потік додатку може або читати, або писати в порт. Пам'ятайте переговорний пристрій у ліфті? Натиснули кнопку - можемо тільки говорити, відпустили кнопку - можемо тільки слухати. p> Синхронний режим обробки простий в реалізації. Якщо треба записати дані в порт, то викликаємо функцію запису і чекаємо, поки вона не завершиться. Якщо ж треба читати дані, то викликаємо функцію читання і чекаємо, поки вона не відпрацює. Для простих завдань синхронний режим обробки цілком підходить, проте в світі Windows він майже завжди приречений на невдачу. Очікування операції читання або запису сприймається користувачем програми як В«зависанняВ». p> Асинхронний режим (Коли параметр dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED) дозволяє виробляти операції читання і запису в порт паралельно з різних потоків. У той час, поки один потік додатку приймає дані, інший потік може паралельно з першим передавати дані - як при розмові по телефону, коли ви можете слухати і говорити одночасно. Даний режим обробки більше імпонує ідеї багатозадачності Windows. Але за все треба платити: для реалізації цього режиму обробки потрібно в два рази більше написаного коду, до того ж, вміння писати багатопотокові програми. Який режим вибрати - вирішуйте самі. Але якщо вже розбиратися в роботі порту, то розбиратися В«по-доросломуВ», до кінця, а тому й розглянемо більш складний варіант - асинхронну обробку. p> На практиці відкриття порту для асинхронного режиму обробки з програми на Delphi виглядає приблизно так:
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if hPort = INVALID_HANDLE_VALUE then
raise Exception.Create ('Error opening port');
Функція повертає описувач порту (hPort), який нам потім знадобиться для виклику інших функцій роботи з портом. Якщо в результаті відкриття порту описувач не отримано, то збуджується виключення з відповідним текстом помилки. Відкривши порт, ми отримуємо його у своє розпорядження. Тепер з цим портом може працювати тільки наша програма (точніше, тільки наш процес). Після закінчення роботи з портом його слід закрити, викликавши функцію:
BOOL CloseHandle (
HANDLE hObject
);
В якості єдиного параметра треба передати отриманий раніше описувач порту (hPort). p> Хоч система при завершенні виконання програми і звільняє всі виділені їй ресурси (в тому числі і порти), хорошим тоном програмування вважається власноручне закриття портів. Відкривати/закривати порт начебто нескладно. Крім того, нам потрібно програмну настройка порту. Думаю, всі бачили діалог налаштування послідовного порту в диспетчері пристроїв системи. Всі ці налаштування ми можемо зробити програмно. Для цих цілей використовується функція WinAPI:
BOOL SetCommState (
HANDLE hFile,
LPDCB lpDCB
);
hFile - описувач відкритого порту. p> lpDCB - покажчик на структуру DCB. br/>
Основні параметри послідовного порту описуються структурою DCB. Вона містить масу полів, кожне з яких відповідає певному параметру настройки порту. Ми розглянемо декілька полів, які нам потрібні:
BaudRate - швидкість передачі даних. Можливо вказівку констант-CBR_100, CBR_300, CBR_600, CBR_1200, ..., CBR_256000. p> Parity - схема контролю парності. Може містити одне з наступних значень: EVENPARITY, MARKPARITY, NOPARITY, ODDPARITY, SPACEPARITY. p> ByteSize - число інформаційних біт в переданих і прийнятих байтах. p> StopBits - кількість степових біт. Може бути ONESTOPBIT, ONE5STOPBIT, TWOSTOPBIT. p> Щоб не заповнювати структуру DCB вручну, її можна заповнити інформацією про поточний стані порту викликом функції GetCommState (), потім змінити необхідні поля і встановити настройки викликом функції SetCommState (). Настройку порту бажано проводити відразу після його відкриття. На Delphi це виглядає так:
var
Dcb: TDcb;
...
if not GetCommState (hPort, Dcb) then
raise Exception.Create ('Error setting port state');
Dcb.BaudRate: = CBR_9600;
Dcb.Parity: = NOPARITY;
Dcb.ByteSize: = 8;
Dcb.StopBits: = ONESTOPBIT;
if not SetCommState (hPort, Dcb) then
raise Exception.Create ('Error setting port state');
Ще одна операція, яка нам знадобиться відразу після відкриття порту - його скидання.
BOOL PurgeComm (
HANDLE hFile,
DWORD dwFlags
);
Виклик цієї функції очищає чергу прийому/передачі і завершує все знаходяться в очікуванні запити введення/виведення. br/>
hFile - описувач відкритого порту. br/>
dwFlags - вироблені дії у вигляді набору ...