Понедельник, Май 25, 2020

ComPort-CScrollView


// FT232ScrollView.h : interface of the CFT232ScrollView class
//

#pragma once


class CFT232ScrollView : public CScrollView
{
protected: // create from serialization only
    CFT232ScrollView();
    DECLARE_DYNCREATE(CFT232ScrollView)

// Attributes
public:
    CFT232ScrollDoc* GetDocument() const;

// Operations
public:

// Overrides
public:
    virtual void OnDraw(CDC* pDC);  // overridden to draw this view
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
    virtual void OnInitialUpdate(); // called first time after construct
    virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// Implementation
public:
    virtual ~CFT232ScrollView();
#ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
    afx_msg void OnFilePrintPreview();
    afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnPlay();
    afx_msg void OnStop();
    afx_msg void OnClear();
protected:
    boolean CaretCreated;
    CPoint  CaretPosition;
    CList<CString> mList;
    afx_msg LRESULT OnMess(WPARAM wParam, LPARAM lParam);
public:
    afx_msg void OnClose();
    afx_msg void OnKillFocus(CWnd* pNewWnd);
    afx_msg void OnSetFocus(CWnd* pOldWnd);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    long Scroll_Y;
    long Scroll_X;
    afx_msg void OnFont();
    LOGFONT lp;
    CFont cf;
};
UINT __cdecl ReadSerial(LPVOID pParam);
char*   HexToASCII(char* sour, char* dest, int len);
#ifndef _DEBUG  // debug version in FT232ScrollView.cpp
inline CFT232ScrollDoc* CFT232ScrollView::GetDocument() const
   { return reinterpret_cast<CFT232ScrollDoc*>(m_pDocument); }
#endif



// FT232ScrollView.cpp : implementation of the CFT232ScrollView class
//

#include "stdafx.h"
// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
// and search filter handlers and allows sharing of document code with that project.
#ifndef SHARED_HANDLERS
#include "FT232Scroll.h"
#endif

#include "FT232ScrollDoc.h"
#include "FT232ScrollView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include "serialport.h"
char        buf[14]="\0";
char        dest[30]="\0";
CString     data="";
CSerialPort port;
int         x=0;
int         y=0;
boolean StartStopThread=false;

// CFT232ScrollView

IMPLEMENT_DYNCREATE(CFT232ScrollView, CScrollView)

BEGIN_MESSAGE_MAP(CFT232ScrollView, CScrollView)
    // Standard printing commands
    ON_COMMAND(ID_FILE_PRINT, &CScrollView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, &CScrollView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CFT232ScrollView::OnFilePrintPreview)
    ON_WM_CONTEXTMENU()
    ON_WM_RBUTTONUP()
    ON_COMMAND(ID_PLAY, &CFT232ScrollView::OnPlay)
    ON_COMMAND(ID_STOP, &CFT232ScrollView::OnStop)
    ON_COMMAND(ID_CLEAR, &CFT232ScrollView::OnClear)
    ON_MESSAGE(MESS, &CFT232ScrollView::OnMess)
    ON_WM_CLOSE()
    ON_WM_KILLFOCUS()
    ON_WM_SETFOCUS()
    ON_WM_LBUTTONDOWN()
    ON_COMMAND(ID_32774, &CFT232ScrollView::OnFont)
END_MESSAGE_MAP()

// CFT232ScrollView construction/destruction

CFT232ScrollView::CFT232ScrollView()
    : Scroll_Y(0)
    , Scroll_X(0)
{
    CaretCreated=false;

}

CFT232ScrollView::~CFT232ScrollView()
{
}

BOOL CFT232ScrollView::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs

    return CScrollView::PreCreateWindow(cs);
}

// CFT232ScrollView drawing

