说明
这是一个课程设计内容,需要配合一个温度传感器进行使用,难点是串口的使用。
在本程序中,还需要懂得IEEE 754标准下的浮点数在计算机中的存储方式,否则无法将读取到的二进制数正确的转换为十进制数字。
步骤
Mysql的安装与使用
Codeblocks的安装与使用
codeblocks下使用mysql见我的这篇文章http://blog.csdn.net/celte/article/details/9908877
打开codeblocks后,文件——新建——项目——Win32 GUI Project——FrameBased——下一步——完成,即可编程。
注意
本程序中需要使用ini格式的配置文件,文件如下,还需要使用Mysql数据库,数据库中只需要建立temperature一张表,表中两个字段time(datetime),value(double)
config.ini
[DataBase]
IP=127.0.0.1
DB=sensor
User=root
Pass=1324354657
[Interval]
Time=3000
[GraphOnShow]
OnShow=false
[StartPoint]
Date=2013-09-17
Time=19:37:46
mark.ini
[2013-09-17-19:12:21]
Wrong=37.8
Right=37.9
代码
Function.h
/************************************************************/
/***这个头文件包含的都是此项目的一些处理函数,与界面无关***/
/************************************************************/
#ifndef FUNCTION_H_INCLUDED
#define FUNCTION_H_INCLUDED
#include <winsock.h>
#include <mysql.h> //包含MySQL所需要的头文件
#include <WinSock2.h> //Socket,连接MySQL也需要用的
HWND Hwnd_STATIC_StateInfo;
/**
**作用:从配置文件中读取出所有的Section名称
**参数:arrSection为返回的Section名称数组,filename为要打开的配置文件的路径
**返回值:为arrSection中Section的个数
**/
int GetSections(char arrSection[][100],char *filename)
{
int i=0,iPos=0,iMaxCount=0;
char chSectionNames[100000]= {'\0'};
char chSection[200]= {'\0'};
GetPrivateProfileSectionNames(chSectionNames,100000,filename);
for(i=0; i<100000; i++)
{
if(chSectionNames[i]==0)
if(chSectionNames[i]==chSectionNames[i+1])
break;
}
iMaxCount=i+1;
int iName=0;
if(chSectionNames[0]==0)
{
return 0;//说明元素为空
}
for(i=0; i<iMaxCount; i++)
{
chSection[iPos++]=chSectionNames[i];
if(chSectionNames[i]==0)
{
strcpy(arrSection[iName++],chSection);
memset(chSection,'\0',i);
iPos=0;
}
}
return iName;
}
/**
**作用:从任意一个Section下读取出配置的键值
**参数:section为该Section的名称,key为该Section下的键的名称,value为返回的该key下面的值
**/
void GetSectionValue(char *section,char *key,char *value)
{
GetPrivateProfileString(section,key,NULL,value,100,".//config.ini");
}
/**
**作用:从任意一个Section下修改键值
**参数:section为该Section的名称,key为该Section下的键的名称,value为需要设置的该key下面的值
**/
void SetSectionValue(char *section,char *key,char *value)
{
WritePrivateProfileString(section,key,value,".//config.ini");
}
char MarkSection[500][100];
int MarkSectionNum;
/**
**作用:添加一组传感器温度标定
**参数:wrong为输入的传感器的错误温度,right为输入的标定的正确温度
**/
void AddMarkSecion(char *wrong,char *right)
{
SYSTEMTIME sysTime;
GetLocalTime( &sysTime );
char nowTime[50];
sprintf(nowTime,"%4d-%02d-%02d-%02d:%02d:%02d",sysTime.wYear,sysTime.wMonth,sysTime.wDay,sysTime.wHour,sysTime.wMinute, sysTime.wSecond);
WritePrivateProfileString(nowTime,"Wrong",wrong,".//mark.ini");
WritePrivateProfileString(nowTime,"Right",right,".//mark.ini");
}
/**
**作用:删除指定的标记项
**参数:index为要删除的Section的序号
**返回值:返回1表示删除成功,返回0表示给出的index参数有问题
**/
int DeleteMarkSection(int index)
{
if(index<0)return 0;
char SectionNames[500][100];
int num=GetSections(SectionNames,".//mark.ini");
if(index>=num)return 0;
WritePrivateProfileString(SectionNames[index],NULL,NULL,".//mark.ini");
return 1;
}
/**
**作用:把标定的配置文件中的数据转化成字符串方便后面在ListBox中输出
**参数:StringValue是返回的字符串数据
**返回值:是StringValue中值的数量
**/
int GetMarkStringValue(char StringValue[][100])
{
int MarkSectionNum=GetSections(MarkSection,".//mark.ini");
int i;
int index=0;
for(i=0; i<500; i++)
memset(StringValue[i],'\0',100);
for(i=0; i<MarkSectionNum; i++)
{
char temp_wrong[20];
char temp_right[20];
GetPrivateProfileString(MarkSection[i],"Wrong",NULL,temp_wrong,20,".//mark.ini");
GetPrivateProfileString(MarkSection[i],"Right",NULL,temp_right,20,".//mark.ini");
sprintf(StringValue[index++],"传感器值:%s℃ 标定值:%s℃",temp_wrong,temp_right);
}
return MarkSectionNum;
}
/**
**作用:计算出温度标定配置文件中的数据的最终偏移量
**参数:value为返回值,为正确值与测定量之间的误差值
**说明:此函数在线程函数中调用
**解释:这个偏移量是按照所给的所有值的偏移量计算出平均的偏移量,作用于所有的值上面的
**/
void GetMarkNum(double *value)
{
char SectionNames[10000][100];
int num=GetSections(SectionNames,".//mark.ini");
double tol_wrong=0;
double tol_right=0;
int i=0;
for(i=0; i<num; i++)
{
char temp_wrong[20];
char temp_right[20];
GetPrivateProfileString(SectionNames[i],"Wrong",NULL,temp_wrong,20,".//mark.ini");
GetPrivateProfileString(SectionNames[i],"Right",NULL,temp_right,20,".//mark.ini");
tol_wrong+=atoi(temp_wrong);
tol_right+=atoi(temp_right);
}
if(num==0)
*value=0;
else
*value=(tol_right-tol_wrong)*1.0/num;
}
HANDLE hCom=INVALID_HANDLE_VALUE;//这个是打开串口后的串口句柄
/**
**作用:将读取到的温度二进制值转化成浮点数
**参数:byte为读取到的二进制字节,length为字节的长度,value为返回的浮点数
**返回值:返回1为正确,返回0为错误
**/
int ByteToDouble(char *byte,int length,double *value)
{
if(length!=5)return 0;//此时说明串口读取的值有问题
char ByteString[32];
memset(ByteString,0,32);
int i=0;
int index=0;
for(i=0; i<4; i++)
{
int target=byte[i];
ByteString[index++]=(target & 128)>>7;
ByteString[index++]=(target & 64)>>6;
ByteString[index++]=(target & 32)>>5;
ByteString[index++]=(target & 16)>>4;
ByteString[index++]=(target & 8)>>3;
ByteString[index++]=(target & 4)>>2;
ByteString[index++]=(target & 2)>>1;
ByteString[index++]=(target & 1);
}
for(i=0; i<32; i++)
{
printf("%d",ByteString[i]);
if((i+1)%8==0)printf("\n");
else
{
if((i+1)%4==0)printf(" ");
}
}
if(ByteString[0]==1)
ByteString[0]=0;//此时第一个字节就是原码了,可以直接转化
else//此时是负数
{
for(i=7; i>0; i--)
if(ByteString[i]==1)
break;
if(i<7)
ByteString[i]=0;
for(; i<8; i++)
ByteString[i]=1;
ByteString[7]=0;
for(i=1; i<8; i++)
{
if(ByteString[i]==1)
ByteString[i]=0;
else
ByteString[i]=1;
}
}
int power=0;//指数
for(i=1; i<8; i++) //求出指数
{
int j=0;
int temp=ByteString[i];
for(j=7-i; j>0; j--)
temp*=2;
power+=temp;
}
ByteString[8]=1;
*value=0;
for(i=8; i<8+power; i++) //计算整数部分
{
int j=0;
int temp=ByteString[i];
for(j=power+7-i; j>0; j--)
temp*=2;
*value+=temp;
}
for(i=8+power; i<32; i++) //计算小数部分
{
int j=0;
double temp=ByteString[i]*1.0;
for(j=i-7-power; j>0; j--)
temp*=0.5;
*value+=temp;
}
return 1;
}
/**
**作用:从注册表中读取出当前电脑的所有端口号
**参数:ports返回读取的所有的端口号;num返回读取到的端口个数
**返回值:返回0代表打开注册表失败,返回1代表读取注册表成功
**注意:经测试,若没有串口号,则打开注册表失败(此时不存在SERIALCOMM项,刚开机时)
**若插上后又拔下,就会存在这个SERIALCOMM
**/
int getPortName(char ports[][20],int *num)
{
HKEY hkey;
LONG lRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\DEVICEMAP\\SERIALCOMM",NULL,KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS|KEY_READ,&hkey);
if(lRes!=ERROR_SUCCESS)
{
*num=0;
return 0;
}
int portsIndex=0;
TCHAR tchKey[MAX_PATH];//读到的键的名称
TCHAR tchValue[20];//键的值
DWORD dwIndex = 0;// 读取名称的索引号,也即在注册表中的序号
DWORD dwType = REG_SZ;//键的值的类型
while(lRes == ERROR_SUCCESS)
{
DWORD dwCount = MAX_PATH;//读取到的键的名称的长度
DWORD dwVCount = 20;//键的值得长度
memset(tchValue,'\0',20);
lRes = RegEnumValue(hkey,dwIndex++,tchKey,&dwCount,NULL,&dwType,(LPBYTE)tchValue,&dwVCount);
if(lRes == ERROR_SUCCESS)
{
if((dwVCount > 0) && (dwCount > 0))
{
memset(ports[portsIndex],'\0',20);
int j=0;
for(j=strlen(tchValue)-1; j>-1; j--)
tchValue[j+4]=tchValue[j];
tchValue[0]='\\';
tchValue[1]='\\';
tchValue[2]='.';
tchValue[3]='\\';
strcpy(ports[portsIndex++],tchValue);
}
}
}
*num=portsIndex;
if(portsIndex)return 1;
return 0;
}
/**
**作用:在读写操作之前进行调用重置
**注释:仅仅使用在Inquery函数中
**/
void ResetBuff(HANDLE hCom)
{
//在读写串口之前,还要用PurgeComm()函数清空缓冲区:
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);//终止目前正在进行的读或写操作
//在调用ReadFile和WriteFile之前,线程应该调用ClearCommError函数清除错误标志。
COMSTAT ComStat;
DWORD dwError=0;
ClearCommError ( hCom , &dwError , &ComStat );
}
/**
**作用:用CreateFile函数连接上端口后,端口配置操作
**/
void ConfigPort()
{
//配置串口
DCB dcb;
GetCommState (hCom, &dcb);
dcb.BaudRate = CBR_57600; //波特率为9600
dcb.ByteSize = 8; //数据位为8
dcb.StopBits = ONESTOPBIT;//停止位为1
dcb.Parity = NOPARITY; //无校验
SetCommState (hCom, &dcb);
//指定程序接受特定串口事件
SetCommMask(hCom,EV_RXFLAG);
//设置I/O缓冲区
SetupComm(hCom, 1024, 1024);
//设置超时
COMMTIMEOUTS TimeOuts;
TimeOuts.ReadIntervalTimeout=1000; //读间隔超时
TimeOuts.ReadTotalTimeoutMultiplier=500; //读时间系数
TimeOuts.ReadTotalTimeoutConstant=5000; //读时间常量
TimeOuts.WriteTotalTimeoutMultiplier=500; //写时间系数
TimeOuts.WriteTotalTimeoutConstant=2000; //写时间常量
SetCommTimeouts(hCom,&TimeOuts);
}
/**
**作用:向端口发送指令,并读取其返回值
**参数:choice标识进行何种查询操作,1为握手协议查询是否连接成功,2为查询温度值
**参数:result为查询后根据byte字节计算出的浮点值
**注意:若是握手协议,则返回的是0x31的值,也即49;若是查询温度,则返回温度浮点值
**/
void Inquery(int choice,double *result)
{
memset(result,'\0',sizeof(result)/sizeof(char));
if(choice==1)//握手协议
{
ResetBuff(hCom);
char lpOutBuffer[4];
lpOutBuffer[0]=35;
lpOutBuffer[1]=0;
lpOutBuffer[2]=13;
lpOutBuffer[3]='\0';
DWORD dwBytesWrite=3;
WriteFile (hCom,lpOutBuffer,dwBytesWrite,&dwBytesWrite,NULL);
ResetBuff(hCom);
char str[20];
memset(str,'\0',20);
DWORD wCount;
ReadFile(hCom,str,20,&wCount,NULL);
if(wCount==1)
{
*result=(str[0]-'\0');
}
else
*result=0;
}
else//查询温度
{
ResetBuff(hCom);
char lpOutBuffer[4];
lpOutBuffer[0]=35;
lpOutBuffer[1]=5;
lpOutBuffer[2]=13;
lpOutBuffer[3]='\0';
DWORD dwBytesWrite=3;
WriteFile (hCom,lpOutBuffer,dwBytesWrite,&dwBytesWrite,NULL);
ResetBuff(hCom);
char str[20];
memset(str,'\0',20);
DWORD wCount;
ReadFile(hCom,str,20,&wCount,NULL);
ByteToDouble(str,wCount,result);
}
}
/**
**作用:根据注册表中的端口项,自动选择端口,然后打开端口
**返回值:返回0表示打开端口失败,打开1表示打开端口成功
**/
int ConnectSensor()
{
char ports[100][20];
int num=0;
if(!getPortName(ports,&num))
return 0;
int i=0;
hCom=INVALID_HANDLE_VALUE;
for(i=0; i<num; i++)
{
hCom=CreateFile(ports[i],GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
if(hCom==INVALID_HANDLE_VALUE)continue;
ConfigPort();
double result;
Inquery(1,&result);
if(result==49.0)
return 1;
hCom=INVALID_HANDLE_VALUE;
}
return 0;
}
/**
**作用:关闭串口连接
**/
void CloseSensor()
{
if(hCom!=INVALID_HANDLE_VALUE)
CloseHandle(hCom);
}
MYSQL mysql, *sock; //声明MySQL的句柄
MYSQL_RES * MySQLresult;
/**
**作用:连接数据库
**返回值:若返回1表示连接数据库成功,返回0表示连接数据库失败
**/
int ConnectDB()
{
char host[100];
GetSectionValue("DataBase","IP",host);
char user[100];
GetSectionValue("DataBase","User",user);
char passwd[100];
GetSectionValue("DataBase","Pass",passwd);
char db[100];
GetSectionValue("DataBase","DB",db);
unsigned int port = 3306; //这是MySQL的服务器的端口,如果你没有修改过的话就是3306。
const char * unix_socket = NULL; //unix_socket这是unix下的,我在Windows下,所以就把它设置为NULL
unsigned long client_flag = 0; //这个参数一般为0
mysql_init(&mysql); //连接之前必须使用这个函数来初始化
if ( (sock = mysql_real_connect(&mysql, host, user, passwd, db, port, unix_socket, client_flag) ) == NULL ) //连接MySQL
return 0;
else
return 1;
}
/**
**作用:关闭数据库连接
**/
void CloseDB()
{
if(sock!=NULL)
mysql_close(sock);
}
/**
**作用:把获取到的double温度值,转变成可用的sql语句,方便后面插入数据库
**参数:temperature是温度值,newPhrases是返回的sql语句字符串
**注意:进行温度值校正的步骤可以在此函数进行
**/
void getInsertPhrase(double temperature,char *newPhrase)
{
memset(newPhrase,'\0',sizeof(newPhrase)/sizeof(char));
SYSTEMTIME sysTime;
GetLocalTime( &sysTime );
sprintf(newPhrase,"insert into temperature (time,value) values ('%4d-%02d-%02d %02d:%02d:%02d',%.3lf)",
sysTime.wYear,sysTime.wMonth,sysTime.wDay,sysTime.wHour,sysTime.wMinute, sysTime.wSecond,temperature);
}
HANDLE monitorThread=INVALID_HANDLE_VALUE;
/**
**作用:线程核心函数,读取温度值,并写入数据库
**/
int index=0;
void ThreadFunc()
{
while(1)
{
double temperature;
Inquery(2,&temperature);
double Markvalue;
GetMarkNum(&Markvalue);
char value[20];
memset(value,'\0',20);
sprintf(value,"%.3lf℃",temperature+Markvalue);
SetWindowText(Hwnd_STATIC_StateInfo,value);
char sqlPhrase[200];
getInsertPhrase(temperature+Markvalue,sqlPhrase);
mysql_query(&mysql,sqlPhrase);//此函数若成功执行则返回0
char intervalStr[100];
GetSectionValue("Interval","Time",intervalStr);
Sleep(atoi(intervalStr));
}
}
/**
**作用:开始线程,获取温度值
**返回值:1表示开始线程,0表示线程已经存在,正在运行
**/
int StartThread()
{
if(monitorThread==INVALID_HANDLE_VALUE)
{
char date[20];
char time[20];
memset(date,'\0',20);
memset(time,'\0',20);
SYSTEMTIME sysTime;
GetLocalTime( &sysTime );
sprintf(date,"%4d-%02d-%02d",sysTime.wYear,sysTime.wMonth,sysTime.wDay);
sprintf(time,"%02d:%02d:%02d",sysTime.wHour,sysTime.wMinute, sysTime.wSecond);
WritePrivateProfileString("StartPoint","Date",date,".//config.ini");
WritePrivateProfileString("StartPoint","Time",time,".//config.ini");
monitorThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,NULL,0,NULL);
return 1;
}
return 0;
}
/**
**作用:终止线程,停止查询
**返回值:1表示结束线程,0表示线程已经结束
**/
int StopThread()
{
if(monitorThread!=INVALID_HANDLE_VALUE)
{
TerminateThread(monitorThread,NULL);
monitorThread=INVALID_HANDLE_VALUE;
SetWindowText(Hwnd_STATIC_StateInfo,"未开始!");
return 1;
}
return 0;
}
/**
**作用:将从数据库中读取出的温度(double,但是读取出来后成了string)
**参数:str为需要转换的字符串,也即读取到的数据
**返回值:读取到的温度值
**/
double StringToDouble(char *str)
{
int index=0;
int hasPoint=0;
int i=0;
for(i=0; i<strlen(str); i++)
{
index++;
if(str[i]=='.')
{
hasPoint=1;
break;
}
}
double result=0;
if(hasPoint==0)
{
for(i=0; i<strlen(str); i++)
{
if(str[i]=='-')continue;
if(i<index-1)
{
double temp=(str[i]-'0')*1.0;
int j;
for(j=0; j+i<index-1; j++)
temp=temp*10;
result+=temp;
}
}
}
else
{
for(i=0; i<strlen(str); i++)
{
if(str[i]=='-')continue;
if(str[i]=='.')continue;
if(i<index-1)
{
double temp=(str[i]-'0')*1.0;
int j;
for(j=0; j+i<index-2; j++)
temp=temp*10;
result+=temp;
}
else//小数
{
double temp=str[i]-'0';
int j=0;
for(j=0; j<(i+1-index); j++)
temp=temp*1.0/10;
result+=temp;
}
}
}
return result;
}
HDC helpDC;
HBITMAP helpDCBack;
/**
**作用:画坐标图
**参数:hwnd为需要话坐标图的窗体句柄
**/
void DrawGraph(HWND hwnd)
{
HDC hDC=GetWindowDC(hwnd);
helpDC=CreateCompatibleDC(0);//辅助画图设备
helpDCBack = CreateCompatibleBitmap(hDC,500,270);//创建画布
SelectObject(helpDC,helpDCBack);
RECT rcClient;
GetClientRect(hwnd,&rcClient);
HBRUSH brushTemp = (HBRUSH)GetStockObject(WHITE_BRUSH);//获得库存物体,白色画刷。
FillRect(helpDC,&rcClient,brushTemp);//填充客户区域。
HPEN hPen = CreatePen( PS_SOLID, 2, RGB(255,0,0) );
SelectObject( helpDC, hPen );
MoveToEx( helpDC, 30, 240, NULL );
LineTo( helpDC, 470, 240 );
MoveToEx( helpDC, 470, 240, NULL );
LineTo(helpDC,465,235);
MoveToEx( helpDC, 470, 240, NULL );
LineTo(helpDC,465,245);
MoveToEx( helpDC, 30, 240, NULL );
LineTo(helpDC,30,30);
MoveToEx( helpDC, 30, 30, NULL );
LineTo(helpDC,25,35);
MoveToEx( helpDC, 30, 30, NULL );
LineTo(helpDC,35,35);
TextOut(helpDC,20,226,"0",1);
TextOut(helpDC,35,25,"温度/℃",7);
TextOut(helpDC,472,225,"时间",4);
TextOut(helpDC,10,185,"10",2);
TextOut(helpDC,10,135,"20",2);
TextOut(helpDC,10,85,"30",2);
TextOut(helpDC,10,35,"40",2);
DeleteObject(brushTemp);
DeleteObject(hPen);
ReleaseDC(hwnd,hDC);
}
/**
**作用:画坐标图上的折线关系
**返回值:从数据库中select出来的项的数目
**/
void DrawLine(HWND hwnd,char *sqlPhrase)
{
mysql_query(&mysql, sqlPhrase);
MySQLresult = mysql_store_result(&mysql);
int count=0;
MYSQL_ROW row;
double largest=0;
double smallest=0;
double total=0;
while((row = mysql_fetch_row(MySQLresult)) != NULL)
{
double value=StringToDouble(row[1]);
count++;
if(largest<value)largest=value;
if(count==1)smallest=value;
if(smallest>value)smallest=value;
total+=value;
}
mysql_free_result(MySQLresult);
HDC hDC=GetWindowDC(hwnd);
HPEN hPen1 = CreatePen( PS_SOLID, 2, RGB(0,255,0) );
HPEN hPen2 = CreatePen( PS_DOT, 1, RGB(255,0,255) );
//int yStep=200/largest;//y坐标是从30到240,共210像素
int yStep=5;
int xStep=430/count;//x坐标是从30到470,共440像素
if(xStep==0)xStep=1;
if(yStep==0)yStep=1;
int index=0;
SetTextColor(helpDC,RGB(0,0,255));
SelectObject( helpDC, hPen2 );
int xMax=xStep*(count-1)+30;
MoveToEx( helpDC, 30,190, NULL );
LineTo(helpDC,xMax,190);
MoveToEx( helpDC, 30,140, NULL );
LineTo(helpDC,xMax,140);
MoveToEx( helpDC, 30,90, NULL );
LineTo(helpDC,xMax,90);
MoveToEx( helpDC, 30,40, NULL );
LineTo(helpDC,xMax,40);
LineTo(helpDC,xMax,240);
char stringValue[100];
memset(stringValue,'\0',100);
sprintf(stringValue,"平均温度:%.3lf℃ 最高温度:%.3lf℃ 最低温度:%.3lf℃",total/(1.0*count),largest,smallest);
TextOut(helpDC,30,5,stringValue,strlen(stringValue));
mysql_query(&mysql, sqlPhrase);
MySQLresult = mysql_store_result(&mysql);
SelectObject( helpDC, hPen1 );
char startTime[30];
char stopTime[30];
memset(startTime,'\0',30);
memset(stopTime,'\0',30);
while((row = mysql_fetch_row(MySQLresult)) != NULL)
{
index++;
if(index==1)
strcpy(startTime,row[0]);
if(index==count)
strcpy(stopTime,row[0]);
double value=StringToDouble(row[1]);
int nowX=xStep*(index-1)+30;
int nowY=240-(int)(yStep*value+0.5);
if(index==1)
{
MoveToEx(helpDC,nowX,nowY,NULL);
LineTo(helpDC,nowX,nowY+1);
LineTo(helpDC,nowX+1,nowY+1);
LineTo(helpDC,nowX+1,nowY);
MoveToEx(helpDC,nowX,nowY,NULL);
}
else
LineTo(helpDC,nowX,nowY);
}
TextOut(helpDC,5,245,startTime,19);
TextOut(helpDC,xMax-80,245,stopTime,19);
mysql_free_result(MySQLresult);
DeleteObject(hPen1);
DeleteObject(hPen2);
BitBlt(hDC,0,0,500,270,helpDC,0,0,SRCCOPY);
ReleaseDC(hwnd,hDC);
}
/**
**作用:判断一个字符串是否都是数字
**参数:numStr是待检测的字符串
**返回值:若都为数字,则返回1;若不是则返回0
**/
int isNumber(char *numStr)
{
int i=0;
for(i=0; i<strlen(numStr); i++)
if(numStr[i]<'0' || numStr[i]>'9')
return 0;
return 1;
}
/**
**作用:用来判断一个字符串是否是浮点数(可以是整数)
**参数:numStr是待检测的字符串
**返回值:返回1表示是浮点数,返回0表示不是
**/
int isDouble(char *numStr)
{
int i=0;
int count=0;
for(i=0; i<strlen(numStr); i++)
{
if(numStr[i]=='.')
count++;
}
if(count>1)return 0;
if(numStr[strlen(numStr)-1]=='.')return 0;
for(i=0; i<strlen(numStr); i++)
if(numStr[i]!='.')
if(numStr[i]<'0' || numStr[i]>'9')
return 0;
return 1;
}
/**
**作用:判断字符串中是否含有空格或者Tab符
**参数:str为输入的需要检查的字符串
**返回值:返回1这含有空格符等,返回0则没有
**/
int hasSpace(char *str)
{
int i=0;
for(i=0; i<strlen(str); i++)
if(str[i]==' ' || str[i]=='\t')
return 1;
return 0;
}
/**
**作用:判断是否是符合“2013-08-25”格式的日期
**参数:str为需要检验的字符串
**返回值:1为符合格式,0为不符合
**/
int isRightDate(char *str)
{
if(strlen(str)!=10)return 0;
int i;
for(i=0; i<10; i++)
{
if(i==4 || i==7)
{
if(str[i]!='-')return 0;
}
else
{
if(str[i]<'0' || str[i]>'9')return 0;
}
}
return 1;
}
/**
**作用:判断是否是符合“22:20:09”格式的时间
**参数:str为需要检验的字符串
**返回值:1为符合格式,0为不符合
**/
int isRightTime(char *str)
{
if(strlen(str)!=8)return 0;
int i;
for(i=0; i<8; i++)
{
if(i==2 || i==5)
{
if(str[i]!=':')return 0;
}
else
{
if(str[i]<'0' || str[i]>'9')return 0;
}
}
return 1;
}
#endif // FUNCTION_H_INCLUDED
Scene.h
/********************************************************/
/***这个头文件包含的都是与界面相关的声明以及函数定义***/
/********************************************************/
#ifndef SCENE_H_INCLUDED
#define SCENE_H_INCLUDED
#include "Function.h"
HWND hwnd;//系统主窗口句柄
//下面的HWND声明的都是窗体控件的句柄
#define ID_Common 10220
#define ID_Menu_Start 10221
#define ID_Menu_Set 10223
#define ID_Menu_Inquery 10225
#define ID_Menu_Mark 10226
HMENU hMenu=CreateMenu();
/**
**作用:创建菜单
**/
void InitialMenu()
{
AppendMenu(hMenu,MF_STRING,(UINT)ID_Menu_Start,"开始");
AppendMenu(hMenu,MF_STRING,(UINT)ID_Menu_Inquery,"查询");
AppendMenu(hMenu,MF_STRING,ID_Menu_Mark,"传感器标定");
AppendMenu(hMenu,MF_STRING,ID_Menu_Set,"参数设置");
SetMenu(hwnd,hMenu);
}
HWND Hwnd_STATIC_Title;
HWND Hwnd_STATIC_State;
//HWND Hwnd_STATIC_StateInfo;//把这个的创建放在Function.h里面,因为线程中要用
/**
**作用:创建主窗口界面
**/
void CreateMainWindow(HWND hwnd, LPARAM lParam)
{
Hwnd_STATIC_Title=CreateWindow(TEXT("STATIC"),TEXT("温度记录分析系统"),WS_CHILD | WS_VISIBLE,90,25,
400,40,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_State=CreateWindow(TEXT("STATIC"),TEXT("当前状态:"),WS_CHILD | WS_VISIBLE,130,140,
150,30,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_StateInfo=CreateWindow(TEXT("STATIC"),TEXT("未开始!"),WS_CHILD | WS_VISIBLE,290,140,
200,30,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
}
/**
**作用:控制主窗口界面的显示与隐藏
**/
void DisplayMainWindow(int nCmdShow)
{
ShowWindow(Hwnd_STATIC_Title,nCmdShow);
ShowWindow(Hwnd_STATIC_State,nCmdShow);
ShowWindow(Hwnd_STATIC_StateInfo,nCmdShow);
}
/**
**作用:设置界面的字体
**/
void SetWindowFont()
{
HFONT hFont;
hFont = CreateFont(40,15,0,0,FW_REGULAR,FALSE,FALSE,FALSE,GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH | FF_MODERN,"华文行楷");
SendMessage(Hwnd_STATIC_Title,WM_SETFONT,(WPARAM)hFont,MAKELPARAM(TRUE,0));
hFont = CreateFont(25,13,0,0,FW_REGULAR,FALSE,FALSE,FALSE,GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH | FF_MODERN,"华文彩云");
SendMessage(Hwnd_STATIC_State,WM_SETFONT,(WPARAM)hFont,MAKELPARAM(TRUE,0));
hFont = CreateFont(25,13,0,0,FW_REGULAR,FALSE,FALSE,FALSE,GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH | FF_MODERN,"华文新魏");
SendMessage(Hwnd_STATIC_StateInfo,WM_SETFONT,(WPARAM)hFont,MAKELPARAM(TRUE,0));
}
#define ID_BUTTON_Mark_Add 10227
#define ID_LISTBOX_Mark 10228
#define ID_BUTTON_Mark_Delete 10229
#define ID_BUTTON_Mark_Cancel 10230
HWND Hwnd_STATIC_Mark_Title;
HWND Hwnd_STATIC_Mark_Add;
HWND Hwnd_STATIC_Mark_Add_Wrong;
HWND Hwnd_STATIC_Mark_Add_Right;
HWND Hwnd_STATIC_Mark_Has;
HWND Hwnd_Edit_Mark_Add_Wrong;
HWND Hwnd_Edit_Mark_Add_Right;
HWND Hwnd_BUTTON_Mark_Add;
HWND Hwnd_BUTTON_Mark_Delete;
HWND Hwnd_BUTTON_Mark_Cancel;
HWND Hwnd_LISTBOX_Mark;
/**
**作用:创建传感器温度值标定界面
**/
void CreateMarkWindow(HWND hwnd, LPARAM lParam)
{
Hwnd_STATIC_Mark_Title=CreateWindow(TEXT("STATIC"),TEXT("传感器温度标定"),WS_CHILD,240,15,
120,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Mark_Add=CreateWindow(TEXT("STATIC"),TEXT("添加温度标定值:"),WS_CHILD,120,45,
120,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Mark_Add_Wrong=CreateWindow(TEXT("STATIC"),TEXT("传感器温度:"),WS_CHILD,150,75,
90,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Mark_Add_Right=CreateWindow(TEXT("STATIC"),TEXT("实 际 温 度:"),WS_CHILD,150,105,
90,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_Edit_Mark_Add_Wrong=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,250,75,
120,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_Edit_Mark_Add_Right=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,250,105,
120,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_BUTTON_Mark_Add=CreateWindow(TEXT("BUTTON"),TEXT("确定"),WS_CHILD|WS_TABSTOP,380,75,
70,50,hwnd,(HMENU)ID_BUTTON_Mark_Add,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Mark_Has=CreateWindow(TEXT("STATIC"),TEXT("已存在的标定值:"),WS_CHILD,120,135,
120,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_LISTBOX_Mark=CreateWindow(TEXT("LISTBOX"),NULL,WS_CHILD | WS_BORDER | WS_VSCROLL | LBS_NOTIFY ,150,165,
300,120,hwnd,(HMENU)ID_LISTBOX_Mark,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_BUTTON_Mark_Delete=CreateWindow(TEXT("BUTTON"),TEXT("删除"),WS_CHILD|WS_TABSTOP,320,290,
60,30,hwnd,(HMENU)ID_BUTTON_Mark_Delete,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_BUTTON_Mark_Cancel=CreateWindow(TEXT("BUTTON"),TEXT("返回"),WS_CHILD|WS_TABSTOP,390,290,
60,30,hwnd,(HMENU)ID_BUTTON_Mark_Cancel,((LPCREATESTRUCT) lParam)->hInstance,NULL);
EnableWindow(Hwnd_BUTTON_Mark_Delete,FALSE);
}
/**
**作用:控制传感器温度标定界面的显示与隐藏
**/
void DisplayMarkWindow(int nCmdShow)
{
ShowWindow(Hwnd_STATIC_Mark_Title,nCmdShow);
ShowWindow(Hwnd_STATIC_Mark_Add,nCmdShow);
ShowWindow(Hwnd_STATIC_Mark_Add_Wrong,nCmdShow);
ShowWindow(Hwnd_STATIC_Mark_Add_Right,nCmdShow);
ShowWindow(Hwnd_Edit_Mark_Add_Right,nCmdShow);
ShowWindow(Hwnd_Edit_Mark_Add_Wrong,nCmdShow);
ShowWindow(Hwnd_BUTTON_Mark_Add,nCmdShow);
ShowWindow(Hwnd_STATIC_Mark_Has,nCmdShow);
ShowWindow(Hwnd_LISTBOX_Mark,nCmdShow);
ShowWindow(Hwnd_BUTTON_Mark_Delete,nCmdShow);
ShowWindow(Hwnd_BUTTON_Mark_Cancel,nCmdShow);
SetWindowText(Hwnd_Edit_Mark_Add_Right,"");
SetWindowText(Hwnd_Edit_Mark_Add_Wrong,"");
SendMessage(Hwnd_LISTBOX_Mark,LB_RESETCONTENT ,0,NULL);
if(nCmdShow==SW_SHOW)
{
EnableWindow(Hwnd_BUTTON_Mark_Delete,FALSE);
char MarkValue[500][100];
int MarkValueNum;
MarkValueNum=GetMarkStringValue(MarkValue);
int i;
for(i=0;i<MarkValueNum;i++)
SendMessage(Hwnd_LISTBOX_Mark,LB_ADDSTRING ,0,(LPARAM)MarkValue[i]);
}
}
#define ID_BUTTON_Set_OK 10231
#define ID_BUTTON_Set_Cancel 10232
HWND Hwnd_BUTTON_Set_OK;
HWND Hwnd_BUTTON_Set_Cancel;
HWND Hwnd_STATIC_Set_Title;
HWND Hwnd_STATIC_Set_IP;
HWND Hwnd_STATIC_Set_User;
HWND Hwnd_STATIC_Set_Pass;
HWND Hwnd_STATIC_Set_DB;
HWND Hwnd_STATIC_Set_Interval;
HWND Hwnd_EDIT_Set_IP;
HWND Hwnd_EDIT_Set_User;
HWND Hwnd_EDIT_Set_Pass;
HWND Hwnd_EDIT_Set_DB;
HWND Hwnd_EDIT_Set_Interval;
/**
**作用:创建设置菜单界面的相关内容
**/
void CreateSetWindow(HWND hwnd, LPARAM lParam)
{
Hwnd_STATIC_Set_Title=CreateWindow(TEXT("STATIC"),TEXT("系统参数设置"),WS_CHILD,240,15,
90,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Set_IP=CreateWindow(TEXT("STATIC"),TEXT("数据库 IP地址:"),WS_CHILD,180,45,
110,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Set_DB=CreateWindow(TEXT("STATIC"),TEXT("数据库名 称:"),WS_CHILD,180,75,
110,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Set_User=CreateWindow(TEXT("STATIC"),TEXT("数据库用户名:"),WS_CHILD,180,105,
110,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Set_Pass=CreateWindow(TEXT("STATIC"),TEXT("数据库密 码:"),WS_CHILD,180,135,
110,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Set_Interval=CreateWindow(TEXT("STATIC"),TEXT("温度查询间隔:"),WS_CHILD,180,165,
110,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_EDIT_Set_IP=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,290,45,
90,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_EDIT_Set_DB=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,290,75,
90,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_EDIT_Set_User=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,290,105,
90,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_EDIT_Set_Pass=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,290,135,
90,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_EDIT_Set_Interval=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,290,165,
90,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_BUTTON_Set_OK=CreateWindow(TEXT("BUTTON"),TEXT("确定"),WS_CHILD|WS_TABSTOP,250,200,
60,30,hwnd,(HMENU)ID_BUTTON_Set_OK,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_BUTTON_Set_Cancel=CreateWindow(TEXT("BUTTON"),TEXT("返回"),WS_CHILD|WS_TABSTOP,320,200,
60,30,hwnd,(HMENU)ID_BUTTON_Set_Cancel,((LPCREATESTRUCT) lParam)->hInstance,NULL);
}
/**
**作用:控制设置界面的显示与隐藏
**/
void DisplaySetWindow(int nCmdShow)
{
ShowWindow(Hwnd_STATIC_Set_Title,nCmdShow);
ShowWindow(Hwnd_STATIC_Set_IP,nCmdShow);
ShowWindow(Hwnd_STATIC_Set_DB,nCmdShow);
ShowWindow(Hwnd_STATIC_Set_User,nCmdShow);
ShowWindow(Hwnd_STATIC_Set_Pass,nCmdShow);
ShowWindow(Hwnd_STATIC_Set_Interval,nCmdShow);
ShowWindow(Hwnd_EDIT_Set_IP,nCmdShow);
ShowWindow(Hwnd_EDIT_Set_DB,nCmdShow);
ShowWindow(Hwnd_EDIT_Set_User,nCmdShow);
ShowWindow(Hwnd_EDIT_Set_Pass,nCmdShow);
ShowWindow(Hwnd_EDIT_Set_Interval,nCmdShow);
ShowWindow(Hwnd_BUTTON_Set_OK,nCmdShow);
ShowWindow(Hwnd_BUTTON_Set_Cancel,nCmdShow);
if(nCmdShow==SW_SHOW)//若是显示,则把当前设置显示出来
{
char value[100];
GetSectionValue("DataBase","IP",value);
SetWindowText(Hwnd_EDIT_Set_IP,value);
GetSectionValue("DataBase","DB",value);
SetWindowText(Hwnd_EDIT_Set_DB,value);
GetSectionValue("DataBase","User",value);
SetWindowText(Hwnd_EDIT_Set_User,value);
GetSectionValue("DataBase","Pass",value);
SetWindowText(Hwnd_EDIT_Set_Pass,value);
GetSectionValue("Interval","Time",value);
SetWindowText(Hwnd_EDIT_Set_Interval,value);
}
}
HWND Hwnd_Graph_Title;
HWND Hwnd_Graph_Graph;
/**
**作用:创建温度走向图的窗体界面
**/
void CreateGraphWindow(HWND hwnd, LPARAM lParam)
{
Hwnd_Graph_Title=CreateWindow(TEXT("STATIC"),TEXT("温度走向图"),WS_CHILD,240,15,
160,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_Graph_Graph=CreateWindow(TEXT("STATIC"),TEXT(""),WS_CHILD | WS_BORDER,50,50,
500,270,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
}
/**
**作用:控制温度走向图界面的显示与隐藏
**/
void DisplayGraphWindow(int nCmdShow)
{
ShowWindow(Hwnd_Graph_Title,nCmdShow);
ShowWindow(Hwnd_Graph_Graph,nCmdShow);
if(nCmdShow==SW_SHOW)
{
DrawGraph(Hwnd_Graph_Graph);
WritePrivateProfileString("GraphOnShow","OnShow","true",".//config.ini");
}
else
{
DeleteObject(helpDCBack);
DeleteDC(helpDC);
WritePrivateProfileString("GraphOnShow","OnShow","false",".//config.ini");
}
}
#define ID_BUTTON_Inquery_OK 10233
#define ID_BUTTON_Inquery_Cancel 10234
HWND Hwnd_STATIC_Inquery_Title;
HWND Hwnd_STATIC_Inquery_StartTitle;
HWND Hwnd_STATIC_Inquery_StartDate;
HWND Hwnd_STATIC_Inquery_StartTime;
HWND Hwnd_STATIC_Inquery_StopTitle;
HWND Hwnd_STATIC_Inquery_StopDate;
HWND Hwnd_STATIC_Inquery_StopTime;
HWND Hwnd_EDIT_Inquery_StartDate;
HWND Hwnd_EDIT_Inquery_StartTime;
HWND Hwnd_EDIT_Inquery_StopDate;
HWND Hwnd_EDIT_Inquery_StopTime;
HWND Hwnd_BUTTON_Inquery_OK;
HWND Hwnd_BUTTON_Inquery_Cancel;
/**
**作用:创建温度查询输入时间段的界面
**/
void CreateInqueryWindow(HWND hwnd, LPARAM lParam)
{
Hwnd_STATIC_Inquery_Title=CreateWindow(TEXT("STATIC"),TEXT("温度走向图查询参数"),WS_CHILD,220,15,
160,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Inquery_StartTitle=CreateWindow(TEXT("STATIC"),TEXT("开始时间点:"),WS_CHILD,180,45,
90,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Inquery_StartDate=CreateWindow(TEXT("STATIC"),TEXT("日期:"),WS_CHILD,210,75,
50,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_EDIT_Inquery_StartDate=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,260,75,
120,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Inquery_StartTime=CreateWindow(TEXT("STATIC"),TEXT("时间:"),WS_CHILD,210,105,
50,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_EDIT_Inquery_StartTime=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,260,105,
120,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Inquery_StopTitle=CreateWindow(TEXT("STATIC"),TEXT("结束时间点:"),WS_CHILD,180,135,
90,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Inquery_StopDate=CreateWindow(TEXT("STATIC"),TEXT("日期:"),WS_CHILD,210,165,
50,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_EDIT_Inquery_StopDate=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,260,165,
120,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_STATIC_Inquery_StopTime=CreateWindow(TEXT("STATIC"),TEXT("时间:"),WS_CHILD,210,195,
50,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_EDIT_Inquery_StopTime=CreateWindow(TEXT("EDIT"),TEXT(""),WS_CHILD | WS_BORDER|WS_TABSTOP,260,195,
120,20,hwnd,(HMENU)ID_Common,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_BUTTON_Inquery_OK=CreateWindow(TEXT("BUTTON"),TEXT("确定"),WS_CHILD|WS_TABSTOP,250,225,
60,30,hwnd,(HMENU)ID_BUTTON_Inquery_OK,((LPCREATESTRUCT) lParam)->hInstance,NULL);
Hwnd_BUTTON_Inquery_Cancel=CreateWindow(TEXT("BUTTON"),TEXT("返回"),WS_CHILD|WS_TABSTOP,320,225,
60,30,hwnd,(HMENU)ID_BUTTON_Inquery_Cancel,((LPCREATESTRUCT) lParam)->hInstance,NULL);
}
/**
**作用:控制温度查询输入时间段界面的显示与隐藏
**/
void DisplayInqueryWindow(int nCmdShow)
{
ShowWindow(Hwnd_STATIC_Inquery_Title,nCmdShow);
ShowWindow(Hwnd_STATIC_Inquery_StartTitle,nCmdShow);
ShowWindow(Hwnd_STATIC_Inquery_StartDate,nCmdShow);
ShowWindow(Hwnd_EDIT_Inquery_StartDate,nCmdShow);
ShowWindow(Hwnd_STATIC_Inquery_StartTime,nCmdShow);
ShowWindow(Hwnd_EDIT_Inquery_StartTime,nCmdShow);
ShowWindow(Hwnd_STATIC_Inquery_StopTitle,nCmdShow);
ShowWindow(Hwnd_STATIC_Inquery_StopDate,nCmdShow);
ShowWindow(Hwnd_EDIT_Inquery_StopDate,nCmdShow);
ShowWindow(Hwnd_STATIC_Inquery_StopTime,nCmdShow);
ShowWindow(Hwnd_EDIT_Inquery_StopTime,nCmdShow);
ShowWindow(Hwnd_BUTTON_Inquery_Cancel,nCmdShow);
ShowWindow(Hwnd_BUTTON_Inquery_OK,nCmdShow);
SetWindowText(Hwnd_EDIT_Inquery_StartDate,"0000-00-00");
SetWindowText(Hwnd_EDIT_Inquery_StartTime,"00:00:00");
SetWindowText(Hwnd_EDIT_Inquery_StopDate,"9999-99-99");
SetWindowText(Hwnd_EDIT_Inquery_StopTime,"00:00:00");
}
#endif // SCENE_H_INCLUDED
main.cpp
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Scene.h"
//#include "Function.h"
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hThisInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow)
{
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
char szClassName[ ] = "CodeBlocksWindowsApp";
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"温度记录分析系统", /* Title Text */
WS_MINIMIZEBOX|WS_SYSMENU|WS_CAPTION|WS_OVERLAPPED, /* default window */
400, /* Windows decides the position */
200, /* where the window ends up on the screen */
600, /* The programs width */
400, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
InitialMenu();
/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
if(!IsDialogMessage(hwnd,&messages))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
else
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE://Create Window
{
CreateMainWindow(hwnd,lParam);
CreateMarkWindow(hwnd,lParam);
CreateSetWindow(hwnd,lParam);
CreateGraphWindow(hwnd,lParam);
CreateInqueryWindow(hwnd,lParam);
SetWindowFont();
break;
}
case WM_COMMAND://send command to the window during runtime
{
switch(LOWORD(wParam))
{
case ID_Menu_Start://click START menu
{
if(sock==NULL)//判断数据库是否连接上
{
if(!ConnectDB())
{
MessageBox(hwnd,"连接数据库失败!\n请检查参数是否有误!","错误!",MB_OK|MB_ICONERROR);
break;
}
}
if(hCom==INVALID_HANDLE_VALUE)
{
if(!ConnectSensor())
{
MessageBox(hwnd,"连接传感器失败!\n请检查连接后重试!","错误!",MB_OK|MB_ICONERROR);
break;
}
}
int choice=StartThread();
if(choice==1)
{
MessageBox(NULL,"开始读取环境温度~","提示",MB_OK|MB_ICONINFORMATION);
char value[10];
memset(value,'\0',10);
GetSectionValue("GraphOnShow","OnShow",value);
if(strcmp(value,"true")==0)
{
DisplayGraphWindow(SW_HIDE);
DisplayMainWindow(SW_SHOW);
}
}
if(choice==0)
MessageBox(NULL,"线程正在运行并读取环境温度~","提示",MB_OK|MB_ICONINFORMATION);
break;
}
case ID_Menu_Inquery://click QUERY menu
{
DisplayMainWindow(SW_HIDE);
DisplayMarkWindow(SW_HIDE);
DisplaySetWindow(SW_HIDE);
DisplayGraphWindow(SW_HIDE);
DisplayInqueryWindow(SW_SHOW);
break;
}
case ID_Menu_Mark://click MARK menu
{
DisplayMainWindow(SW_HIDE);
DisplayGraphWindow(SW_HIDE);
DisplaySetWindow(SW_HIDE);
DisplayInqueryWindow(SW_HIDE);
DisplayMarkWindow(SW_SHOW);
break;
}
case ID_Menu_Set://click SET menu
{
DisplayMainWindow(SW_HIDE);
DisplayGraphWindow(SW_HIDE);
DisplayMarkWindow(SW_HIDE);
DisplayInqueryWindow(SW_HIDE);
DisplaySetWindow(SW_SHOW);
break;
}
case ID_LISTBOX_Mark://cilck item of ListBox in MARK menu
{
EnableWindow(Hwnd_BUTTON_Mark_Delete,TRUE);
break;
}
case ID_BUTTON_Inquery_OK://cilck OK button in QUERY menu
{
char StartDate[20];
char StartTime[20];
char StopDate[20];
char StopTime[20];
memset(StartDate,'\0',20);
memset(StartTime,'\0',20);
memset(StopDate,'\0',20);
memset(StopTime,'\0',20);
GetWindowText(Hwnd_EDIT_Inquery_StartDate,StartDate,20);
GetWindowText(Hwnd_EDIT_Inquery_StartTime,StartTime,20);
GetWindowText(Hwnd_EDIT_Inquery_StopDate,StopDate,20);
GetWindowText(Hwnd_EDIT_Inquery_StopTime,StopTime,20);
if(!isRightDate(StartDate) || !isRightDate(StopDate))
{
MessageBox(hwnd,"请输入“2013-01-01”格式的日期","错误",MB_ICONERROR);
break;
}
if(!isRightTime(StartTime) || !isRightTime(StopTime))
{
MessageBox(hwnd,"请输入“00:00:00”格式的时间","错误",MB_ICONERROR);
break;
}
strcat(StartDate," ");
strcat(StartDate,StartTime);
strcat(StopDate," ");
strcat(StopDate,StopTime);
char sqlPhrase[500];
memset(sqlPhrase,'\0',500);
strcat(sqlPhrase,"select * from temperature where time>'");
strcat(sqlPhrase,StartDate);
strcat(sqlPhrase,"' and time<'");
strcat(sqlPhrase,StopDate);
strcat(sqlPhrase,"' order by time asc");
if(sock==NULL)//判断数据库是否连接上
{
if(!ConnectDB())
{
MessageBox(hwnd,"连接数据库失败!\n请检查参数是否有误!","错误!",MB_OK|MB_ICONERROR);
break;
}
}
if(mysql_query(&mysql, sqlPhrase)!=0)
{
MessageBox(hwnd,"查询失败!","错误",MB_ICONERROR);
break;
}
if((MySQLresult = mysql_store_result(&mysql))==NULL)
{
MessageBox(hwnd,"保存结果集失败!","错误",MB_ICONERROR);
break;
}
int count=0;
MYSQL_ROW row;
while((row = mysql_fetch_row(MySQLresult)) != NULL)
count++;
mysql_free_result(MySQLresult);
if(count==0)
{
MessageBox(hwnd,"该时间段内没有温度值","提示",MB_ICONINFORMATION);
break;
}
DisplayInqueryWindow(SW_HIDE);
DisplayGraphWindow(SW_SHOW);
//MessageBox(hwnd,"aaa","提示",MB_ICONINFORMATION);
DrawLine(Hwnd_Graph_Graph,sqlPhrase);
break;
}
case ID_BUTTON_Inquery_Cancel://cilck CANCEL button in QUERY menu
{
DisplayInqueryWindow(SW_HIDE);
DisplayMainWindow(SW_SHOW);
break;
}
case ID_BUTTON_Mark_Delete://cilck DELETE button in MARK menu
{
int index=SendMessage(Hwnd_LISTBOX_Mark, LB_GETCURSEL, 0, 0);
DeleteMarkSection(index);
SendMessage(Hwnd_LISTBOX_Mark,LB_DELETESTRING,index,NULL);
EnableWindow(Hwnd_BUTTON_Mark_Delete,FALSE);
break;
}
case ID_BUTTON_Mark_Cancel://click CANCEL button in MARK menu
{
DisplayMarkWindow(SW_HIDE);
DisplayMainWindow(SW_SHOW);
break;
}
case ID_BUTTON_Mark_Add://click ADD button in MARK menu
{
char wrong[50];
char right[50];
memset(wrong,'\0',50);
memset(right,'\0',50);
GetWindowText(Hwnd_Edit_Mark_Add_Wrong,wrong,50);
GetWindowText(Hwnd_Edit_Mark_Add_Right,right,50);
if(strlen(wrong)==0 || strlen(right)==0)
{
MessageBox(hwnd,"请不要留空任何一项","错误",MB_ICONERROR);
break;
}
if(!isDouble(wrong) || !isDouble(right))
{
MessageBox(hwnd,"只能输入整数或者浮点数!","错误",MB_ICONERROR);
break;
}
AddMarkSecion(wrong,right);
char result[100];
sprintf(result,"传感器值:%s℃ 标定值:%s℃",wrong,right);
SendMessage(Hwnd_LISTBOX_Mark,LB_ADDSTRING ,0,(LPARAM)result);
SetWindowText(Hwnd_Edit_Mark_Add_Right,"");
SetWindowText(Hwnd_Edit_Mark_Add_Wrong,"");
break;
}
case ID_BUTTON_Set_OK://click OK button in SET menu
{
int sure=0;
sure=MessageBox(hwnd,"确认修改参数?\n有些参数需要在重启程序后生效。","提示?",MB_YESNO|MB_ICONINFORMATION);
if(sure!=IDYES)break;
char IP[50];
char DB[50];
char User[50];
char Pass[50];
char Interval[50];
memset(IP,'\0',50);
memset(DB,'\0',50);
memset(User,'\0',50);
memset(Pass,'\0',50);
memset(Interval,'\0',50);
GetWindowText(Hwnd_EDIT_Set_IP,IP,50);
GetWindowText(Hwnd_EDIT_Set_DB,DB,50);
GetWindowText(Hwnd_EDIT_Set_User,User,50);
GetWindowText(Hwnd_EDIT_Set_Pass,Pass,50);
GetWindowText(Hwnd_EDIT_Set_Interval,Interval,50);
if(strlen(IP)==0 || strlen(DB)==0 || strlen(User)==0 || strlen(Pass)==0 || strlen(Interval)==0)
{
MessageBox(hwnd,"请不要留空任何一项","错误",MB_ICONERROR);
break;
}
if(hasSpace(IP) || hasSpace(DB) || hasSpace(User) || hasSpace(Pass) || hasSpace(Interval))
{
MessageBox(hwnd,"请不要输入空格符","错误",MB_ICONERROR);
break;
}
if(!isNumber(Interval))
{
MessageBox(hwnd,"温度查询间隔只能输入数字!","错误",MB_ICONERROR);
break;
}
SetSectionValue("DataBase","IP",IP);
SetSectionValue("DataBase","DB",DB);
SetSectionValue("DataBase","User",User);
SetSectionValue("DataBase","Pass",Pass);
SetSectionValue("Interval","Time",Interval);
DisplaySetWindow(SW_HIDE);
DisplayMainWindow(SW_SHOW);
break;
}
case ID_BUTTON_Set_Cancel://click CANCEL button in SET menu
{
DisplaySetWindow(SW_HIDE);
DisplayMainWindow(SW_SHOW);
break;
}
default:
break;
}
break;
}
case WM_CTLCOLORSTATIC://set color of static
{
if((HWND)lParam==Hwnd_STATIC_Title)
{
SetBkColor((HDC)wParam,RGB(255,255,255));
SetTextColor((HDC)wParam,RGB(0,200,0));
return (LRESULT)GetStockObject(NULL_BRUSH);
}
else if((HWND)lParam==Hwnd_STATIC_State)
{
SetBkColor((HDC)wParam,RGB(255,255,255));
SetTextColor((HDC)wParam,RGB(100,0,255));
return (LRESULT)GetStockObject(NULL_BRUSH);
}
else if((HWND)lParam==Hwnd_STATIC_StateInfo)
{
SetBkColor((HDC)wParam,RGB(255,255,255));
SetTextColor((HDC)wParam,RGB(200,0,0));
return (LRESULT)GetStockObject(NULL_BRUSH);
}
else
{
SetBkColor((HDC)wParam,RGB(255,255,255));
SetTextColor((HDC)wParam,RGB(0,0,0));
return (LRESULT)GetStockObject(NULL_BRUSH);
}
break;
}
case WM_CLOSE://on close window
{
int ok=0;
ok=MessageBox(hwnd,"是否确认退出?","退出?",MB_YESNO|MB_ICONINFORMATION);
if(ok==IDYES)
{
StopThread();
CloseDB();
CloseSensor();
DestroyWindow(hwnd);
}
return 0 ;
}
case WM_PAINT://paint the graph of temperature
{
PAINTSTRUCT ps;
HDC hdc;
hdc =BeginPaint (hwnd, &ps) ;
char value[10];
memset(value,'\0',10);
GetSectionValue("GraphOnShow","OnShow",value);
if(strcmp(value,"true")==0)
{
HDC hDC=GetWindowDC(Hwnd_Graph_Graph);
BitBlt(hDC,0,0,500,270,helpDC,0,0,SRCCOPY);
}
EndPaint(hwnd, &ps);
break;
}
case WM_KEYDOWN://Esc to stop read the temperature
{
switch(wParam)
{
case VK_ESCAPE:
{
int choice=StopThread();
if(choice==1)
{
MessageBox(NULL,"停止读取环境温度~\r\n下面将显示本时间段内的温度走向图","提示",MB_OK|MB_ICONINFORMATION);
char date[20];
char time[20];
char sqlPhrase[100];
memset(date,'\0',20);
memset(time,'\0',20);
memset(sqlPhrase,'\0',100);
GetPrivateProfileString("StartPoint","Date",NULL,date,20,".//config.ini");
GetPrivateProfileString("StartPoint","Time",NULL,time,20,".//config.ini");
WritePrivateProfileString("StartPoint",NULL,NULL,".//config.ini");
SYSTEMTIME sysTime;
GetLocalTime( &sysTime );
sprintf(sqlPhrase,"select * from temperature where time>'%s %s' and time<'%4d-%02d-%02d %02d:%02d:%02d' order by time asc",
date,time,sysTime.wYear,sysTime.wMonth,sysTime.wDay,sysTime.wHour,sysTime.wMinute, sysTime.wSecond);
DisplayMainWindow(SW_HIDE);
DisplayInqueryWindow(SW_HIDE);
DisplaySetWindow(SW_HIDE);
DisplayMarkWindow(SW_HIDE);
DisplayGraphWindow(SW_SHOW);
DrawLine(Hwnd_Graph_Graph,sqlPhrase);
}
if(choice==0)MessageBox(NULL,"线程已经停止运行,无需重复!","提示",MB_OK|MB_ICONINFORMATION);
break;
}
}
break;
}
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}