温度传感器室温监控仪

说明

这是一个课程设计内容,需要配合一个温度传感器进行使用,难点是串口的使用。

在本程序中,还需要懂得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;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值