MSComm (Microsoft Communication Control) 是一個 ActiveX 控件,極大簡化了串口通訊程式開發。在對話方塊專案中加入它很直觀,但在單文檔介面 (SDI) 專案中,若視圖類別非 CFormView 派生,則需以動態建立方式處理。本文詳細說明在 CView 架構下整合 MSComm 的完整步驟與程式碼。
mscomm.cpp、mscomm.h 並加入專案MscommDemoView.h)protected:
CMSComm m_Comm; // 控件物件
afx_msg void OnComm(); // 事件處理函式
DECLARE_EVENTSINK_MAP() // 事件對應表宣告
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 一致性。
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(); // 清空緩衝區
MscommDemoView.cpp)BEGIN_EVENTSINK_MAP(CMscommDemoView, CView)
ON_EVENT(CMscommDemoView, IDC_MSCOMM, 1, OnComm, VTS_NONE)
END_EVENTSINK_MAP()
接收資料 (事件驅動)
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 下除錯通過。實際部署時建議: