⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpsscdoc.cpp

📁 用VC写的监控中心后台程序。 代码全
💻 CPP
字号:
// GpsSCDoc.cpp : implementation of the CGpsSCDoc class
//

#include "stdafx.h"
#include "GpsSC.h"

#include "GpsSCDoc.h"
#include "ProcSM.h"
#include "SetCommDlg.h"
#include "ShowAllClientDlg.h"
#include "AddClientinfoDlg.h"
#include "ClientinfoSet.h"
#include "VehicleMessageSet.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern CGpsSCApp theApp;       // 在此引用应用类中的theApp来获取库连接指针
/////////////////////////////////////////////////////////////////////////////
// CGpsSCDoc

IMPLEMENT_DYNCREATE(CGpsSCDoc, CDocument)
BEGIN_MESSAGE_MAP(CGpsSCDoc, CDocument)
	//{{AFX_MSG_MAP(CGpsSCDoc)
	ON_UPDATE_COMMAND_UI(ID_CCONNET_COMM, OnUpdateCconnetComm)
	ON_COMMAND(ID_CDISCONNET_COMM, OnCdisconnetComm)
	ON_UPDATE_COMMAND_UI(ID_CDISCONNET_COMM, OnUpdateCdisconnetComm)
	ON_COMMAND(ID_CSET_COMM, OnCsetComm)
	ON_UPDATE_COMMAND_UI(ID_CSET_COMM, OnUpdateCsetComm)
	ON_COMMAND(IDD_READONESM, OnReadonesm)
	ON_COMMAND(IDD_ADDCLIENTD, OnAddclientd)
	ON_COMMAND(IDD_CLIENTLIST, OnClientlist)
	ON_UPDATE_COMMAND_UI(IDD_CLIENTLIST, OnUpdateClientlist)
	ON_UPDATE_COMMAND_UI(IDD_ADDCLIENTD, OnUpdateAddclientd)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGpsSCDoc construction/destruction

CGpsSCDoc::CGpsSCDoc()
{
	// TODO: add one-time construction code here
	m_bConnected = FALSE;
	m_pThread	 = NULL;

	m_sPort			 = theApp.m_strPort;
	m_nBaud			 = atol(theApp.m_strBaud);
	m_nDataBits		 = atol(theApp.m_strDataBits);
	m_nParity		 = theApp.m_nParity;
	m_nStopBits		 = theApp.m_nStopBit;
}

CGpsSCDoc::~CGpsSCDoc()
{
	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 CGpsSCDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
	if (!CDocument::OnNewDocument())
	{
		return FALSE;
	}
	
	SetTitle("广州海特天高信息有限公司");

	// 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;

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CGpsSCDoc serialization

void CGpsSCDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CGpsSCDoc diagnostics

#ifdef _DEBUG
void CGpsSCDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CGpsSCDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CGpsSCDoc commands

// 打开并配置串行口,建立工作者线程
BOOL CGpsSCDoc::OpenConnection()
{
	COMMTIMEOUTS TimeOuts;

	POSITION firstViewPos;
	CView *pView;

	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)
	{
		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 CGpsSCDoc::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);
}

BOOL CGpsSCDoc::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	= 1;
	dcb.fRtsControl		= 1?RTS_CONTROL_HANDSHAKE:RTS_CONTROL_ENABLE;

	// XON/XOFF流控制设置
	dcb.fInX			= dcb.fOutX = 1;
	dcb.XonChar			= XON;
	dcb.XoffChar		= XOFF;
	dcb.XonLim			= 50;
	dcb.XoffLim			= 50;
*/
	return SetCommState(m_hCom, &dcb);
}

DWORD CGpsSCDoc::ReadComm(char *buff, DWORD dwLength)
{
	DWORD length=0;
	COMSTAT ComStat;
	DWORD dwErrorFlags;

	ClearCommError(m_hCom,&dwErrorFlags,&ComStat);
	length=min(dwLength, ComStat.cbInQue);

	ReadFile(m_hCom,buff,length,&length,&m_osRead);

	return length;
}

