首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC++ 單文檔架構 (SDI) 中整合 MSComm 串口控件的完整指南

     編輯:關於VC++

前言:MSComm 控件簡介

MSComm (Microsoft Communication Control) 是一個 ActiveX 控件,極大簡化了串口通訊程式開發。在對話方塊專案中加入它很直觀,但在單文檔介面 (SDI) 專案中,若視圖類別非 CFormView 派生,則需以動態建立方式處理。本文詳細說明在 CView 架構下整合 MSComm 的完整步驟與程式碼。

環境建置與控件註冊

  1. 專案 → 加入專案 → 元件與控件 → 已註冊的 ActiveX 控件
  2. 選擇 Microsoft Communication Control, version 6.0 插入專案
  3. 系統自動產生 mscomm.cpp、mscomm.h 並加入專案

核心實作步驟

1. 視圖類別宣告 (MscommDemoView.h)

protected:
    CMSComm m_Comm;                    // 控件物件
    afx_msg void OnComm();             // 事件處理函式
    DECLARE_EVENTSINK_MAP()            // 事件對應表宣告

2. 動態建立控件 (OnCreate 處理)

int CMscommDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct) {
    if (CView::OnCreate(lpCreateStruct) == -1) return -1;

    DWORD style = WS_VISIBLE | WS_CHILD;
    if (!m_Comm.Create(NULL, style, CRect(0,0,0,0), this, IDC_MSCOMM)) {
        TRACE0("Failed to create OLE Communication Controls!\n");
        return -1;
    }
    return 0;
}

關鍵點:IDC_MSCOMM 需在關於對話方塊中拖放 MSComm 控件後自動產生,確保 ID 一致性。

3. 串口初始化設定

void CMscommDemoView::InitPort() {
    m_Comm.SetCommPort(1);              // COM1
    m_Comm.SetInputMode(1);             // 文字模式
    m_Comm.SetSettings(_T("9600,n,8,1")); // 鮑率、無奇偶、8資料位、1停止位
    m_Comm.SetRThreshold(1);            // 接收 1 字元觸發事件
    m_Comm.SetInputLen(0);              // 讀取緩衝區所有資料

    if (!m_Comm.GetPortOpen()) {
        m_Comm.SetPortOpen(TRUE);
    } else {
        AfxMessageBox(_T("Open The Serial Port 1 Failure!"));
    }
    m_Comm.GetInput(); // 清空緩衝區

4. 事件對應表實作 (MscommDemoView.cpp)

BEGIN_EVENTSINK_MAP(CMscommDemoView, CView)
    ON_EVENT(CMscommDemoView, IDC_MSCOMM, 1, OnComm, VTS_NONE)
END_EVENTSINK_MAP()

5. 資料收發核心邏輯

接收資料 (事件驅動)

void CMscommDemoView::OnComm() {
    VARIANT m_input;
    char *str, *str1;
    int k, nEvent, i;
    CString str2, m_RcvData;

    nEvent = m_Comm.GetCommEvent();
    switch (nEvent) {
        case 2: // comEvReceive
            k = m_Comm.GetInBufferCount();
            if (k > 0) {
                m_input = m_Comm.GetInput();
                str = (char*)(unsigned char*)m_input.parray->pvData;
            }
            i = 0;
            str1 = str;
            while (i < k) { i++; str1++; }
            *str1 = '\0';
            str2 = (const char*)str;
            m_RcvData = (const char*)str;
            // 此處加入資料顯示/處理邏輯
            break;
    }
}

發送資料 (使用 CByteArray 解決 Unicode/ANSI 相容性)

void CMscommDemoView::SendData() {
    CString m_SendData = _T("Hello!");
    int Count = m_SendData.GetLength();
    CByteArray m_Array;

    m_Array.RemoveAll();
    m_Array.SetSize(Count);
    for (int i = 0; i < Count; i++)
        m_Array.SetAt(i, m_SendData[i]);

    m_Comm.SetOutput(COleVariant(m_Array));
}

關鍵技術點總結

  • 動態建立:非 CFormView 架構必須在 OnCreate 中 Create() 控件
  • 事件驅動:透過 ON_EVENT 宏對應 OnComm 事件,避免輪詢
  • 資料型別轉換:VARIANT 與 CByteArray 搭配,跨平台相容 (Win9x/NT)
  • 錯誤處理:開啟埠前檢查 GetPortOpen(),失敗給予提示

測試環境與建議

本程式在 Win2000 + VC6.0 下除錯通過。實際部署時建議:

  1. 將通訊參數 (鮑率、埠號) 設為可配置
  2. 加入逾時重傳與 CRC 校驗機制
  3. 使用獨立執行緒處理通訊,避免阻塞 UI
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved