只是为了记录自己研究生生涯编程过程中遇到的问题。
1.注意选用的控件适用平台是32位的还是64位的,否则两个控件适用平台不一致会很麻烦,下载控件时注意协调
2.将软件与硬件结合调试时硬件发送数据速度过快,加延时是非常必要的。
3.面对[X:“41.111”,Y:“51.112”,Z:“61.113”]这种格式的数据若想将X、Y、Z对应的数据分别提取出来显示在对应的编辑框内,
size_t a = txt.find_last_of(‘X’);
size_t b = txt.find_first_of(‘Y’);
string res1 = txt.substr(a + 3, b - 2 - a - 3);
此函数寻找的X,Y是最后位置的,所以若同时传递两组数据,则只识别第二组。
3.注意字符间的转换问题。
#include "stdafx.h"
#include "串口V1.h"
#include "串口V1Dlg.h"
#include "afxdialogex.h"
#include
#include
#include "mysql.h"
#include "vector"
MYSQL mysqlCon;//数据库结构
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
long len = 0;
vector<CString> x;
vector<CString> y;
vector<CString> z;
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
int num_iput = 1;
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
enum {
IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// C串口V1Dlg 对话框
C串口V1Dlg::C串口V1Dlg(CWnd* pParent /*=NULL*/)
: CDialogEx(C串口V1Dlg::IDD, pParent)
, m_EditReceive1(_T(""))
, m_EditReceive2(_T(""))
, m_EditReceive3(_T(""))
, m_EditSend(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void C串口V1Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_EditReceive1);
DDX_Text(pDX, IDC_EDIT2, m_EditReceive2);
DDX_Text(pDX, IDC_EDIT3, m_EditReceive3);
DDX_Text(pDX, IDC_EDIT4, m_EditSend);
DDX_Control(pDX, IDC_COMBO1, m_comb1);
DDX_Control(pDX, IDC_COMBO2, m_comb2);
DDX_Control(pDX, IDC_MSCOMM1, m_mscom);
DDX_Control(pDX, IDC_EDIT1, m_Edit1);
DDX_Control(pDX, IDC_EDIT2, m_Edit2);
DDX_Control(pDX, IDC_EDIT3, m_Edit3);
DDX_Control(pDX, IDC_TCHART1, m_chart);
}
BEGIN_MESSAGE_MAP(C串口V1Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_OPEN, &C串口V1Dlg::OnBnClickedButtonOpen)
ON_BN_CLICKED(IDC_BUTTON_SEND, &C串口V1Dlg::OnBnClickedButtonSend)
ON_BN_CLICKED(IDC_BUTTON_, &C串口V1Dlg::OnBnClickedButton)
ON_BN_CLICKED(IDC_BUTTON_CLOSE, &C串口V1Dlg::OnBnClickedButtonClose)
ON_BN_CLICKED(IDC_BUTTON_SAVE, &C串口V1Dlg::OnBnClickedButtonSave)
END_MESSAGE_MAP()
// C串口V1Dlg 消息处理程序
BOOL C串口V1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
// 串口选择组合框
CString str;
int i;
for (i = 0; i<15; i++)
{
str.Format(_T("com %d"), i + 1);
m_comb1.InsertString(i, str);
}
m_comb1.SetCurSel(0);//预置COM口
//波特率选择组合框
CString str1[] = {
_T("300"), _T("600"), _T("1200"), _T("2400"), _T("4800"), _T("9600"),
_T("19200"), _T("38400"), _T("43000"), _T("56000"), _T("57600"), _T("115200") };
for (int i = 0; i<12; i++)
{
int judge_tf = m_comb2.AddString(str1[i]);
if ((judge_tf == CB_ERR) || (judge_tf == CB_ERRSPACE))
MessageBox(_T("build baud error!"));
}
m_comb2.SetCurSel(5);//预置波特率为"9600"
CAxes m_Axis = m_chart.get_Axis(); //获取坐标轴
CAxis m_left = m_Axis.get_Left(); //获取纵轴
CAxis m_bottom = m_Axis.get_Bottom(); //获取横轴
m_left.put_Automatic(FALSE); //设置不自动适应
m_left.put_Minimum(0); //设置纵轴起始值
m_left.put_Maximum(100); //设置纵轴结束值
m_left.put_Increment(0.1); //设置增量
m_left.put_StartPosition(0); //设置起始位置%
m_left.put_EndPosition(100); //设置结束位置%
CAxisTitle m_AxisLeftTitle = m_left.get_Title();//得到纵轴标题
m_AxisLeftTitle.put_Caption(_T("Y"));//设置纵轴标题
CAxisTitle m_AxisBottomTitle = m_bottom.get_Title();//得到横轴标题
m_AxisBottomTitle.put_Caption(_T("X"));//设置横轴标题
CChartFont m_LeftTitleFont = m_AxisLeftTitle.get_Font();//得到坐标轴字体样式大小
m_LeftTitleFont.put_Size(14);
m_LeftTitleFont.put_Bold(TRUE);
CChartFont m_BottomTitleFont = m_AxisBottomTitle.get_Font();//得到坐标轴样式
m_BottomTitleFont.put_Size(14);
m_BottomTitleFont.put_Bold(TRUE);
m_bottom.put_Automatic(FALSE); //设置不自动适应
m_bottom.put_Minimum(0); //设置横轴起始值
m_bottom.put_Maximum(100); //设置横轴结束值
m_bottom.put_Increment(1); //设置增量
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void C串口V1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void C串口V1Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR C串口V1Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void C串口V1Dlg::OnBnClickedButtonOpen() //打开串口按钮程序
{
// TODO: 在此添加控件通知处理程序代码
CString str, str1, n; //定义字符串
GetDlgItemText(IDC_BUTTON_OPEN, str);
CWnd *h1;
h1 = GetDlgItem(IDC_BUTTON_OPEN); //指向控件的caption
if (!m_mscom.get_PortOpen())
{
m_comb2.GetLBText(m_comb2.GetCurSel(), str1);//取得所选的字符串,并存放在str1里面
str1 = str1 + ',' + 'n' + ',' + '8' + ',' + '1'; //这句话很关键
m_mscom.put_CommPort((m_comb1.GetCurSel() + 1)); //选择串口
m_mscom.put_InputMode(1); //设置输入方式为二进制方式
m_mscom.put_Settings(str1); //波特率为(波特率组Á合框)无校验,8数据位,1个停止位
m_mscom.put_InputLen(1024); //设置当前接收区数据长度为1024
m_mscom.put_RThreshold(1); //缓冲区一个字符引发事件
m_mscom.put_RTSEnable(1); //设置RT允许
m_mscom.put_PortOpen(true); //打开串口
if (m_mscom.get_PortOpen())
{
str = _T("关闭串口");
UpdateData(true);
h1->SetWindowText(str); //改变按钮名称为‘’关闭串口”
}
}
else
{
m_mscom.put_PortOpen(false);
if (str != _T("打开串口"))
{
str = _T("打开串口");
UpdateData(true);
h1->SetWindowText(str); //改变按钮名称为打开串口
}
}
}
void C串口V1Dlg::OnBnClickedButtonSend() //发送数据按钮程序
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(true); //更新控件数据
m_mscom.put_Output(COleVariant(m_EditSend));//把发送编辑框的数据发送出去
}
void C串口V1Dlg::OnBnClickedButton() //清除数据按钮程序
{
// TODO: 在此添加控件通知处理程序代码
m_EditReceive1 = _T(""); //给接收编辑框发送空格符
m_EditReceive2 = _T("");
m_EditReceive3 = _T("");
UpdateData(false); //更新数据
}
void C串口V1Dlg::OnBnClickedButtonClose() //退出按钮程序
{
// TODO: 在此添加控件通知处理程序代码
if (m_mscom.get_PortOpen())
m_mscom.put_PortOpen(false);
CDialogEx::OnCancel();
}
BEGIN_EVENTSINK_MAP(C串口V1Dlg, CDialogEx)
ON_EVENT(C串口V1Dlg, IDC_MSCOMM1, 1, C串口V1Dlg::OnCommMscomm1, VTS_NONE)
END_EVENTSINK_MAP()
void C串口V1Dlg::OnCommMscomm1() //串口控件程序
{
// TODO: 在此处添加消息处理程序代码
CSeries lineSeries0 = (CSeries)m_chart.Series(0);
CSeries lineSeries1 = (CSeries)m_chart.Series(1);
CSeries lineSeries2 = (CSeries)m_chart.Series(2);
if (m_mscom.get_CommEvent() == 2)
{
char str[1024] = {
0 };
long len1, k;
VARIANT InputData = m_mscom.get_Input(); //读缓冲区
COleSafeArray fs;
fs = InputData; //VARIANT型变À量转换为COleSafeArray型变量
len1 = fs.GetOneDimSize();
len += len1 - 16;
for (k = 0; k < fs.GetOneDimSize(); k++)
fs.GetElement(&k, str + k); //转换为BYTE型数组
string txt = str ;
size_t a = txt.find_last_of('X');
size_t b = txt.find_first_of('Y');
string res1 = txt.substr(a + 3, b - 2 - a - 3);
size_t c = txt.find_last_of('Y');
size_t d = txt.find_first_of('Z');
string res2 = txt.substr(c + 3, d - 2 - c - 3);
size_t e = txt.find_last_of('Z');
size_t f = txt.find_first_of(']');
string res3 = txt.substr(e + 3, f - 2 - e - 2);
CString res1_C, res2_C, res3_C;
res1_C = res1.c_str();
res2_C = res2.c_str();
res3_C = res3.c_str();
m_EditReceive1 += res1_C; // 接收到编辑框里面
m_EditReceive2 += res2_C;
m_EditReceive3 += res3_C;
x.push_back(res1_C);
y.push_back(res2_C);
z.push_back(res3_C);
if (len > 1024)
{
m_EditReceive1 = _T(""); //给接收编辑框发送空格符
m_EditReceive2 = _T("");
m_EditReceive3 = _T("");
UpdateData(false);
len = 0;
}
m_EditReceive1 += "\r\n"; // 接收到编辑框里面进行换行
m_EditReceive2 += "\r\n";
m_EditReceive3 += "\r\n";
//SetTimer(1,10,NULL); //延时10ms
UpdateData(false);
//m_Edit1.SetSel(-1, -1);
//this->SetDlgItemTextW(IDC_EDIT1, m_EditReceive1);//将m_EditReceive内容显示到ID为IDC_EDIT1的编辑框的最后位置
//m_Edit1.LineScroll(m_Edit1.GetLineCount() - 1, 0);//将垂直滚动条滚动到最后一
//m_Edit2.SetSel(-1, -1);
//this->SetDlgItemTextW(IDC_EDIT2, m_EditReceive2);//将m_EditReceive内容显示到ID为IDC_EDIT1的编辑框的最后位置
//m_Edit2.LineScroll(m_Edit2.GetLineCount() - 1, 0);//将垂直滚动条滚动到最后一
//m_Edit3.SetSel(-1, -1);
//this->SetDlgItemTextW(IDC_EDIT3, m_EditReceive3);//将m_EditReceive内容显示到ID为IDC_EDIT1的编辑框的最后位置
//m_Edit3.LineScroll(m_Edit3.GetLineCount() - 1, 0);//将垂直滚动条滚动到最后一
double dispaly_tmp = strtod(str, NULL);
//double m = _ttof(dispaly_tmp);
double dispaly_tmp1 = _ttof(res1_C);
lineSeries0.AddXY((double)num_iput, dispaly_tmp1, NULL, 0);
double dispaly_tmp2 = _ttof(res2_C);
lineSeries1.AddXY((double)num_iput, dispaly_tmp2, NULL, 0);
double dispaly_tmp3 = _ttof(res3_C);
lineSeries2.AddXY((double)num_iput, dispaly_tmp3, NULL, 0);
num_iput++;
if (num_iput > 100)
{
lineSeries0.Clear();
lineSeries1.Clear();
lineSeries2.Clear();
num_iput = 1;
}
}
}
void C串口V1Dlg::OnBnClickedButtonSave()
{
// TODO: 在此添加控件通知处理程序代码
// UpdateDate(TRUE);
for (int i = 0; i < x.size(); i++)
{
CString local_X = x[i].GetBuffer();
CString local_Y = y[i].GetBuffer();
CString local_Z = z[i].GetBuffer();
// 创建 MYSQL 对象。
MYSQL local_mysql;
// 初始化 MYSQL 对象。
mysql_init(&local_mysql);
// 连接数据库
if (!mysql_real_connect(&local_mysql, "localhost", "root", "123456", "test", 3306, NULL, 0))
{
AfxMessageBox(_T("connect to database failed!"));
}
else
{
//AfxMessageBox(_T("connect to database success!"));
// 设置字符集, 使程序支持中文。
mysql_query(&local_mysql, "set names 'gb2312'");
}
// 创建 SQL 语句字符串
CString sql_insert;
//sql_insert.Format(_T("insert into test.emp_test(X, Y, Z) values (2, 2, 3)"))/* local_X, local_Y, local_Z*/;
// 执行 sql 语句。
// mysql_query() 的返回值份很多情形, 进行判断使要注意。
char insert[1024];
sprintf_s(insert, "insert into test.emp_test(X, Y, Z) values (\'%s\', \'%s\', \'%s\')", local_X, local_Y, local_Z);
if (mysql_query(&local_mysql, insert) == 0)
{
//AfxMessageBox(_T("insert succeed!"));
}
else{
AfxMessageBox(_T("insert failed!"));
}
}
// 关闭 local_mysql 所关联的数据库连接, 一般情况下不用写。
//mysql_close(&local_mysql);
UpdateData(FALSE);
}