工作总结
[user]
ID=fml
[oracle]
UserID=bstsadmin
DataSource=192.168.10.143/BSDB
PassWord=100F0402081D1D1F
[sqlite]
Address=SwBSLocal.db
[mapInfo]
Path=E:\\项目\\深圳\\深圳市.gst
Longitude=113.935715
Latitude=22.548965
Zoom=2.052
[gps]
ComNum=COM3
Time=3
.cpp
CConfig::CConfig(void)
{
	m_pPath = ".\\config.ini";
	Init();
}
CConfig::~CConfig(void)
{
}
int CConfig::m_nDBType = 0;
bool CConfig::Init()
{
	if (NULL == m_pPath)
	{
		return FALSE;
	}
CXCode code;
char TempBuff[255] = "";
	bool bRes = FALSE;
	char* pApp = "user";
	GetPrivateProfileString(pApp, "ID", "", TempBuff, sizeof(TempBuff), m_pPath);
	m_strUserID = TempBuff;
	pApp = "oracle";
	GetPrivateProfileString(pApp, "UserID", "", TempBuff, sizeof(TempBuff), m_pPath);
	m_strOraUserID = TempBuff;
	GetPrivateProfileString(pApp, "DataSource", "", TempBuff, sizeof(TempBuff), m_pPath);
	m_strOraDataSource = TempBuff;
	GetPrivateProfileString(pApp, "PassWord", "", TempBuff, sizeof(TempBuff), m_pPath);
	code.Decode(TempBuff, m_strOraUserID, m_strOraPassWord);
	pApp = "sqlite";
	GetPrivateProfileString(pApp, "Address", "", TempBuff, sizeof(TempBuff), m_pPath);
	m_strSqliteAddress = TempBuff;
	pApp = "mapInfo";
	GetPrivateProfileString(pApp, "Path", "", TempBuff, sizeof(TempBuff), m_pPath);
	m_strMapPath = TempBuff;
	pApp = "mapInfo";
	GetPrivateProfileString(pApp, "Longitude", "", TempBuff, sizeof(TempBuff), m_pPath);
	m_strLongitude = TempBuff;
	
	pApp = "mapInfo";
	GetPrivateProfileString(pApp, "Latitude", "", TempBuff, sizeof(TempBuff), m_pPath);
	m_strLatitude = TempBuff;
	pApp = "mapInfo";
	GetPrivateProfileString(pApp, "Zoom", "", TempBuff, sizeof(TempBuff), m_pPath);
	m_strZoom = TempBuff;
	pApp = "gps";
	GetPrivateProfileString(pApp, "ComNum", "", TempBuff, sizeof(TempBuff), m_pPath);
	m_strComNum = TempBuff;
	pApp = "gps";
	GetPrivateProfileString(pApp, "Time", "", TempBuff, sizeof(TempBuff), m_pPath);
	m_strTime = TempBuff;
	return TRUE;
}
bool CConfig::WirteLastUserID(CString strID)
{
	if (NULL == m_pPath)
	{
		return FALSE;
	}
char* pApp = "user";
	char* pUserID = strID.GetBuffer();
	BOOL bRes = WritePrivateProfileString(pApp, "ID", pUserID, m_pPath);
	strID.ReleaseBuffer();
	return bRes;
}
bool CConfig::WirteLastUserID(char *pNode,char *pSecondNode,char *pValue)
{
	if (NULL == m_pPath)
	{
		return FALSE;
	}
	if (pNode==NULL||pSecondNode==NULL)
	{
		return FALSE;
	}
	BOOL bRes = WritePrivateProfileString(pNode, pSecondNode, pValue, m_pPath);
	return bRes;
}
.h
class CConfig
{
public:
	CConfig(void);
	~CConfig(void);
private:
	bool Init();
public:
	bool WirteLastUserID(CString strID);
	bool WirteLastUserID(char *pNode,char *pSecondNode,char *pValue);//by lsn
public:
	CString m_strUserID;
	CString m_strOraUserID;
	CString m_strOraDataSource;
	CString m_strOraPassWord;
	CString m_strSqliteAddress;
	CString m_strMapPath;
	CString m_strComNum;
	CString m_strTime;
	CString m_strLongitude;
	CString m_strLatitude;
	CString m_strZoom;
public:
	static int m_nDBType;  //0-远端,1-本地
private:
	const char* m_pPath;
};
#include "stdafx.h"
#include "Wire.h"
#include "WireDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CWireDoc
IMPLEMENT_DYNCREATE(CWireDoc, CDocument)
BEGIN_MESSAGE_MAP(CWireDoc, CDocument)
END_MESSAGE_MAP()
// CWireDoc construction/destruction
CWireDoc::CWireDoc()
{
	// TODO: add one-time construction code here
	m_bConnected=FALSE;//断开连接
	m_nBaud = 9600;
	m_nDataBits = 8;
	m_nParity = 0;
	m_sPort = m_config.m_strComNum;
	m_nStopBits = 0;
	m_nTime=atoi(m_config.m_strTime.GetBuffer());
}
CWireDoc::~CWireDoc()
{
	//程序结束时删除线程、关闭串口的操作
	if(m_bConnected)
		CloseConnection();
	// 删除事件句柄
	if(m_hPostMsgEvent)
		CloseHandle(m_hPostMsgEvent);
	if(m_osRead.hEvent)
		CloseHandle(m_osRead.hEvent);
	if(m_osWrite.hEvent)
		CloseHandle(m_osWrite.hEvent);
}
BOOL CWireDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;
	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
	// 为WM_COMMNOTIFY消息创建事件对象,手工重置,初始化为有信号的
	if((m_hPostMsgEvent=CreateEvent(NULL, TRUE, TRUE, NULL))==NULL)
		return FALSE;
	memset(&m_osRead, 0, sizeof(OVERLAPPED));
	memset(&m_osWrite, 0, sizeof(OVERLAPPED));
	// 为重叠读创建事件对象,手工重置,初始化为无信号的
	if((m_osRead.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL)
		return FALSE;
	// 为重叠写创建事件对象,手工重置,初始化为无信号的
	if((m_osWrite.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL)
		return FALSE;
	OpenConnection();
	return TRUE;
}
// CWireDoc serialization
void CWireDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}
// CWireDoc diagnostics
#ifdef _DEBUG
void CWireDoc::AssertValid() const
{
	CDocument::AssertValid();
}
void CWireDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG
// CWireDoc commands
//配置串口连接
BOOL CWireDoc::ConfigConnection()
{
	DCB dcb;
	if(!GetCommState(m_hCom, &dcb))
		return FALSE;
	dcb.fBinary=TRUE;
	dcb.BaudRate = m_nBaud; // 数据传输速率
	dcb.ByteSize = m_nDataBits; // 每字节位数
	dcb.fParity = TRUE;
	switch(m_nParity) // 校验设置
	{
	case 0: 
		dcb.Parity=NOPARITY;
		break;
	case 1: 
		dcb.Parity=EVENPARITY;
		break;
	case 2: 
		dcb.Parity=ODDPARITY;
		break;
	default:;
	}
	switch(m_nStopBits) // 停止位
	{
	case 0: 
		dcb.StopBits=ONESTOPBIT;
		break;
	case 1: 
		dcb.StopBits=ONE5STOPBITS;
		break;
	case 2:
		dcb.StopBits=TWOSTOPBITS;
		break;
	default:;
	}
	// 硬件流控制设置
	dcb.fOutxCtsFlow = TRUE;
	dcb.fRtsControl = TRUE;
	// XON/XOFF流控制设置
	dcb.fInX=dcb.fOutX = TRUE;
	dcb.XonChar = XON;
	dcb.XoffChar = XOFF;
	dcb.XonLim = 50;
	dcb.XoffLim = 50;
	return SetCommState(m_hCom, &dcb);
}
// 打开并配置串行口,建立工作者线程
BOOL CWireDoc::OpenConnection()
{
	COMMTIMEOUTS TimeOuts;
	CView *pView=NULL;
	POSITION firstViewPos;
	firstViewPos=GetFirstViewPosition();
	pView=GetNextView(firstViewPos);
	m_hTermWnd=pView->GetSafeHwnd();
	if(m_bConnected)
		return FALSE;
	m_hCom=CreateFile(m_sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 
		NULL); // 重叠方式
	if(m_hCom==INVALID_HANDLE_VALUE)
	{
		//检查是否连接好GPS设备
		return FALSE;
	}
	
	SetupComm(m_hCom,MAXBLOCK,MAXBLOCK);
	SetCommMask(m_hCom, EV_RXCHAR);
	// 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作
	TimeOuts.ReadIntervalTimeout=MAXDWORD; 
	TimeOuts.ReadTotalTimeoutMultiplier=0; 
	TimeOuts.ReadTotalTimeoutConstant=0; 
	/* 设置写超时以指定WriteComm成员函数中的GetOverlappedResult函数的等待时间*/
	TimeOuts.WriteTotalTimeoutMultiplier=50;
	TimeOuts.WriteTotalTimeoutConstant=2000;
SetCommTimeouts(m_hCom, &TimeOuts);
	if(ConfigConnection())
	{
		m_pThread=AfxBeginThread(CommProc, this, THREAD_PRIORITY_NORMAL, 
			0, CREATE_SUSPENDED, NULL); // 创建并挂起线程
		if(m_pThread==NULL)
		{
			CloseHandle(m_hCom);
			return FALSE;
		}
		else
		{
			//以下两句是启动线程读取串口数据的开关,可以程序员自己控制什么时候启动
			m_bConnected=TRUE;
			m_pThread->ResumeThread(); // 恢复线程运行
		}
	}
	else
	{
		CloseHandle(m_hCom);
		return FALSE;
	}
	return TRUE;
}
//关闭连接,关闭工作线程
void CWireDoc::CloseConnection()
{
	if(!m_bConnected)
		return;
m_bConnected=FALSE;
	//结束CommProc线程中WaitSingleObject函数的等待
	SetEvent(m_hPostMsgEvent); 
	//结束CommProc线程中WaitCommEvent的等待
	SetCommMask(m_hCom, 0); 
	//等待辅助线程终止
	WaitForSingleObject(m_pThread->m_hThread, INFINITE);
	m_pThread=NULL;
	CloseHandle(m_hCom);
}
UINT CommProc(LPVOID pParam)
{
	CWireDoc *pDoc=(CWireDoc*)pParam;
	OVERLAPPED os;
	DWORD dwMask, dwTrans;
	COMSTAT ComStat;
	DWORD dwErrorFlags;
	/*memset(&os, 0, sizeof(OVERLAPPED));
	os.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
	if(os.hEvent==NULL)
	{
		AfxMessageBox("Can't create event object!");
		return (UINT)-1;
	}*/
	char buf[1024];
	buf[0]='\0';
	char bufEx[10]="$GPRMC";
	int nCount=0;
	int nLength=0;
	while(pDoc->m_bConnected)
	{
		ClearCommError(pDoc->m_hCom,&dwErrorFlags,&ComStat);
		if(ComStat.cbInQue)
		{
			Sleep(200);
			nLength=pDoc->ReadComm(buf,cNlength);
			char *bufTmp=strstr(buf,bufEx);
			if (bufTmp==NULL)
			{
				continue;
			}
			else
			{
				WaitForSingleObject(pDoc->m_hPostMsgEvent,INFINITE);
				ResetEvent(pDoc->m_hPostMsgEvent);
				pDoc->GetData(buf,nLength);
			}	
		}
		//dwMask=0;
		//if(!WaitCommEvent(pDoc->m_hCom, &dwMask, &os)) // 重叠操作
		//{
		//	if(GetLastError()==ERROR_IO_PENDING)
		//		// 无限等待重叠操作结果
		//		GetOverlappedResult(pDoc->m_hCom, &os, &dwTrans, TRUE);
		//	else
		//	{
		//		CloseHandle(os.hEvent);
		//		return (UINT)-1;
		//	}
		//}
	}
	//CloseHandle(os.hEvent);
	return 0;
}
// 从串行口输入缓冲区中读入指定数量的字符
DWORD CWireDoc::ReadComm(char *buf, DWORD dwLength)
{
	DWORD length=0;
	DWORD ret=0;
	COMSTAT ComStat;
	DWORD dwErrorFlags;
	ClearCommError(m_hCom,&dwErrorFlags,&ComStat);
	length=min(dwLength, ComStat.cbInQue);
	//TRACE( "\r\n  ComStat.cbInQue = %d ,length=%d",  ComStat.cbInQue,length );
	ReadFile(m_hCom,buf,length,&ret,&m_osRead);
	buf[length-1]='\0';
	//ReadFile(m_hCom,buf,dwLength,&ret,NULL);
	// TRACE( "\r\n  ret = %d ",  ret );
	return length;
	//return dwLength;
}
int CWireDoc::GetCharOccurrence(char *strSource,char cDivider)  
{  
	if(strSource==NULL) return 0;  
	int nCount=0;  
	char *pStart=strSource;  
	char* pDividerPos = strchr( pStart, cDivider);  
	while(pDividerPos)  
	{  
		nCount++;  
		pStart=pDividerPos+1;  
		pDividerPos = strchr( pStart, cDivider);  
	}  
	return nCount;  
}  
int CWireDoc::GetData(char *buf,int nLength)
{
	if (buf==NULL)
	{
		SetEvent(m_hPostMsgEvent); // 允许发送下一个WM_COMMNOTIFY消息
		return 0;
	}
	CString str=buf;
	int ii,j,k;
	int day=0;
	long  Utime;
	CString str2;
	CString  strTime;
	CString  strStatus;
	CString strLatitude;
	CString strLongitude;
	CString strSpeed;
	CString strCourse;
	CString strDate;
	double dHisLatitude=0;
	double dHisLongitude=0;
	k=str.Find(_T("$GPRMC"),0);
	if (k>= 0&&k<=40)
	{
		int count=GetCharOccurrence(buf,','); 
		if( count>8)
		{
			//该输出语句中的各项以','分隔
			for (ii=k,j=0; (ii<nLength)&&(str[ii]!='/r'); ii++)                  //j为逗号的计数器
			{
				if (str[ii] == ',')
				{
					j++;
					if(j>9) break;
					str2 = "";
					for (ii++; (ii<nLength)&&(str[ii]!=',')&&(str[ii]!='/r'); ii++)
						str2 += str[ii];                      //str为某项的值
					ii--;
					//对各项数据分别处理
					switch (j)
					{
					case 1:                                     //时间(UTC)  
						Utime = atoi(str2.Left(6))+80000;
						if(Utime>240000)
						{
							Utime=Utime%240000;
							day=1;
						}
						strTime.Format("%6d",Utime); 
						strTime.Insert(2, ':');
						strTime.Insert(5, ':');
						break;
					case 2:                                     //状态(A-数据有效;V-数据无效,还未定位)
						if (str2 == "A")
							strStatus = "有效数据";
						else if(str2 == "V")
						{
							strStatus = "正在定位...";
							//goto end;
						}
						else
						{
							strStatus = "非法数据格式";
							goto end;
						}
						break;
					case 3:                                     //纬度(ddmm.mmmm)
						float  fLat;
						fLat=atof(str2.Left(2))+atof(str2.Mid(2,2))/60+atof(str2.Right(4))/600000;
						dHisLatitude=m_pGpsInfo.fCurLatitude;
						m_pGpsInfo.fCurLatitude=fLat;
						strLatitude.Format("%.7f",fLat);
						break;
					case 4:                                     //纬度指示(N-北纬;S-南纬)
						if (str2 == "N")
							strLatitude.Insert(0, _T("北纬:"));
						else
							strLatitude.Insert(0, _T("南纬:"));
						break;
					case 5:                                     //经度(dddmm.mmmm)
						float  fLong;
						fLong=atof(str2.Left(3))+atof(str2.Mid(3,2))/60+atof(str2.Right(4))/600000;
						dHisLongitude=m_pGpsInfo.fCurLongitude;
						m_pGpsInfo.fCurLongitude=fLong;
						strLongitude.Format("%.7f",fLong);
						break;
					case 6:                                     //经度指示(E-东经;W-西经)
						if (str2 == "E")
							strLongitude.Insert(0, _T("东经:"));
						else
							strLongitude.Insert(0, _T("西经:"));
						break;
					case 7:                                     //速度(单位:节)
						strSpeed = str2;
						break;
					case 8:                                     //航向(单位:度)
						strCourse = str2;
						break;
					case 9:		//日期(UTC)
						int nlen=strlen(str2.GetBuffer());
						str2.ReleaseBuffer();
						if (nlen<6)//当接受的数据不对时,还原为上次的数据
						{
							m_pGpsInfo.fCurLatitude=dHisLatitude;
							m_pGpsInfo.fCurLongitude=dHisLongitude;
							goto end;
						}
						strDate = "";
						strDate += "20";
						strDate += str2[4];
						strDate += str2[5];
						strDate += "-";
						strDate += str2[2];
						strDate += str2[3];
						strDate += "-";
						strDate += str2[0];
						strDate += str2[1];
						CTime   GPStime(atoi(strDate.Left(4)),   atoi(strDate.Mid(5,2)),   atoi(strDate.Mid(8,2)),   atoi(strTime.Left(2)),   atoi(strTime.Mid(3,2)),   atoi(strTime.Mid(6,2)));
						CTimeSpan  GPSSPAN(day, 0, 0, 0 );
						GPStime+=GPSSPAN;
						strDate = GPStime.Format("%Y-%m-%d %H:%M:%S");
						m_pGpsInfo.strTime=strDate;
						break;
						//default:
						//    break;
					}
				}
			}
		}
	}
end:
	SetEvent(m_hPostMsgEvent); // 允许发送下一个WM_COMMNOTIFY消息
	return 0;
}
#pragma once
#include "Config.h"
#define MAXBLOCK 4096
#define XON 0x11
#define XOFF 0x13
const int cNlength=100;
class CWireDoc : public CDocument
{
protected: // create from serialization only
	CWireDoc();
	DECLARE_DYNCREATE(CWireDoc)
// Attributes
public:
	int m_nBaud;//数据传输速率
	int m_nDataBits;//数据位
	int m_nParity;//校验位
	CString m_sPort;//串行端口
	int m_nStopBits;//停止位
	int m_nTime;//更新数据的时间间隔
	CConfig m_config;
	volatile BOOL m_bConnected;//表示连接否,用来标识菜单串口连接和断开连接是否可用
	volatile HANDLE m_hCom; // 串行口句柄
	CWinThread* m_pThread; // 代表辅助线程
	volatile HANDLE m_hPostMsgEvent; // 用于WM_COMMNOTIFY消息的事件对象
	volatile HWND m_hTermWnd;//辅助窗口
	OVERLAPPED m_osRead, m_osWrite; // 用于重叠读/写
	GpsDataInfo m_pGpsInfo;
		// Operations
public:
// Overrides
	public:
	virtual BOOL OnNewDocument();
	virtual void Serialize(CArchive& ar);
	BOOL ConfigConnection();
	BOOL OpenConnection();
	void CloseConnection();
	DWORD ReadComm(char *buf, DWORD dwLength);
	int GetCharOccurrence(char *strSource,char cDivider);
	int GetData(char *buf,int nLength);
// Implementation
public:
	virtual ~CWireDoc();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
	DECLARE_MESSAGE_MAP()
};
UINT CommProc(LPVOID pParam);
                    
                
                
            
        
浙公网安备 33010602011771号