void CFT232ScrollView::OnDraw(CDC* pDC)
{
    CFT232ScrollDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    LOGFONT lf;
    lf.lfHeight = 0xfffffff3;
    lf.lfWidth = 0;
    lf.lfEscapement = 0;
    lf.lfOrientation = 0;
    lf.lfWeight = 0x000002bc;
    lf.lfItalic = 0;
    lf.lfUnderline = 0;
    lf.lfStrikeOut = 0;
    lf.lfCharSet = 0xcc;
    lf.lfOutPrecision = 0x03;
    lf.lfClipPrecision = 0x02;
    lf.lfQuality = PROOF_QUALITY;
    lf.lfPitchAndFamily = 0x31;  
    strcpy(lf.lfFaceName,"Courier New");
    CFont ft;
    ft.CreateFontIndirect(&lf);
    CFont* oldf=pDC->SelectObject(&ft);

    pDoc->doc+=data;
    SetScrollSizes(MM_TEXT, CSize(Scroll_X,Scroll_Y));
    if(!CaretCreated)
    {
        TEXTMETRIC textmetric;
        pDC->GetTextMetrics(&textmetric);
        CreateSolidCaret(textmetric.tmAveCharWidth,textmetric.tmHeight);
        CaretPosition.x=CaretPosition.y=0;
        SetCaretPos(CaretPosition);
        CaretCreated=true;
    }
    
    CRect rect;
    GetWindowRect(rect);

    
    POSITION pos = mList.GetHeadPosition();
    if(pos)
    {
        for(int i=0;i<mList.GetSize();i++)
        {
            pDC->TextOutA(x,y,mList.GetNext(pos));
            y+=16;
            
        }
        y=0;
    }
    HideCaret();
    CSize size=pDC->GetTextExtent(data);
    CaretPosition.x=x+size.cx;
    CaretPosition.y=y;
    SetCaretPos(CaretPosition);
    ShowCaret();
    pDC->SelectObject(oldf);
}

void CFT232ScrollView::OnInitialUpdate()
{
    CScrollView::OnInitialUpdate();

    CSize sizeTotal;
    // TODO: calculate the total size of this view

    sizeTotal.cx = sizeTotal.cy = 100;
    SetScrollSizes(MM_TEXT, sizeTotal);
}


// CFT232ScrollView printing


void CFT232ScrollView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
    AFXPrintPreview(this);
#endif
}

BOOL CFT232ScrollView::OnPreparePrinting(CPrintInfo* pInfo)
{
    // default preparation
    return DoPreparePrinting(pInfo);
}

void CFT232ScrollView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: add extra initialization before printing
}

void CFT232ScrollView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: add cleanup after printing
}

void CFT232ScrollView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
    ClientToScreen(&point);
    OnContextMenu(this, point);
}

void CFT232ScrollView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
    theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CFT232ScrollView diagnostics

#ifdef _DEBUG
void CFT232ScrollView::AssertValid() const
{
    CScrollView::AssertValid();
}

void CFT232ScrollView::Dump(CDumpContext& dc) const
{
    CScrollView::Dump(dc);
}

CFT232ScrollDoc* CFT232ScrollView::GetDocument() const // non-debug version is inline
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFT232ScrollDoc)));
    return (CFT232ScrollDoc*)m_pDocument;
}
#endif //_DEBUG


// CFT232ScrollView message handlers


void CFT232ScrollView::OnPlay()
{
    try
    {
        //Пробуем открыть порт для асинхронной передачи
        port.Open(1, 806800, CSerialPort::NoParity, 8, CSerialPort::OneStopBit, CSerialPort::NoFlowControl, TRUE);
        //Флаг в проц для while()
        StartStopThread=true;
        //Для того, чтобы поток мог передать сообщение ему нужно знать HWND.
        HWND hWnd=GetSafeHwnd();
        //передадим ее в параметрах.
        AfxBeginThread(ReadSerial, hWnd);
    }
    catch (CSerialException* pEx)
    {
        AfxMessageBox("Не удалось найти ComPort");
        pEx->Delete();
    }
}


void CFT232ScrollView::OnStop()
{
    StartStopThread=false;
    Sleep(1000);
    //Закрываем порт
    if(port.IsOpen())
    {
        port.Close();
    }
}


