Программирование под модем.
Чтобы постоянно опрашивать модем на предмет
поступления новых символов надо открыть
дополнительный поток с бесконечным циклом.
//Прототип функции дополнительного потока.
UINT TerminalThread(LPVOID arg);
DWORD dwCount;
DCB dcb;
HANDLE hCommPort;
DWORD Errors;
COMSTAT pComStat;
COMMTIMEOUTS CommTimeouts;
UINT TerminalThread(LPVOID arg)
{
//Открытие порта
hCommPort = CreateFile(options.Port, GENERIC_READ
| GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, 0);
//Получаем настройки порта
GetCommState(hCommPort, &dcb);
//Меняем часть настроек на свои
dcb.BaudRate = 9600; //Скорости в бодах
dcb.ByteSize = 8; //Байты информации
dcb.Parity = NOPARITY; //Четность
dcb.StopBits = ONESTOPBIT; //Кол-во стоп. битов
//Устанавливаем новые настройки
SetCommState(hCommPort, &dcb);
/* Установка таймаутов.
Служит, чтобы программа не висла
в ожидании ответа от модема */
GetCommTimeouts(hCommPort,&CommTimeouts);
CommTimeouts.ReadIntervalTimeout = 50;
CommTimeouts.ReadTotalTimeoutMultiplier = 1;
CommTimeouts.ReadTotalTimeoutConstant = 50;
CommTimeouts.WriteTotalTimeoutMultiplier = 1;
CommTimeouts.WriteTotalTimeoutConstant = 50;
SetCommTimeouts(hCommPort,&CommTimeouts);
//Очистка буфера (На всякий случай)
FlushFileBuffers(hCommPort);
//Цикл опроса модема
for (;;) {
//Опрос модема
ReadFile(hCommPort, &ch, 1, &dwCount, NULL);
if(ch) //Проверка на наличие символа
{
//Вывод поступившего символа
Функция_форматированного_вывода_символа(&ch,1);
};
ch = 0;
}
return 0;
}
Класс ввода/вывода HCSVIEW
Ниже приведенный класс предназначен для
форматированного ввода/вывода. По интерфейсу
класс максимально близок к средствам
ввода/вывода под Dos. Т.е. вам придется только
задать окно и текст, который надо вывести в этом
окне, все остальное класс берет на себя. Текст,
который не помещается в окне будет автоматически
перенесен на следующую строку. Также класс
понимает символы возврата каретки и перехода на
следующую строку. Чтобы осуществить прокрутку в
окне, надо всего лишь перенаправить данные
получаемые по сообщению ON_WM_SCROLL соответствующей
функции класса.
Класс HCSView:
class HCSView : public CWnd
{
char ch;
TEXTMETRIC Font;
RECT WinPos;
char Buf[10000];
int MaxX,MaxY,x,y,ScrollRange,ScrollPos;
int Bufi;
CClientDC *dcCompPtr;
CBrush membrush;
CBitmap VirtWin;
CWnd *WinPtr;
CDC memdc;
int FullLineSize;
public:
//Функция прокрутки.
void HSScroll(UINT SBCode, UINT Pos, CScrollBar *SB);
//Установить шрифт. NewFont - новый шрифт.
void HSSetFont(LOGFONT NewFont);
//Установить цвет текста.
void HSSetTextColor(COLORREF TextColor);
/*
Функция вывода текста.
Заносит данные в буфер
И вызывает функцию HFillVirtWin.
*str - указатель на строку.
l - длинна строки.
*/
void HSTextOut(char *str, int l);
/*
Функция перерисовки виртуального окна.
Выводит данные и буфера в виртуальное окно.
Имеет смысл вызывать при изменении размеров окна.
При получении сообщения ON_WM_SIZE
Функцию нужно вызывать без аргументов:
HFillVirtWin();
*/
void HFillVirtWin(int csr = 1,int nw = 1,int bp = 0);
/*
Функция копирования виртуального окна в
реальное. Нужно вызывать при каждом сообщении
WM_ON_PAINT
*/
void HSCopyVtR();
//Конструктор класса.
HCSView(CWnd *SWinPtr);
};
Пример работы с классом
/*
Пример части программы выводящий символы,
поступающие с клавиатуры, на экран.
MainWin - объект класса (CMainWin) окна
в которое будет выводится текст.
*/
HCSView View(&MainWin);
//Вывод символа на экран
afx_msg void CMainWin::OnChar(UINT ch, UINT count, UINT flag)
{
View.HSTextOut(&c,1);
}
//Прокрутка
afx_msg void CMainWin::OnVScroll(UINT SBCode,
UINT Pos, CScrollBar *SB)
{
View.HSScroll(SBCode,Pos,SB);
}
//Перерисовка окна
afx_msg void CMainWin::OnPaint()
{
View.HSCopyVtR();
}
//Форматирования текста,
//при изменении размеров окна.
afx_msg void CMainWin::OnSize(UINT nType, int cx, int cy)
{
View.HFillVirtWin();
}
|