Использование стандартного диалога настроек порта

Не всегда настройку порта можно агрессивно зашить в код программки. Наружные устройства могут позволять изменять характеристики полосы связи, в большинстве случаев скорость обмена, которая находится в зависимости от длины соединительного кабеля. В таких случаях уместно предоставить юзеру самому задавать режимы обмена. Можно самому создать соответственный настроечный диалог, а можно пользоваться Использование стандартного диалога настроек порта стандартным, предоставляемым операционной системой, а поточнее, производителем порта. Стандартный диалог выводится функцией CommConfigDialog, которая работает со структурой COMMCONFIG. Как и в случае со структурой DCB, заполнять структуру COMMCONFIG можно вручную либо вызовом соответственных функций.

Структура COMMCONFIG имеет последующие поля:

typedef struct _COMM_CONFIG {

DWORD dwSize;

WORD wVersion;

WORD wReserved;

DCB Использование стандартного диалога настроек порта dcb;

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

Устройство-зависимый блок инфы. Это поле может быть хоть какого размера либо вообщем отсутствовать.

Невзирая на то, что нужна только DCB, приходится иметь дело со всеми полями. Наполнение данной структуры противоречивыми данными может привести к неверной настройке порта, потому Использование стандартного диалога настроек порта следует воспользоваться функцией GetCommConfig:

BOOL GetCommConfig(

HANDLE hCommDev,

LPCOMMCONFIG lpCC,

LPDWORD lpdwSize

);

Характеристики функции последующие:

hCommDev

Дескриптор открытого коммуникационного порта.

lpCC

Адресок выделеного и заполненого нулями, не считая поля dwSize, блока памяти под структуру COMMCONFIG. В поле dwSize необходимо занести размер структуры COMMCONFIG. После вызова функции все поля структуры будут Использование стандартного диалога настроек порта содержать информацию о текущих параметрах порта.

lpdwSize

Адресок двойного слова, которое после воврата из функции будет содержать число практически переданных в структуру б.

В случае удачного окончания функция возвращает ненулевое значение. Характеристики функции CommConfigDialog последующие:

lpszName

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

hWnd

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

lpCC

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

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

Фактическая настройка порта производится функцией SetCommConfig:

BOOL SetCommConfig(

HANDLE hCommDev,

LPCOMMCONFIG lpCC,

DWORD dwSize

);

Характеристики имеют то Использование стандартного диалога настроек порта же самое значение, как и в функции GetCommConfig. На рис.2.10 показано соответствие меж полями структуры DCB и полями диалогового окна опций порта.

Рис.16.10. Соответствие полей структуры DCB

Пример 5. Выполнить задание предшествующего примера, но с возможностью опции характеристик порта через стандартное диалоговое окно.

Пояснение. Порядок действий:

1. Запускаем среду разработки Visual Studio .NET. Открываем проект Использование стандартного диалога настроек порта, сделанный в примере 4.

2. Добавляем на форму отран управления кнопка и изменяем надпись на «Настроить порт» (поле «Caption» на страничке параметров) (рис.16.11).

Рис.16.11. Окно программки

3. Добавляем обработчик действия нажатия на кнопку «Настроить порт». Обработчик действия должен смотреться последующим образом:

void CCOMTestDlg::OnBnClickedButton3()

{

DWORD sz;

COMMCONFIG comm; // переменная структуры

if(!GetCommConfig(m Использование стандартного диалога настроек порта_hCom,&comm,&sz)) // получение характеристик порта

{

MessageBox("Нереально получить характеристики порта!");

return;

}

CommConfigDialog("COM2",NULL,&comm); // вызов диалога опции порта

if(!SetCommConfig(m_hCom,&comm,sz)) // установка характеристик порта

MessageBox("Нереально установить характеристики порта!");

}

После компиляции проекта следует открыть порт. После чего нажатие на кнопку «Настроить порт» приведет к возникновению диалогового окна Использование стандартного диалога настроек порта, показанного на рис.16.12.

Рис.16.12. Окно опции порта

Если надавить на кнопку «Настроить порт», за ранее не открыв порт, появится окно сообщения с надписью "Нереально получить характеристики порта!".

Функция CommConfigDialog не делает опции порта. Она все только позволяет юзеру поменять некие поля в блоке DCB, содержащемся в структуре COMMCONFIG.

Прием и передача Использование стандартного диалога настроек порта данных

Прием и передача данных производится функциями ReadFile и WriteFile, другими словами теми же самыми, которые употребляются для работы с дисковыми файлами. Ах так смотрятся макеты этих функций:

BOOL ReadFile(

HANDLE hFile,

LPVOID lpBuffer,

DWORD nNumOfBytesToRead,

LPDWORD lpNumOfBytesRead,

LPOVERLAPPED lpOverlapped

);

BOOL WriteFile(

HANDLE hFile,

LPVOID lpBuffer,

DWORD nNumOfBytesToWrite Использование стандартного диалога настроек порта,

LPDWORD lpNumOfBytesWritten,

LPOVERLAPPED lpOverlapped

);

Описание характеристик функций:

hFile

Дескриптор открытого файла коммуникационного порта.

lpBuffer

Адресок буфера. Для операции записи данные из этого буфера будут передаваться в порт. Для операции чтения в этот буфер будут помещаться принятые данные.

nNumOfBytesToRead, nNumOfBytesToWrite

Число ожидаемых к приему либо предназначенных к передаче б.

nNumOfBytesRead, nNumOfBytesWritten

Число практически принятых либо Использование стандартного диалога настроек порта переданных б. Если принято либо передано меньше данных, чем запрошено, то для дискового файла это свидетельствует об ошибке, а для коммуникационного порта совершенно не непременно. Причина в тайм-аутах.

lpOverlapped

Адресок структуры OVERLAPPED, применяемой для асинхронных операций. Для синхронных операций данный параметр должен быть равным NULL.

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

BOOL TransmitCommChar(

HANDLE hFile,

char cChar

);

Данная функция передает один (и только один) внеочередной б в линию, не глядя на наличие данных в очереди передатчика, и перед Использование стандартного диалога настроек порта этими данными. 1-ый параметр – дескриптор открытого порта. 2-ой параметр – знак для передачи.

Пример 6. Микропроцессорная система сбора данных, присоединенная к ПК через СОМ-порт, делает контроль температуры некого объекта. Написать программку, которая воспринимает значение температуры и показывает ее в виде графика. Для получения данных нужно выслать запрос – команда 0хBC. Периодичность запроса Использование стандартного диалога настроек порта значения температуры – 100 мс. Скорость передачи составляет 9600 бит/с. Формат посылки – 8 бит данных в информационном блоке, 1 стоповый бит, проверка на чётность отсутствует.

Пояснение. Порядок действий:

1. Запускаем среду разработки Visual Studio .NET. Открываем проект, сделанный в примере 5, который берём за базу.

2. Изменяем вид диалогового окна. Выносим на форму отран управления «Static Text» корректируем Использование стандартного диалога настроек порта его ID на IDC_STATIC3. Также очищаем поле «Caption» чтоб не отображался текст. Потом нужно растянуть этот отран управления так, чтоб по ширине он занял всю форму, а по высоте – примерно 70%. В поле «Border» на страничке параметров установить значение «True». В области, которую занял отран управления «Static Text Использование стандартного диалога настроек порта» будет отображаться график конфигурации температуры. Также нужно привязать к элементу этому управления переменную с именованием m_graph. На рис.16.13 приводится вид диалогового окна.

Рис.16.13. Окно программки

Не считая того, нужно добавить отран управления «Static Text» для отображения текущей температуры. Поменять ID на IDC_STATIC4. К этому элементу управления привязать переменную с Использование стандартного диалога настроек порта именованием m_currtemp.

3. Для хранения приобретенных данных о температуре употребляется переменная m_temp и имеющая тип CByteArray. Эта переменная – член класса CCOMTestDlg. Для того, чтоб добавить переменную, в окне «Class View» выделить класс «CCOMTestDlg», вызвать контекстное меню и из подменю «Add» избрать команду «Add Variable». Показавшееся Использование стандартного диалога настроек порта диалоговое окно заполнить так, как показано на рис.16.14.

Рис.16.14. Окно добавление переменной

4. Добавляем обработчик действия таймера. Для этого из странички параметров (Properties) вызвать окно «Messages» и напротив позиции «WM_TIMER» избрать «OnTimer» (рис.16.15).

Рис.16.15 Создание обработчика действия таймера

5. Добавляем в функцию - обработчик действия таймера код, как показано ниже:

void CCOMTestDlg::OnTimer(UINT Использование стандартного диалога настроек порта nIDEvent)

{

TransmitCommChar(m_hCom,(char)0xBC); // передача значения 0xBC

BYTE rdata;

DWORD size;

ReadFile(m_hCom,&rdata,1,&size,NULL);// чтение 1 б с порта

if(size!=1) // если 1 б не считан

{

// выдаем сообщение

SetWindowText("Отсутствуют данные о температуре!");

return; // выход из функции

}

m_temp.Add(rdata); // добавляем данные в массив

CString s;

// форматирование строчки

s.Format("Текущая температура Использование стандартного диалога настроек порта: %d град.",rdata);

m_currtemp.SetWindowText(s);

DrawGraph(); // обновление графика на дисплее

CDialog::OnTimer(nIDEvent);

}

В этой функции запрос на получение данных о температуре отчаливает при помощи функции TransmitCommChar. Потом происходит считывание с порта 1 б данных Если данные были получены, значение переменной size (количество считанных б) будет равно 1. Если же это значение Использование стандартного диалога настроек порта отличается от 1, выдается сообщение о том, что данные о температуре отсутствуют. Благодаря настройкам тайм-аутов, программка не «зависнет» из-за отсутствия принятых данных.

6. Реализуем функцию void DrawGraph(void). Для этого ее нужно сделать членом класса CCOMTestDlg. Реализация функции имеет последующий вид:

void CCOMTestDlg::DrawGraph(void)

{

CClientDC Использование стандартного диалога настроек порта dc(&m_graph); // создание контекста для рисования

CPen p(PS_SOLID,2,RGB(200,0,0));// создание пера красноватого цвета

CPen pp(PS_DOT,1,RGB(0,0,0));

CRect rect;

CRgn rgn;

CPen* op;

m_graph.RedrawWindow(); // перерисовка окна рисования графика

m_graph.GetClientRect(&rect);

// получение размеров области рисоания

rgn.CreateRectRgn(0,0,rect.Width(),rect.Height());

// создание региона для ограничения области рисования

op Использование стандартного диалога настроек порта=dc.SelectObject(&pp); // установка пера

for(int x=20;x

{

dc.MoveTo(x,0); // перемещение исходной позиции

dc.LineTo(x,rect.Height()); // рисование полосы

}

dc.SetTextColor(RGB(50,50,50)); // установка цвета текста

dc.SetBkColor(RGB(210,210,210)); // установка цвета фона

for(int y=20;y

{

dc.MoveTo(0,rect.Height()-y);

dc.LineTo(rect Использование стандартного диалога настроек порта.Width(),rect.Height()-y);

CString s;

s.Format("%d",y); // форматирование строчки

dc.TextOut(rect.Width()-30,rect.Height()-y,s);

// вывод текстовых меток

}

dc.SelectObject(&p); // выбор красноватого пера в контекст

dc.SelectClipRgn(&rgn); // установка региона

if(rect.Width()<=m_temp.GetCount()) m_temp.RemoveAll();

// если значение частей в массиве превосходит размер области

// рисования Использование стандартного диалога настроек порта, то удаляются все элементы массива

for(int i=1;i

{

// рисование графика температуры

dc.MoveTo(i,rect.Height()-m_temp.GetAt(i));

dc.LineTo(i-1,rect.Height()-m_temp.GetAt(i-1));

}

dc.SelectObject(op);

}

7. Корректируем обработчик нажатия на кнопку «Открыть порт». Добавляем в этот обработчик строчку

SetTimer(1,200,NULL);

При нажатии на эту Использование стандартного диалога настроек порта кнопку, в случае удачного открытия порта, запускается таймер, который будет срабатывать через каждые 200 мс. При всем этом будет вызываться функция OnTimer, в какой реализован код по запросу данных о температуре и их отображению.

8. Корректируем обработчик действия нажатия на кнопку «Закрыть порт». Так как при закрытии порта данные нереально будет считать Использование стандартного диалога настроек порта, нужно приостановить таймер. Для этого в обработчик добавляем последующую строку:

KillTimer(1);

9. Откомпилировав проект, появится диалоговое окно, как показано на рис.16.16 (при условии, что данные принимаются через порт).

Рис.16.16. Окно программки

Внедрение потоков

В прошлом примере функция ReadFile завершала свое выполнение даже если данные не поступали в порт. Методом анализа Использование стандартного диалога настроек порта количества считанных б можно узнать причину окончания работы функции (приняты данные, истек тайм-аут). Существует ряд задач, в каких поток данных не является равномерным. К примеру, пожарная сигнализация. При обычной обстановке в компьютер данные могут не поступать, а обрабатываться на локальных объектах. В случае пожара на главный компьютер передаются данные Использование стандартного диалога настроек порта о месте появления пожара, также другая информация. Для реализации таковой задачки внедрение повторяющегося опроса порта будет не действенным. В данном случае более прибыльно использовать потоки.

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

DWORD WINAPI ThreadFunction(PVOID pvParam){ ... return(0); }

Функция потока может делать любые задачки. В нашем случае это ожидание данных с порта и передача управления главной программке. Действия, связанные с портом, отслеживаются при помощи функции:

BOOL SetCommMask(

HANDLE hFile,

DWORD dwEvtMask

);

В качестве первого параметра передается дескриптор открытого Использование стандартного диалога настроек порта порта. Для слежения за появлением определенных событий, связанных с портом, нужно установить маску отслеживаемых событий, которая задается вторым параметром. Можно указывать всякую комбинацию последующих значений:

EV_BREAK - Состояние разрыва приемной полосы

EV_CTS - Изменение состояния полосы CTS

EV_DSR - Изменение состояния полосы DSR

EV_ERR - Ошибка четности

EV_RING - Входящий звонок на модем (сигнал Использование стандартного диалога настроек порта на полосы RI порта)

EV_RLSD - Изменение состояния полосы RLSD (DCD)

EV_RXCHAR - Знак принят и помещен в приемный буфер

EV_RXFLAG - Принят знак данный полем EvtChar структуры DCB использованной для опции режимов работы порта

EV_TXEMPTY - Из буфера передачи передан последний знак

Если dwEvtMask равно нулю, то отслеживание событий воспрещается.

Очевидно Использование стандартного диалога настроек порта, всегда можно получить текущую маску отслеживаемых событий при помощи функции

BOOL GetCommMask(

HANDLE hFile,

LPDWORD lpEvtMask

);

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

Когда маска отслеживаемых событий задана, можно остановить выполнение программки до пришествия действия. При всем этом программка не будет занимать микропроцессор. Это производится Использование стандартного диалога настроек порта вызовом функции

BOOL WaitCommEvent(

HANDLE hFile,

LPDWORD lpEvtMask,

LPOVERLAPPED lpOverlapped,

);

где hFile – дескриптор открытого порта. В переменной, адресуемой вторым параметром lpEvtMask, в единичное состояние установятся только те биты, которые соответствуют реально произошедшим событиям.

Адресок структуры OVERLAPPED (3-ий параметр функции – lpOverlapped) требуется для асинхронного ожидания. Для синхронных операций этот параметр должен быть NULL Использование стандартного диалога настроек порта.

Функция WaitCommEvent приостанавливает выполнение потока до того времени, пока не возникнет какое-либо из событий, данных маской. Для того, чтоб сказать основной программке, что появилось событие, связанное с портом, можно использовать механизм передачи сообщений, сделанных юзером. Для этого употребляются последующая функция:

LRESULT SendMessage(HWND hWnd, UINT Msg Использование стандартного диалога настроек порта, WPARAM wParam, LPARAM lParam );

Эта функция WinAPI отправляет определенное сообщение окну либо окнам. Функция вызывает оконную функцию (WndProc) определенного окна и не выходит из процедуры, пока та не обработает сообщение. Другими словами, выполнение программки не будет продолжено, пока сообщение не будет обработано.

hWnd - дескриптор окна, которое получает сообщение;

Msg Использование стандартного диалога настроек порта - определенное сообщение;

wParam - содержит определенную информацию о сообщении (находится в зависимости от сообщения);

lParam - содержит определенную информацию о сообщении (находится в зависимости от сообщения).

Возвращаемое значение функции находится в зависимости от типа посылаемого сообщения.

Если диалоговое окно получает сообщение, вызывается определенная функция. Какая конкретно функция будет вызвана, указывается в карте Использование стандартного диалога настроек порта сообщений (Message Map). Макет функции – обработчика пользовательского сообщения имеет вид:

LRESULT OnMyMessage(WPARAM wp, LPARAM lp);

Каждое сообщение имеет собственный номер. Некие из сообщений заняты операционной системой, потому их нельзя использовать. Сообщения с номерами больше чем WM_USER не задействованы, потому их можно использовать.

Пример 7.Написать программку обмена Использование стандартного диалога настроек порта данными меж 2-мя компьютерами по СОМ-порту (чат). Скорость обмена данными – 9600 бит/с.

Пояснение. Порядок действий:

  1. Запускаем среду разработки Visual Studio .NET. Открываем проект, сделанный в примере 4.
  2. Добавляем на форму последующие элементы управления: Edit Control, Button, List Box, также Static Text, и располагаем их на диалоговом окне так, как Использование стандартного диалога настроек порта показано на рис.16.17.

Рис.16.17. Спроектированное диалоговое окно

В элементе управления Edit Control юзер будет вводить текстовое сообщение. При нажатии на кнопку «Отправить» введенное сообщение будет передано в порт. Принимаемые сообщения будут отображаться в элементе управления «Список» (List Box). Для этого элемента управления на страничке параметров в поле «Sort» установить значение «False». В неприятном Использование стандартного диалога настроек порта случае строчки, добавляемые в отран управления, будут отсортированы по алфавиту, и порядок приема сообщений не будет сохраняться.

  1. Связываем с органами управления переменные. К «List Box» привязывается переменная с именованием m_recmess, а к текстовому полю «Edit Control» переменная с именованием m_sendmess. Для выполнения этих действий нужно по очереди Использование стандартного диалога настроек порта выделить каждый отран управления и вызвать контекстное меню, из которого избрать команду «Add Variable» (рис.16.18).

Рис.16.18. Добавление переменной

  1. Создаем глобальную переменную hCom. В этой переменной будет храниться дескриптор открытого порта. Так как переменная глобальная, доступ к ней вероятен из функции потока. Также нужно найти пользовательское сообщение. Для этого Использование стандартного диалога настроек порта сначала файла COMTestDlg.cpp, после секции #include, добавляем строчки:

volatile HANDLE hCom; // глобальная переменная – дескриптор

#define WM_MESSRECIEVED WM_USER+1 // пользовательское сообщение

Для остановки работы потока следует знать указатель на него. В библиотеке MFC для работы с потоками употребляется класс CWinThread. В класс CCOMTestDlg нужно добавить переменную-член класса:

CWinThread* m_thread;

При Использование стандартного диалога настроек порта разработке потока в этой переменной будет храниться указатель на него.

  1. Добавляем функцию рабочего потока, в каком будет ожидаться прием сообщения. Эта функция не является членом класса диалогового окна CCOMTestDlg. Ее описание следует расположить в файле COMTestDlg.cpp, до описания обработчиков событий нажатия на кнопку. Функция смотрится последующим образом:

UINT Использование стандартного диалога настроек порта ThreadFunction(LPVOID param)

DWORD cm;

SetCommMask(hCom, EV_RXCHAR); // установка маски событий порта

PurgeComm(hCom, PURGE_RXCLEAR

  1. Изменяем обработчик действия нажатия на кнопку «Открыть порт». В случае удачного открытия порта, глобальной переменной hCom нужно присвоить дескриптор открытого порта. Не считая того, нужно запустить поток. Обработчик действия нажатия на кнопку «Открыть Использование стандартного диалога настроек порта порт» имеет вид:

void CCOMTestDlg::OnBnClickedButton1()

{

CString sp;

m_port.GetLBText(m_port.GetCurSel(),sp);

m_hCom=CreateFile(sp,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);

// открываем поочередный порт

if(m_hCom==INVALID_HANDLE_VALUE)

{

m_status.SetWindowText("Нереально открыть порт!");

// если нереально открыть порт, выдаем сообщение

return;

}

else Использование стандартного диалога настроек порта // если порт открыт

m_status.SetWindowText("Порт открыт.");

// сообщаем, что порт открыт

m_bOpen.EnableWindow(0); // изменение состояний

m_bClose.EnableWindow(1); // частей управления

m_port.EnableWindow(0);

}

DCB *pDCB; // указатель на структуру DCB

COMMTIMEOUTS ct; // переменная для опции тайм-аутов

pDCB=new DCB;

memset(pDCB,0,sizeof(DCB)); // обнуление полей структуры

if(!GetCommState(m_hCom,pDCB)) // получение состояния порта

{

MessageBox Использование стандартного диалога настроек порта("Нереально получить характеристики порта!");

return;

}

if(!GetCommTimeouts(m_hCom, &ct)) // получение тайм-аутов

{

MessageBox("Нереально получить значения тайм-аутов!");

return;

}

pDCB->DCBlength=sizeof(DCB); // размер структуры

pDCB->BaudRate=CBR_9600; // скорость передачи данных

pDCB->ByteSize=8; // размер слова

pDCB->StopBits=ONESTOPBIT; // количество стоповых бит

pDCB->Parity=NOPARITY; // четность отсутствует

ct.ReadIntervalTimeout=10; // значение тайм-аута чтения

ct.ReadTotalTimeoutConstant=300;

ct Использование стандартного диалога настроек порта.ReadTotalTimeoutMultiplier=2;

ct.WriteTotalTimeoutConstant=300; // значение тайм-аута записи

ct.WriteTotalTimeoutMultiplier=2;

if(! SetCommState(m_hCom,pDCB)) // установка характеристик порта

{

MessageBox("Нереально установить характеристики порта!");

return;

}

if(!SetCommTimeouts(m_hCom,&ct)) // установка тайм-аутов

{

MessageBox("Нереально установить значения тайм-аутов!");

return;

}

hCom=m_hCom;

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

m_thread=AfxBeginThread(ThreadFunction, m_hWnd Использование стандартного диалога настроек порта, THREAD_PRIORITY_NORMAL); // пуск рабочего потока

}

  1. Изменяем обработчик действия нажатия на кнопку «Закрыть порт». При нажатии на кнопку нужно приостановить выполнение потока. Обработчик действия нажатия на кнопку «Закрыть порт» имеет вид:

void CCOMTestDlg::OnBnClickedButton2()

{

::TerminateThread(m_thread->m_hThread,0); // остановка потока

CloseHandle(m_hCom); // закрытие порта

m_status.SetWindowText("Порт закрыт.");

m Использование стандартного диалога настроек порта_port.EnableWindow(1);

// изменение состояний частей управления

m_port.EnableWindow(1);

m_bOpen.EnableWindow(1);

m_bClose.EnableWindow(0);

}

  1. Создаем функцию – обработчик сообщения WM_MESSRECIEVED, которое передается главному окну программки из рабочего потока при приеме данных. Эта функция является членом класса диалогового окна. В окне «Class View» следует выделить класс CCOMTestDlg и из контекстного меню Использование стандартного диалога настроек порта избрать команду «Add Function». Появится диалоговое окно, в каком нужно указать заглавие функции, также тип и имена характеристик, передаваемых в функцию. Вид этого окна представлен на рис.16.19.

Рис.16.19. Окно прибавления функции в класс

Также нужно указать, что при возникновении сообщения WM_MESSRECIEVED будет вызвана функция OnRecieveData. Для этого карту сообщений Использование стандартного диалога настроек порта необходимо поменять последующим образом:

BEGIN_MESSAGE_MAP(CCOMTestDlg, CDialog)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

//}}AFX_MSG_MAP

ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)

ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)


ispolzujte-sintopticheskoe-chtenie-dlya-poznaniya-zhizni.html
ispolzujte-tehnologii-dlya-podkrepleniya-garantij.html
ispolzujte-vnutrennyuyu-rech-dlya-upravleniya-mishleniem.html