본문 바로가기

Windows/MFC

CSerial

http://www.codeproject.com/system/serial.asp

GPL Licence 로 나름대로 사용하기도 좋고 나온지 오래되었으니 +_+ 꽤 실용성있고 제일 맘에 드는건 유니 코드를 제대로 지원해주시는 센스가 있어서 -_-;

1. CRichEditCtrl 을 Override하시는 클래스를 하나 생성해주시곤 CSerial* pSerial 하나 생성 WM_CHAR에 다음과 같은 소스를 추가
[code]
void CRichCommEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
    if (m_pSerial && m_pSerial->IsOpen())
    {
        char ch = static_cast<char>(nChar);
        m_pSerial->Write(&ch,1);                // command write
    }

    if (m_bEcho)
    {
        CRichEditCtrl::OnChar(nChar, nRepCnt, nFlags);
    }
}
[/code]
2. CSerialMFC m_serial 멤버 변수 할당, CRichEditCtrl Override한 클래스를 가지고 멤버 변수 할당.
3. Init 부분에 아래와 같은 코드 입력
[code]
    if (m_serial.Open(L"\\\\.\\COM20", this) != ERROR_SUCCESS)
    {
        AfxMessageBox(_T("Unable to open COM-port"),MB_ICONSTOP|MB_OK);
        GetParent()->PostMessage(WM_CLOSE);
        return 0;
    }

    // Setup the COM port
    if (m_serial.Setup(CSerial::EBaud115200,CSerial::EData8,CSerial::EParNone,CSerial::EStop1))
        return false;

    // Setup handshaking
    if (m_serial.SetupHandshaking(CSerial::EHandshakeHardware))
        return false;

    VERIFY(m_rich.Create(WS_VISIBLE|WS_CHILD|WS_BORDER|ES_AUTOHSCROLL|ES_AUTOVSCROLL|ES_LEFT|ES_MULTILINE,
        CRect(0,0,640,480),this,0));

    m_rich.m_pSerial = &m_serial;
[/code]
ex > COM포트가 4를 넘으면 가상으로다가 해야기 땜시로 \\\\.\\를 붙여주도록 해야합니다잉
    > 다이얼로그라 강제로 사이즈를 640, 480을 주었지만 실제적으로는 WM_SIZE에서 재조정해주면 됩니다요 물론 현재 윈도우 사이즈 가져와도 되고

4. 요거 PASTE 선언은 protected로 다가 해주면 되3
[code]
void CMySerialTestDlg::DisplayEvent (LPCTSTR lpszMsg)
{
    // Format the selection as red text
    CHARFORMAT cf;
    cf.cbSize = sizeof(cf);
    cf.dwMask = CFM_COLOR;
    m_rich.GetSelectionCharFormat(cf);
    cf.crTextColor = 0x000000FF;
    cf.dwEffects &= ~CFE_AUTOCOLOR;
    m_rich.SetSelectionCharFormat(cf);

    // Display the text
    TCHAR tszMsg[200];
    wsprintf(tszMsg,_T("[%s]"), lpszMsg);
    m_rich.SetSel(-1,-1);
    m_rich.ReplaceSel(tszMsg);
}

void CMySerialTestDlg::DisplayEventSetting (LPCTSTR lpszMsg, LPCTSTR lpszSetting, bool fOn)
{
    TCHAR tszMsg[200];
    wsprintf(tszMsg,_T("%s (%s=%s)"), lpszMsg, lpszSetting, (fOn?_T("on"):_T("off")));
    DisplayEvent(tszMsg);
}

void CMySerialTestDlg::DisplayData (LPCTSTR pszData)
{
    // Format the selection as default text
    CHARFORMAT cf;
    cf.cbSize = sizeof(cf);
    cf.dwMask = CFM_COLOR;
    m_rich.GetSelectionCharFormat(cf);
    cf.dwEffects |= CFE_AUTOCOLOR;
    m_rich.SetSelectionCharFormat(cf);

    // Add the event to the edit control
    m_rich.SetSel(-1,-1);
    m_rich.ReplaceSel(pszData);
}


LRESULT CMySerialTestDlg::OnSerialMsg (WPARAM wParam, LPARAM /*lParam*/)
{
    CSerial::EEvent eEvent = CSerial::EEvent(LOWORD(wParam));
    CSerial::EError eError = CSerial::EError(HIWORD(wParam));

    if (eError)
        DisplayEvent(_T("An internal error occurred."));

    if (eEvent & CSerial::EEventBreak)
        DisplayEvent(_T("Break detected on input."));

    if (eEvent & CSerial::EEventError)
        DisplayEvent(_T("A line-status error occurred."));

    if (eEvent & CSerial::EEventRcvEv)
        DisplayEvent(_T("Event character has been received."));

    if (eEvent & CSerial::EEventRing)
        DisplayEvent(_T("Ring detected"));

    if (eEvent & CSerial::EEventSend)
        DisplayEvent(_T("All data is send"));

    if (eEvent & CSerial::EEventCTS)
        DisplayEventSetting(_T("CTS signal change"), _T("CTS"), m_serial.GetCTS());

    if (eEvent & CSerial::EEventDSR)
        DisplayEventSetting(_T("DSR signal change"), _T("DSR"), m_serial.GetDSR());

    if (eEvent & CSerial::EEventRLSD)
        DisplayEventSetting(_T("RLSD signal change"), _T("RLSD"), m_serial.GetRLSD());

    if (eEvent & CSerial::EEventRecv)
    {
        // Create a clean buffer
        DWORD dwRead;
        char szData[101];
        const int nBuflen = sizeof(szData)-1;

        // Obtain the data from the serial port
        do
        {
            m_serial.Read(szData,nBuflen,&dwRead);
            szData[dwRead] = '\0';

            // Scan the string for unwanted characters
            for (DWORD dwChar=0; dwChar<dwRead; dwChar++)
            {
                if (!isprint(szData[dwChar]) && !isspace(szData[dwChar]))
                {
                    szData[dwChar] = '.';
                }
            }

#ifdef _UNICODE
            // Convert the ANSI data to Unicode
            LPTSTR lpszData = LPTSTR(_alloca((dwRead+1)*sizeof(TCHAR)));
            if (!::MultiByteToWideChar(CP_ACP, 0, szData, -1, lpszData, dwRead+1))
                return 0;

            // Display the fetched string
            DisplayData(lpszData);
#else
            // Display the fetched string
            DisplayData(szData);
#endif
        } while (dwRead == nBuflen);
    }

    return 0;
}[/code]

'Windows > MFC' 카테고리의 다른 글

CTimer  (0) 2013.10.02
CSerial  (0) 2013.10.02
CSplitterWnd - Multiple FormView  (0) 2013.10.02
VS BUG FIX  (0) 2013.10.02
CEdit Auto Create Scrollbar, 자동으로 Scrollbar 생성, GetLineCount ShowScrollBar  (0) 2013.10.02