DWORD CGpsSCDoc::WriteComm(char *buff, DWORD dwLength)
{
	BOOL fState;
	DWORD length=dwLength;
	COMSTAT ComStat;
	DWORD dwErrorFlags;

	ClearCommError(m_hCom,&dwErrorFlags,&ComStat);
	fState=WriteFile(m_hCom,buff,length,&length,&m_osWrite);

	if(!fState)
	{
		if(GetLastError()==ERROR_IO_PENDING)
		{
			GetOverlappedResult(m_hCom,&m_osWrite,&length,TRUE);		// 等待
		}
		else
		{
			length=0;
		}
	}

	return length;
}




// 工作者线程,负责监视串行口
UINT CommProc(LPVOID pParam)
{
	OVERLAPPED os;
	DWORD dwMask, dwTrans;
	COMSTAT ComStat;
	DWORD dwErrorFlags;

	CGpsSCDoc *pDoc=(CGpsSCDoc*)pParam;

	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;
	}

	while(pDoc->m_bConnected)
	{
		ClearCommError(pDoc->m_hCom,&dwErrorFlags,&ComStat);
		
		if(ComStat.cbInQue)
		{
			// 无限等待WM_COMMNOTIFY消息被处理完
			WaitForSingleObject(pDoc->m_hPostMsgEvent, INFINITE);
			ResetEvent(pDoc->m_hPostMsgEvent);

			// 通知视图
			PostMessage(pDoc->m_hTermWnd, WM_COMMNOTIFY, EV_RXCHAR, 0);

			continue;
		}

		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;
}

//inite the Wavecom
BOOL CGpsSCDoc::OnConnetComm() 
{
	// TODO: Add your command handler code here
	if(!OpenConnection())
	{
		AfxMessageBox("不能打开串行口!");
		return FALSE;
	}

	return TRUE;	
}

void CGpsSCDoc::OnUpdateCconnetComm(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(!m_bConnected);
}

void CGpsSCDoc::OnCdisconnetComm() 
{
	// TODO: Add your command handler code here
	CloseConnection();
}

void CGpsSCDoc::OnUpdateCdisconnetComm(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_bConnected);
}

void CGpsSCDoc::OnCsetComm() 
{
	// TODO: Add your command handler code here
	CSetCommDlg		dlg;
	CString			str;
	

	dlg.m_bConnected = m_bConnected;
	dlg.m_sPort		 = theApp.m_strPort;
	dlg.m_sBaud		 = theApp.m_strBaud;
	dlg.m_sDataBits  = theApp.m_strDataBits;
	dlg.m_nParity	 = theApp.m_nParity;
	dlg.m_nStopBits  = theApp.m_nStopBit;

	if(dlg.DoModal() == IDOK)
	{
		m_sPort		= dlg.m_sPort;
		m_nBaud		= atoi(dlg.m_sBaud);
		m_nDataBits = atoi(dlg.m_sDataBits);
		m_nParity	= dlg.m_nParity;
		m_nStopBits = dlg.m_nStopBits;

		theApp.m_strPort		= dlg.m_sPort;
		theApp.m_strBaud		= dlg.m_sBaud;
		theApp.m_strDataBits	= dlg.m_sDataBits;
		theApp.m_nParity		= dlg.m_nParity;
		theApp.m_nStopBit		= dlg.m_nStopBits;
		if(m_bConnected)
		{
			if(!ConfigConnection())
			{
				AfxMessageBox( "不能设置串行口!");
			}
		}		
		
	}
}

void CGpsSCDoc::OnUpdateCsetComm(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	
}




void CGpsSCDoc::OnReadonesm() 
{
	WriteComm("AT+CMGR=1\r",10);
}

void CGpsSCDoc::OnAddclientd() 
{
	CAddClientinfoDlg dlg;
	dlg.DoModal();
}

void CGpsSCDoc::OnClientlist() 
{
	CShowAllClientDlg dlg;
	dlg.DoModal();
}

BOOL CGpsSCDoc::CanCloseFrame(CFrameWnd* pFrame) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	return CDocument::CanCloseFrame(pFrame);

	CVehicleMessageSet		messageSet;
	CClientinfoSet	clientinfoSet;

	try
	{
		messageSet.Close();
		clientinfoSet.Close();
	}
	catch(CDBException *Exp)
	{
		AfxMessageBox(Exp->m_strError);
		messageSet.Close();
		clientinfoSet.Close();
	}
}

void CGpsSCDoc::OnUpdateClientlist(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(theApp.m_bUserType);
}

void CGpsSCDoc::OnUpdateAddclientd(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(theApp.m_bUserType);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -