Программа управления LPT портом под Windows на MFC Продолжая цикл статей по программированию устройств сопряжения, а конкретно LPT порта, думаю настало время рассказать Вам о том, как написать программу для работы с данным портом под ОС Windows, т.е. в виде "привычного" взору окна с кнопочками, окошками ввода и тому подобными атрибутами.
Ну что, давайте приступим. Создаем новый MFC проект в Microsoft Visual C++ 6.0, выбирая в меню пункт File -> New. В открывшемся окне указываем тип проекта MFC AppWizard(exe). В поле Location выберете место расположения проекта. В поле Project Name введите имя проекта, например LPTWin.
Нажимаете Ok. Дальше запускается мастер построения приложения. На первом (и в нашем проекте последнем) шаге на вопрос о типе приложения выберете пункт Dialog Based. Нажимаем кнопку Finish.
Выскочит информационное окно, в котором будет дана некоторая информация по построению проекта. Не обращайте на него внимание и нажимайте Ok.
После этого перед нами появится рабочая область нашего проекта с пустой заготовкой формы, где мы сейчас начнем ваять приложение.
Сначала наполним наш диалог необходимыми элементами управления. На окне Controls выбирете элемент Group Box и разместите его на окне заготовки диалога. Должно получиться что-то похожее на рис. ниже.
Данный элемент не несет не какой фактической нагрузки и нужен он только для "декоративного" обрамления других элементов. Пока что он имеет заголовок по умолчанию Static. Давайте исправим это. Нажмите правой кнопкой мыши на него, и в выпавшем списке выберите пункт Properties.
В появившемся окне в поле Caption введите Write to Port. Закройте окно.
Далее, выберите элемент управления Static Text и разместите его в диалоге. По умолчанию он будет содержать текст Static. Замените его на Port Adress:, зайдя в свойства этого элемента.
Далее, выберите элемент управления Edit Box, и разместите его, как показано на рис. ниже. Зайдите в свойства и в поле ID вместо ID_EDIT1 введите IDC_ADRtoWrite. То что мы сейчас указали называется идентификатором элемента управления и теперь в программе данный элемент ассоциируется с этим именем.
Теперь абсолютно аналогично разместите еще один элемент Static Text с именем Data и Edit Box с идентификатором IDC_DATAtoWRITE.
Далее, выберите элемент управления Button и разместите его в диалоге. Зайдите в его свойства и в качестве заголовка укажите Write to Port. В итоге должно получиться нечто похожее на рис. ниже.
Теперь мы закончили с оформлением элементов управления, с помощью которых можно будет ввести адрес порта, указать число для записи в порт и провести запись по нажатию кнопки Write to Port. Конечно, это все пока что еще не работает, поскольку мы еще не написали ни одной строчки кода. Но это дальше. Продолжим.
Далее, по аналогии создайте набор элементов для чтения данных из порта, а именно Group Box с именем Read from Port, два Static Text`a с именами Port Adress:, Data: и два Edit Box`a с идентификаторами IDC_ADRtoRead, IDC_DATAfromRead соответственно. В результате должно получиться что-то похожее на это:
Для презентабельного вида нашего приложения растяните ("стяните") до нужных размеров как само диалоговое окно так и элементы управления, расположенные в нем.
Иногда бывает удобно посмотреть внешний вид окна не на рабочей области, а в живую. Для этого вовсе не обязательно компилировать и запускать приложение, а можно воспользоваться командой Test. Для ее запуска нужно нажать "рычажок" в нижнем левом углу программы.
Если Вы так сделаете, то появится наш созданный диалог. Он не рабочий и по щелчку по нему он закроется. Пока он открыт, можно убедиться в правильности расположения всех элементов управления.
Далее нам необходимо создать переменные для элементов управления. Для этого выбирайте в главном меню пункт View - > ClassWizard.
В открывшемся окне перейдите на вкладку Member Variables. Если в списке Class Name установлен не CLPTWinDlg то выберете его. В списке просмотра Control IDs показаны все идентификаторы для элементов управления использующихся в нашем диалоге. Будем создавать переменные только для окон редактирования. Для этого выбирайте нужный идентификатор и нажимайте кнопку Add Variable.
Например, создадим переменную для IDC_ADRtoRead. В открывшемся окне в поле Member Variable Name введите m_ADRtoRead, в списке Category - Value, а в списке Variable Type тип int. Нажмите Ok. Имя переменной не критично и может быть выбрано любым (по правилам Си, конечно), но для того чтобы не путался какой переменной соответствует тот или иной идентификатор элемента управления, я задал их имена похожими друг на друга.
Далее, по аналогии, создаем переменные для оставшихся трех окон редактирования с темеже значениями параметров Category, Variable Type и соответствующими именами. В результате окно идентификаторов должно выглядеть так:
Последнее, что нам осталось сделать, прежде чем мы возьмемся за программирование, так это подключить файлы библиотеки inpout32.dll к нашему проекту, поскольку именно с помощью ее мы будем работать с LPT портом под Windows. Процесс подключения этих файлов я подробно рассматривал в предыдущих статьях. Напомню, только, что файл inpout32.dll должен находиться в одной директории с запускаемой программой. После подключения файлов древо нашего проекта должно принять вид:
И еще один важный момент: необходимо с помощью оператора #include подключить файл с описаниями функций библиотеки (h.h) в код программы. Для этого откройте файл LPTWinDlg.cpp и добавьте в верху строчку:
#include "h.h"
после записи #include "stdafx.h".
Все, наконец-то, добрались до места, где собственно начнем писать код программы. Перейдите в редактор диалога (туда, где мы наполняли диалог элементами управления) и дважды щелкните по кнопке Write to Port. Появится окно, в котором предлагается создать функцию-обработчик на нажатие это кнопки. Ей будет дано имя OnButton1. Соглашаемся с этим и нажимаем на кнопку Ok.
Нас "перенесет" к пустой заготовке кода этой функции.
Допишите тело этой функции, используя код ниже. После этого она должна выглядеть так:
void CLPTWinDlg::OnButton1()
{
// TODO: Add your control notification handler code here
UpdateData(true);
if ((m_ADRtoWrite>0)&&(m_DATAtoWRITE>=0))
{
Out32(m_ADRtoWrite, m_DATAtoWRITE);
}
else
{
MessageBox("Вы ввели не корректные данные","Error", MB_ICONERROR);
}
}
Рассмотрим, как работает этот код. Сначала идет обращение к функции UpdateData() с параметром true. При этом в созданные нами переменные элементов управления скопируются введенные в них данные. Далее проводится проверка на корректность этих данных. Например, если адрес порта или передаваемое в него данное меньше нуля, то ситуация не совсем корректная. Если все в порядке, то идет обращение к функции Out32() библиотеки inpout32.dll.
Теперь оживим функцию предназначенную для чтения данных из порта. Для этого создайте функцию-обработчик на нажатие кнопки Read from Port, оставьте ей имя OnButton2 и добавьте в нее следующий код:
void CLPTWinDlg::OnButton2()
{
// TODO: Add your control notification handler code here
UpdateData(true);
if (m_ADRtoRead>0)
{
short d=Inp32(m_ADRtoRead);
m_DATAfromRead=d;
UpdateData(false);
}
else
{
MessageBox("Вы ввели не корректные данные","Error", MB_ICONERROR);
}
}
Я думаю, что принцип работы данного кода вполне понятен, только хотел обратить внимание на на вызов функции UpdateData() с параметром false. При этом значения переменных элементов управления скопируються в них и мы сможем наблюдать из на экране.
Все, готово! Можно компилировать и запускать. Для тестирования этой программы я использовал устройство для LPT порта в виде блока светодиодов, описанное в предыдущей статье.
Иванов Д. В.
17 ноября 2006 года
www.pcports.ru