void CFT232ScrollView::OnClear()
{
    mList.RemoveAll();
    Scroll_Y=0;
    Invalidate();
}
//Свое сообщение из процесса ReadSerial сработало,обновим данные.
afx_msg LRESULT CFT232ScrollView::OnMess(WPARAM wParam, LPARAM lParam)
{
    data.Insert(2,' ');
    data.Insert(5,' ');
    data.Insert(6,' ');
    data.Insert(9,' ');
    data.Insert(12,' ');
    data.Insert(13,' ');
    data.Insert(16,' ');
    data.Insert(17,' ');

    data.Insert(20,' ');
    data.Insert(23,' ');
    data.Insert(26,' ');
    data.Insert(29,' ');
    data.Insert(32,' ');
    data.Insert(35,' ');
    data.Insert(38,' ');

    mList.AddTail(data);
    Invalidate();
    Scroll_Y+=16;
    return 0;
}

//Процесс чтения байтов из компорта
UINT ReadSerial(LPVOID pParam)
{
    //Событие
    CEvent event(FALSE, TRUE);
    //объявление асинхронной структуры
    OVERLAPPED overlapped;
    //чистим структуру
    ZeroMemory(&overlapped, sizeof(OVERLAPPED));
    //приладим событие
    overlapped.hEvent = event;
    //бесконечный цикл
    while(StartStopThread)
    {
        //асинхронное чтение порта
        if (!port.Read(buf, 13, overlapped))
        {    
            //сколько байт было принято
            DWORD dwBytesRead;
            //если нет передачи по компорту ждем минуту
            if (WaitForSingleObject(event, 10000) == WAIT_OBJECT_0)
            {
                //если всеже передача началась
                port.GetOverlappedResult(overlapped, dwBytesRead, FALSE);
                data="Data was read from the serial port";
                //Обновим окно
                ::PostMessage(HWND(pParam),MESS,0,0);
            }
            else
            {
                //передача за минуту не началась
                data="Нет данных ... попробуй еще раз !";
                //обновим окно
                ::PostMessage(HWND(pParam),MESS,0,0);
                //закрываем порт
                if(port.IsOpen())
                {
                    port.Close();
                }
                //останавливаем процесс
                return 1;
            }
        }
        //Преобразуем в строку полученные данные
        HexToASCII(buf,dest,13);
        //Скопируем в CString
        data=dest;
    }
    //Закрываем порт
    if(port.IsOpen())
    {
        port.Close();
    }
    // Terminate the thread
   ::AfxEndThread(0, FALSE);
    return 0;
}
char* HexToASCII(char* sour, char* dest, int len)
{
    int i;
    char tmp;
    int j=0;
    for(i=0;i<len;i++){
        tmp=((sour[i]>>4)&0x0f);
        if(tmp<=9){
            dest[j]=tmp+0x30;
        }
        else if(tmp>=0x0A && tmp<=0x0F){
            dest[j]=tmp+0x37;
        }
        j++;
        tmp=sour[i];
        tmp=tmp &= 0x0f;
        if(tmp<=9){
            dest[j]=tmp+0x30;
        }
        else if(tmp>=0x0A && tmp<=0x0F){
            dest[j]=tmp+0x37;
        }
        j++;
    }
    dest[j]=0;
    return dest;
}

void CFT232ScrollView::OnClose()
{
    StartStopThread=false;
    Sleep(1000);
    //Закрываем порт
    if(port.IsOpen())
    {
        port.Close();
    }

    CScrollView::OnClose();
}


void CFT232ScrollView::OnKillFocus(CWnd* pNewWnd)
{
    CScrollView::OnKillFocus(pNewWnd);
     HideCaret();
    // TODO: Add your message handler code here
}


void CFT232ScrollView::OnSetFocus(CWnd* pOldWnd)
{
    CScrollView::OnSetFocus(pOldWnd);
    ShowCaret();
    // TODO: Add your message handler code here
}


void CFT232ScrollView::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    x=point.x;
    y=point.y;
    data.Empty();
    Invalidate();
    CScrollView::OnLButtonDown(nFlags, point);
}


void CFT232ScrollView::OnFont()
{
    CFontDialog dlgFont;
    if (dlgFont.DoModal()==IDOK)
    {
        dlgFont.GetCurrentFont(&lp);
        cf.CreateFontIndirect(&lp);
    }
}


Back to Top