Визуальный компонент-монитор COM-порта

    Сегодня мы попробуем создать визуальный компонент для работы с разного рода считывателями, подключаемыми по COM-порту (правильное название интерфейса – RS232). Наша цель — получать последовательность байт, которую отправляет устройство при считывании.

    Начнем с создания нового проекта типа Delphi Component:
    image
    В следующем окне выберем TEdit в качестве родительского компонента.
    image
    Напоследок, дадим звучное имя нашему будущему компоненту – TRS232Edit и поместим его в набор MyComponents палитры компонентов (RS 232 — наименование стандарта).
    image
    После нажатия Finish назовем модуль компонента uRS232Edit.pas и сохраним его. Среда разработки автоматически сформирует такой шаблон:

    unit uRS232EANEdit;
    interface
    uses
    SysUtils, Classes, Controls, StdCtrls;

    type
    TRS232Edit = class(TEdit)
    private
    { Private declarations }
    protected
    { Protected declarations }
    public
    { Public declarations }
    published
    { Published declarations }
    end;

    procedure Register;

    implementation

    procedure Register;
    begin
    RegisterComponents('MyComponents', [TRS232Edit]);
    end;

    end.


    Объявим структуру для хранения 20-ти байтов с порта (больше и не надо :))

    type
    TBuffer = array[0..20] of byte;


    Начинаем закладывать функционал. Для начала объявим в секции private класса TRS232Edit переменные, в которых будем хранить параметры соединения с портом.

    cComPort : integer;   // номер порта
    cBaud : integer;  // скорость передачи (бод)
    cParity : integer; // режим проверки четности
    cCountBit : integer;  //число бит данных
    cStopBit : integer;  //число стоповых бит


    Ещё нам понадобятся

    CommHandle : integer;  //хэндл COM-порта
    DCB : TDCB;  //структура для хранения параметров соединения с портом
    Ovr : TOverlapped; //структура для корректности асинхронных процессов
    Stat : TComStat;  //  структура для хранения состояния порта
    CommThread : THandle;  //хэндл потока, обрабатывающего события порта
    function DigitHex(aValue: Integer): Char;
    function GetAsHexagonal(aValue: Integer): String;  //преобразование в 16-ричный код
    function DecodeBarCode(buf : TBuffer; bufsize : integer) : string;
    procedure PortInit;
    procedure SetZero;


    и в секции public

    BarCode : string; //будет выводиться в свойство Text
    constructor Create(AOwner:Tcomponent);override;
    destructor Free;
    procedure Init(comport, baud, parity, countbit, stopbit : integer);


    Инициализировать соединение с портом будем вызовом метода Init. В нем присываиваются парамерты внутренним переменным, выставляются начальные значения и вызывается метод непосредственно коннекта.

    procedure TRS232EANEdit.Init(comport, baud, parity, countbit, stopbit : integer);
    begin
    cComPort := comport;
    cBaud := baud;
    cParity := parity;
    cCountBit := countbit;
    cStopBit := stopbit;
    SetZero;
    PortInit;
    end;


    Наибольший интерес здесь представляет метод PortInit — разберем его детально

    procedure TRS232EANEdit.PortInit;
    var
    ThreadID: dword ;
    begin
    //открытие порта и получение его хэндла
    CommHandle:= CreateFile(cComPort,GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,0);
    //ставим маску - "по пришествии определенного символа"
    SetCommMask(CommHandle,EV_RXFLAG);
    //получаем текущие настройки соединения в DCB
    GetCommState(CommHandle, DCB);
    //выставляем наши значения
    DCB.BaudRate:=cBaud;
    DCB.Parity:=cParity;
    DCB.ByteSize:=cCountBit;
    DCB.StopBits:=cStopBit;
    DCB.EvtChar:=chr(13); // будем ждать прихода байта 0x0D

    //применение новых значений
    SetCommState(CommHandle,DCB);
    /* создаем параллельный поток, где вертеться процедура приема строки. Третий параметр - указатель на класс нашего компонента. BeginThread - обертка вокруг CreateThread. @ReadComm - указатель на функцию приема строки */

    CommThread := BeginThread(nil,0,@ReadComm,Self,0,ThreadID);
    end;


    Прием данных происходит в процедуре ReadComm

    procedure ReadComm(s : Pointer);
    var
    Resive : TBuffer;
    a : TRS232EANEdit;
    begin
    a := s; // s - указатель на объект нашего компонента
    while true do
    begin
    a.TransMask:=0;
    WaitCommEvent(a.CommHandle,a.TransMask,@a.Ovr);
    if (a.TransMask and EV_RXFLAG)=EV_RXFLAG then //проверяем нужное событие
    begin
    ClearCommError(a.CommHandle,a.Errs,@a.Stat);
    ReadFile(a.CommHandle, Resive, a.Stat.cbInQue, a.Stat.cbInQue, @a.Ovr);//читаем
    a.Text := a.DecodeBarCode(Resive, 20);  //в поле появляется штрих-код
    Application.ProcessMessages;
    end;
    end;
    end;


    Всё. Компилим, устанавливаем. Чтобы считываение запустилось, в тестовом приложении достаточно приписать что-то вроде

    RS232Edit1.Init(1, 9600, 0, 8, 1)
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 30
    • –4
      Вау. А я и не знал, что на Делфи всё ещё кто-то пишет вне ВУЗов с устаревшей на 15 лет программой обучения.
      • +1
        >анимэ на аватарке
        >http://hivemind.me
        Да шо ты говоришь то!
        • +1
          • –4
            Самое забавное, что таблица только подтверждает мною сказанное. Язык ушёл из топа, доля продолжает падать, используется в основном там, где есть тонны legacy-кода, перспективы развития не прослеживаются вообще.
            • +3
              Самое главное, таблица только противоречит Вами сказанному: на Делфи все-таки пишут. Не нравится язык — не пишите.
            • 0
              Ассемблер и Ада имеют кучу зелёных стрелочек.
              Не думаю что этот топ так уж объективен :)
              • 0
                Дайте какой-нибудь другой топ
            • +2
              AIMP, QIP, R&Q, The Bat!, Download Master, Inno Setup написаны на Delphi. Они устарели на 15 лет?
              • +1
                Total Commander самое главное.
                • +2
                  ertaquo и Oxide расширили мой кругозор =) Спасибки.
                  Насчет 15ти лет — не устарели!!!

                  ps Пользуюсь, 4 из 7 представленных программ =)
                • –2
                  Не использовал ни одной из них уже много лет. Наверное, потому что эти годы живу без windows.
                  • +1
                    Игрушка Hedgewars, архиватор Peazip и клон Total Commander — Double Commander написаны на Free Pascal. Более-менее знаменитых программ под линукс назвать не могу, потому что под ним паскаль и его диалекты не особо распространены. Под маками они еще меньше используются, так что для них назвать не могу ни одной.
                    Что Delphi, что паскаль вполне живы и до сих пор много где используются. Например, если мне надо что-то на скорую руку и с графическим интерфейсом слепить, я скорее всего возьму Delphi. Как вариант — C#, но его я довольно плохо знаю и он требует .NET. В Delphi довольно легко использовать сторонние компоненты, а написано их немало — на www.torry.net/ больше 10 тысяч всяких полезностей.
                  • +1
                    Ещё виндовый клиент Skype, KMPlayer, FinalBuilder, PyScripter, BS Player
                    • 0
                      KMP, имхо, наиболее функциональный плеер
                    • 0
                      мне очень нравится r&q, но он практически не развивается, и по сравнению с конкурентами выглядит устаревшим :(
                    • +2
                      На Делфях пишут, пишут и пишут хорошо =)
                      • –2
                        Я не говорю, что на них нельзя хорошо писать. Писать хорошо можно хоть на брейнфаке. У языка объективно есть тонны проблем, главная из которых — ограниченность одной платформой. Даже софт писаный на Визуальном Основном с успехом компилится и работает на Mac и Linux. Не говоря уже о разных мобилках.
                        • 0
                          Скоро и на дельфи можно будет компилить программы для Mac и Linux.
                          Только, боюсь, как и любое кроссплатформенное, будет выглядеть ненативно, т.е. на мой взгляд, средненький плюс в наличии кроссплатформенности.
                          • 0
                            Да есть тот же Delphi.NET. Потом эти сборки заставить прожевать Mono — то ещё веселье. А ещё у меня есть сомнения, что борланд (или кто там сейчас владеет) осилит создание нормального компилятора под ARM.
                            • +1
                              Delphi.NET давно мёртв, ему на смену пришёл Delphi Prism.
                              Embarcadero сейчас акцентируются на создании 64-битного компилятора (выйдет в сентябре) и Linux/Mac (может тогда же будет доступен, но сомневаюсь).
                              ARM? Думаю ждать пока не стоит, хотя и не уверен что очень надо.
                              Опять же, если разбрасываться во все стороны, то ничего не успеешь, не майкрософт, не хватит ресурсов. Хотя последняя дельфи у меня работает на порядок стабильнее студии 2010.
                            • 0
                              Я связан договором о неразглашении, но выглядеть будет нативно и пиздато. Я уже видел. :)
                              • 0
                                Супер!
                                Я правильно понял, что в новой версии будут полные и стабильные реализации c поддержкой IDE и прочего и 64 битов и Linux/Mac?
                                И ещё маленький вопрос: FireMonkey будет заменой VCL или они будут парарельно в дельфи или ещё как? Не получится ли, что понадобится переписывать программы.
                                • 0
                                  Да, 32 и 64 бита, Винда и Мак… Линупса нету в списке. Обезьянка будет не заменой. Обезьянка — это библиотека для построения кроссплатформенных ГУЕв. То есть, если интересует только Винда, оставляем VCL. Если нацелились на все подряд, переделываем через FireMonkey.
                            • 0
                              Free Pascal и IDE Lazarus. Они вполне кроссплатформенны. FPC поддерживает диалект Delphi. Минус FPC — недостаточная оптимизация, что ведет к увеличению размера программы. Но если писать не демки в 10 килобайт, а какую-нибудь более-менее серьезную программу, не сильно зависящую от ОС (то бишь не использующую специфические функции ОС), то все будет пучком.
                              • +2
                                Ну вы сравнили делфи с его VCL и фрипаскаль. Код на паскале можно и GCC компилить при желании, VCL от этого там не появится.
                                • 0
                                  В Lazarus есть набор классов, сходный с VCL. Недостающие можно довольно легко портировать или переписать.
                                  • +1
                                    К сожалению, Lazarus очень сильно проигрывает любой версии Delphi в плане RTL/VCL: количество ошибок, стабильность в целом, функциональные возможности. Для крупных проектов он просто неюзабелен.
                                    • 0
                                      Лазарус до чих пор напоминает какое-то школьное поделие. Напихали рюшек и финтифлюшек, а баги поправить — руки не дошли.
                          • НЛО прилетело и опубликовало эту надпись здесь

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