vc mscomm串口通信使用了CButtonST按钮类软件分析
使用了mscomm串口控件,
使用了CButtonST按钮类,
使用CDigitalClock类设置时间。
使用静态文本框实现了系统时间的显示控件,引入按钮文件BtnST.cpp,BtnST中使用了 BCMenu类。
对话框背景色及字体颜色设置,
在初始化实例中设置:
CDoorControlApp theApp; ///////////////////////////////////////////////////////////////////////////// // CDoorControlApp initialization BOOL CDoorControlApp::InitInstance() { AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif // SetDialogBkColor(RGB(245,250,190),RGB(0,0,250)); //设置对话框的背景色及字体颜色,前面为背景色,后面是字体颜色 CDoorControlDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; }
主对话框头文件中:
class CDoorControlDlg : public CDialog { // Construction public: char ConvertHexChar(char ch);//转换字符->十六进制 int String2Hex(CString str, CByteArray &senddata);//字符串->十六进制 void EableSetting(BOOL able); HICON m_hIcon_comoff;//关闭串口图标 HICON m_hIcon_comon;//打开串口图标 BOOL m_bcomonoff;//串口状态标志
整个程序文件:
使用了 BCMenu类,CDigitalClock类
图标是图片控件:
文本框控件:属性:
串口控件属性:
按钮控件,在主对话框初始化函数中,用到按钮类的对话框的头文件中要引入#include "BtnST.h"文件
//按钮的设置 m_btn_com.SubclassDlgItem(IDC_BTN_ONOFF,this); m_btn_com.SetIcon(IDI_ICON_COMOF);//图标 // m_btn_com.SetFlat(FALSE); m_btn_com.SetColor(CButtonST::BTNST_COLOR_BK_OUT, RGB(208,100,208)); //颜色 m_btn_com.SetColor(CButtonST::BTNST_COLOR_BK_FOCUS, RGB(208,208,208)); m_btn_com.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 10);
通过按钮类:CButtonST::,来设置按钮各种状态时候的背景颜色,
按钮控件要继承自 CButtonST
// CDoorControlDlg dialog #include "BtnST.h" #include "DigitalClock.h" #include "Management.h" class CDoorControlDlg : public CDialog { // Construction public: char ConvertHexChar(char ch);//转换字符->十六进制 int String2Hex(CString str, CByteArray &senddata);//字符串->十六进制 void EableSetting(BOOL able); HICON m_hIcon_comoff;//关闭串口图标 HICON m_hIcon_comon;//打开串口图标 BOOL m_bcomonoff;//串口状态标志 CDoorControlDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CDoorControlDlg) enum { IDD = IDD_DOORCONTROL_DIALOG }; CDigitalClock m_digital_clock; CButtonST m_btn_lookback; CButtonST m_btn_loadsys; CButtonST m_btn_manage;//手动添加变量定义 CStatic m_ctrlIconOpenoff; CButtonST m_btn_receclr; CButtonST m_btn_send;
添加了一个按钮,然后手动设置变量 CButtonST m_onbuton1;
按钮类的 头文件中引入了#include "BCMenu.h"文件。
// Uncomment the following 2 lines to enable support for BCMenu class #define BTNST_USE_BCMENU #include "BCMenu.h" // Uncomment the following line to enable support for sound effects #define BTNST_USE_SOUND #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000
对话框初始化函数中,添加按钮的设置函数:
m_onbutton1.SubclassDlgItem(IDC_BUTTON1,this); m_onbutton1.SetIcon(IDI_ICON_ADD); m_onbutton1.SetColor(CButtonST::BTNST_COLOR_BK_OUT, RGB(208,208,208)); m_onbutton1.SetColor(CButtonST::BTNST_COLOR_BK_FOCUS, RGB(208,208,208)); m_onbutton1.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 30);
实现效果:
完成按钮的设置使用。
打开串口按钮:
// TODO: Add extra initialization here SetTimer(1,10,NULL);//获取系统时间并显示到静态文本框 //打开串口按钮的设置 m_btn_com.SubclassDlgItem(IDC_BTN_ONOFF,this); m_btn_com.SetIcon(IDI_ICON_COMOF);//图标 // m_btn_com.SetFlat(FALSE); m_btn_com.SetColor(CButtonST::BTNST_COLOR_BK_OUT, RGB(208,100,208)); //颜色 m_btn_com.SetColor(CButtonST::BTNST_COLOR_BK_FOCUS, RGB(208,208,208)); m_btn_com.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 10); //串口状态图标
列表框的样式属性:
列表框添加了变量后:
void CManagement::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CManagement) // DDX_Control(pDX, IDC_BUN_DELET, m_btn_delet); DDX_Control(pDX, IDC_LIST, m_list); //}}AFX_DATA_MAP }
在对话框的初始化函数中设置列表框样式等,添加初始化数据:
// CManagement message handlers BOOL CManagement::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);//样式 m_list.SetBkColor(RGB(247,247,255));//控件背景色 m_list.SetTextColor(RGB(0,0,255));//文本色 m_list.SetTextBkColor(RGB(247,247,255));//文本的背景色 //列表框每列的标题,属性设置 m_list.InsertColumn(0, "卡号", LVCFMT_LEFT, 120);//第一列 m_list.InsertColumn(1, "姓名", LVCFMT_LEFT, 90);//第二列 m_list.InsertColumn(2, "权限", LVCFMT_LEFT, 180);//第三列 m_list.InsertColumn(3, "最近使用时间", LVCFMT_LEFT, 200);//第四列 //第一行 m_list.InsertItem(0,"15870295");//第一列 m_list.SetItemText(0,1,"小陈");//第二列 m_list.SetItemText(0,2,"1,2,3,4,5");//第三列 m_list.SetItemText(0,3,"2011,4,20 23:22:11");//第四列 //第二行 m_list.InsertItem(1,"02112126"); m_list.SetItemText(1,1,"小论"); m_list.SetItemText(1,2,"5,6,7"); m_list.SetItemText(1,3,"2011,4,21 13:02:18"); //第三行 m_list.InsertItem(2,"18112125"); m_list.SetItemText(2,1,"陈宏论"); m_list.SetItemText(2,2,"5,9"); m_list.SetItemText(2,3,"2011,4,21 21:22:00"); //第四行 m_list.InsertItem(3,"20888103"); m_list.SetItemText(3,1,"Google"); m_list.SetItemText(3,2,"1,2,9"); m_list.SetItemText(3,3,"2010,4,20 02:24:41");
主对话框控件的变量值,设置之后:
void CDoorControlDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDoorControlDlg) DDX_Control(pDX, IDC_STATIC_TIME, m_digital_clock); DDX_Control(pDX, IDC_STATIC_OPENOFF, m_ctrlIconOpenoff); DDX_Text(pDX, IDC_EDIT_RECEIVE, m_receive); DDX_Text(pDX, IDC_EDIT_SEND, m_send); DDX_Control(pDX, IDC_MSCOMM1, m_mscom); DDX_Check(pDX, IDC_CHECK_AUTOSEND, m_check_autoS); DDX_Check(pDX, IDC_CHECK_HEXS, m_check_hexS); DDX_Check(pDX, IDC_CHECK_HEXR, m_check_hexR); //}}AFX_DATA_MAP }
主对话框
// CDoorControlDlg dialog CDoorControlDlg::CDoorControlDlg(CWnd* pParent /*=NULL*/) : CDialog(CDoorControlDlg::IDD, pParent) { //{{AFX_DATA_INIT(CDoorControlDlg) m_receive = _T("");//接收的字符串 m_send = _T("");//发送的字符串 m_check_autoS = FALSE;//自动发送 m_check_hexS = FALSE;//十六进制发送 m_check_hexR = FALSE;//十六进展接收 //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_bcomonoff=FALSE;//串口状态标志位串口处于关闭状态 }
主对话框初始化函数中;
启动定时器,按钮图标和颜色设置,串口状态图标资源引入,设置主对话框显示的标题,
给组合框控件添加串口号,选择默认串口号。
// TODO: Add extra initialization here SetTimer(1,10,NULL); //按钮的设置 m_btn_com.SubclassDlgItem(IDC_BTN_ONOFF,this); m_btn_com.SetIcon(IDI_ICON_COMOF);//图标 // m_btn_com.SetFlat(FALSE); m_btn_com.SetColor(CButtonST::BTNST_COLOR_BK_OUT, RGB(208,100,208)); //颜色 m_btn_com.SetColor(CButtonST::BTNST_COLOR_BK_FOCUS, RGB(208,208,208)); m_btn_com.OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 10); //串口状态图标 m_hIcon_comon = AfxGetApp()->LoadIcon(IDI_ICON_COMLEDON); //串口指示灯打开状态图标的设置 m_hIcon_comoff = AfxGetApp()->LoadIcon(IDI_ICON_COMLEDOFF);//关闭状态图标 m_ctrlIconOpenoff.SetIcon(m_hIcon_comoff);//串口指示灯初始状态为关闭 //设置主对话框窗口标题 SetWindowText("电梯门禁系统上位机!"); //串口号选择的组合框设置 ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM1");//串口号选择复选框的设置 ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM2"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM3"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM4"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM5"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM6"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM7"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM8"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM9"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM10"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM11"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM12"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM13"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM14"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->AddString("COM15"); ((CComboBox *)GetDlgItem(IDC_COMBO1))->SetCurSel(0);//选择默认的COMM0口 UpdateData(FALSE); //更新屏幕显示 return TRUE; // return TRUE unless you set the focus to a control }
打开关闭串口按钮
//打开关闭串口按钮 void CDoorControlDlg::OnBtnOnoff() { /* m_mscom.SetCommPort(3); //串口1 m_mscom.SetInBufferSize(1024); //设置输入缓冲区的大小,Bytes m_mscom.SetOutBufferSize(512); //设置输入缓冲区的大小,Bytes if(!m_mscom.GetPortOpen()) //打开串口 { m_mscom.SetPortOpen(true); } m_mscom.SetInputMode(1); //设置输入方式为二进制方式 m_mscom.SetSettings("9600,n,8,1"); //设置波特率等参数 m_mscom.SetRThreshold(1); //为1表示有一个字符即引发事件 m_mscom.SetInputLen(0); */ // TODO: Add your control notification handler code here if(!m_bcomonoff) //第一次点击,打开串口 { if(m_mscom.GetPortOpen()) { AfxMessageBox("该端口已经被打开或者被占用!"); } int ComSel; ComSel=((CComboBox *)GetDlgItem(IDC_COMBO1))->GetCurSel();//串口号索引值 m_mscom.SetCommPort(ComSel+1); //选择串口号 m_mscom.SetInputMode(1);//设置输入方式为二进制方式 m_mscom.SetInBufferSize(1024);//设置输入缓冲区的大小,Bytes m_mscom.SetOutBufferSize(512);//设置输出缓冲区的大小,Bytes m_mscom.SetSettings("9600,n,8,1"); //设置波特率等参数 if(!m_mscom.GetPortOpen()) m_mscom.SetPortOpen(TRUE); else { AfxMessageBox("该端口已经被打开或者被占用!"); } m_mscom.SetRThreshold(1);//为1表示有一个字符即引发事件 m_mscom.SetInputLen(0); m_mscom.GetInput(); EableSetting(FALSE);//获取串口号的 组合框不可用 m_ctrlIconOpenoff.SetIcon(m_hIcon_comon);//设置串口打开图标 ((CButton *)GetDlgItem(IDC_BTN_ONOFF))->SetWindowText("关闭串口");//设置按钮控件文本内容 m_bcomonoff=TRUE;//串口打开标志位 } else if(m_bcomonoff) //第2次点击,关闭串口 { int ComSel; ComSel=((CComboBox *)GetDlgItem(IDC_COMBO1))->GetCurSel(); m_mscom.SetPortOpen(FALSE); EableSetting(TRUE);//获取串口号的 组合框可用 m_ctrlIconOpenoff.SetIcon(m_hIcon_comoff); ((CButton *)GetDlgItem(IDC_BTN_ONOFF))->SetWindowText("打开串口"); m_bcomonoff=FALSE; } }
串口组合框使能
//串口组合框使能 void CDoorControlDlg::EableSetting(BOOL able) { GetDlgItem(IDC_COMBO1)->EnableWindow(able); //串口组合框使能 UpdateData(FALSE); //更新屏幕显示 }
串口控件,接收触发函数:
BEGIN_EVENTSINK_MAP(CDoorControlDlg, CDialog) //{{AFX_EVENTSINK_MAP(CDoorControlDlg) ON_EVENT(CDoorControlDlg, IDC_MSCOMM1, 1 /* OnComm */, OnOnCommMscomm1, VTS_NONE) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP()
接收函数:
void CDoorControlDlg::OnOnCommMscomm1() { // TODO: Add your control notification handler code here UpdateData(true); VARIANT variant_inp; COleSafeArray safearray_inp; long i = 0; int len; char rxdata[1000]; CString tmp; switch (m_mscom.GetCommEvent()) { case 2://表示接收缓冲区内有字符 { variant_inp = m_mscom.GetInput(); safearray_inp = variant_inp; len = safearray_inp.GetOneDimSize(); for (i = 0; i < len; i++) { safearray_inp.GetElement(&i, &rxdata[i]);//转换为BYTE型数组 } for(i=0;i<len;i++) //将数组转换为Cstring型变量 { BYTE bt=*(char*)(rxdata+i); //字符型 if(m_check_hexR) { tmp.Format("%X ",bt); //将字符以十六进制方式送入临时变量strtemp存放,注意这里加入一个空隔 m_receive+=tmp; } else tmp.Format("%c",bt); //将字符送入临时变量strtemp存放 } rxdata[i] = '\0'; } if(!m_check_hexR) m_receive +=rxdata; UpdateData(false); break; default: break; } }
发送函数:
//发送数据到串口 void CDoorControlDlg::OnBtnSend() { // TODO: Add your control notification handler code here UpdateData(true); CByteArray sendArr; WORD wLength; CByteArray hexdata; wLength = m_send.GetLength(); sendArr.SetSize(wLength); for(int i =0; i<wLength; i++) { sendArr.SetAt(i, m_send.GetAt(i)); } if(m_check_hexS) { int len=String2Hex(m_send,hexdata); m_mscom.SetOutput(COleVariant(hexdata)); } else m_mscom.SetOutput(COleVariant(sendArr)); }
清除接收和发送文本框内容、
void CDoorControlDlg::OnBtnSendclr() { // TODO: Add your control notification handler code here m_send=""; UpdateData(false); } void CDoorControlDlg::OnBtnRececlr() { // TODO: Add your control notification handler code here m_receive=""; UpdateData(false); }
定时器函数: 系统时间获取显示,时间显示静态文本框的背景色设置,文本色设置
void CDoorControlDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default CTime time=CTime::GetCurrentTime();//获取时间 int nHour=time.GetHour(); int nMinute=time.GetMinute(); int nSecond=time.GetSecond(); //设置显示时间的静态文本框控件, m_digital_clock.SetBkColor(RGB(250,200,100)); //设置时间背景色 m_digital_clock.SetTextColor(RGB(0,0,255));//文本色 m_digital_clock.SetClock(nHour,nMinute,nSecond);//设置时钟 CDialog::OnTimer(nIDEvent); }
使用了 设置显示时间的类,来实现时间的显示:
void CDigitalClock::SetClock(int nHour, int nMinute, int nSecond) { m_nHour = nHour; m_nMinute = nMinute; m_nSecond = nSecond; DrawTimer(); }
字符串转换:
int CDoorControlDlg::String2Hex(CString str, CByteArray &senddata) { int hexdata,lowhexdata; int hexdatalen=0; int len=str.GetLength(); senddata.SetSize(len/2); for(int i=0;i<len;) { char lstr,hstr=str[i]; if(hstr==' ') { i++; continue; } i++; if(i>=len) break; lstr=str[i]; hexdata=ConvertHexChar(hstr); lowhexdata=ConvertHexChar(lstr); if((hexdata==16)||(lowhexdata==16)) break; else hexdata=hexdata*16+lowhexdata; i++; senddata[hexdatalen]=(char)hexdata; hexdatalen++; } senddata.SetSize(hexdatalen); return hexdatalen; }
十六进制:
char CDoorControlDlg::ConvertHexChar(char ch) { //这是一个将字符转换为相应的十六进制值的函数 //功能:若是在0-F之间的字符,则转换为相应的十六进制字符,否则返回-1 if((ch>='0')&&(ch<='9')) return ch-0x30; else if((ch>='A')&&(ch<='F')) return ch-'A'+10; else if((ch>='a')&&(ch<='f')) return ch-'a'+10; else return (-1); }
清除数据:
//清除发送 void CDoorControlDlg::OnBtnSendclr() { // TODO: Add your control notification handler code here m_send=""; UpdateData(false); } //清除接收 void CDoorControlDlg::OnBtnRececlr() { // TODO: Add your control notification handler code here m_receive=""; UpdateData(false); }
几个按钮的响应:
//管理人员信息 void CDoorControlDlg::OnBtnAdmin() { // TODO: Add your control notification handler code here CManagement dlg; dlg.DoModal(); } //启动系统 void CDoorControlDlg::OnBtnLoadsys() { // TODO: Add your control notification handler code here MessageBox("这部分还没加!"); } //查询历史记录 void CDoorControlDlg::OnBtnLookback() { // TODO: Add your control notification handler code here MessageBox("这部分还没加!"); }
单选框的实现:没有实现代码。
////十六进制接收 void CDoorControlDlg::OnCheckHexr() { // TODO: Add your control notification handler code here // UpdateData(TRUE); } //十六进制发送 void CDoorControlDlg::OnCheckHexs() { // TODO: Add your control notification handler code here // UpdateData(TRUE); } //1s自动发送 void CDoorControlDlg::OnCheckAutosend() { // TODO: Add your control notification handler code here // UpdateData(TRUE); }
发现自己的不足,善于利用找到的方法去扬长避短。行动起来。