📄 demo3doc.cpp
字号:
// Demo3Doc.cpp : implementation of the CDemo3Doc class
//
#include "stdafx.h"
#include "Demo3.h"
#include "map.h"
#include "Listen.h"
#include "TcpData.h"
#include "UdpData.h"
#include "Register.h"
#include "Dynamic.h"
#include "Demo3Doc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDemo3Doc
IMPLEMENT_DYNCREATE(CDemo3Doc, CDocument)
BEGIN_MESSAGE_MAP(CDemo3Doc, CDocument)
//{{AFX_MSG_MAP(CDemo3Doc)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDemo3Doc construction/destruction
CDemo3Doc::CDemo3Doc()
{
// TODO: add one-time construction code here
m_pMemDC = NULL;
m_pBitmap = NULL;
m_pData = NULL;
m_nMaxPoint = 0;
//设置初始偏移位置
m_nOffsetX = 0;
m_nOffsetY = 0;
//初始化文档标题
m_strMapName = _T("无海图");
//初始化网络通信类
m_pListen = NULL;
m_pUdp = NULL;
//初始化类型选择
m_nSelected = 0;
//初始化动态目标数据
m_pShips = new CDynaObjects(this);
m_nMustResend = 0;
m_nCanDisplay = 0;
}
CDemo3Doc::~CDemo3Doc()
{
if(m_aLayers.GetSize()>0)
{
int i;
for(i = m_aLayers.GetSize(); i>0; i--)
{
delete m_aLayers.GetAt(i-1);
}
m_aLayers.RemoveAll();
}
if(m_pMemDC)
{//清除程序创建的DC资源
m_pMemDC->SelectObject(m_pDefaultBitmap);
m_pMemDC->DeleteDC();
m_pMemDC = NULL;
}
if(m_pBitmap)
{//清除程序创建的BITMAP资源
m_pBitmap->DeleteObject();
delete m_pBitmap;
m_pBitmap = NULL;
}
if(m_pData)
{//清除绘图用整数数组
m_nMaxPoint = 0;
delete[] m_pData;
m_pData = NULL;
}
//删除动态目标数据
delete m_pShips;
//清除网络通信接口
CloseAllTcp();
}
BOOL CDemo3Doc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
//清除网络通信接口
CloseAllTcp();
//选择程序类型
CRegister dlg;
dlg.m_nSelected = m_nSelected;
dlg.DoModal();
m_nSelected = dlg.m_nSelected;
CloseAllTcp();//清除网络通信接口
m_nCanDisplay = 1<<m_nSelected;
m_pShips->InitData();//清原动态目标
//建立网络接口
if(!InitSocket(InterNetTcpPort[m_nSelected], InterNetUdpPort[m_nSelected]))
{
AfxMessageBox("本机无法启动指定的网络设定!");
CloseAllTcp();//清除网络通信接口
m_nSelected = -1;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////
// CDemo3Doc serialization
void CDemo3Doc::Serialize(CArchive& ar)
{//读海图数据,同时绘制海图
if (ar.IsStoring())
{
// TODO: add storing code here
/*
m_fMapjw[0]=105.0;//海图左边界经度
m_fMapjw[1]=120.0;//海图右边界经度
m_fMapjw[2]=28.0;//海图上边界纬度
m_fMapjw[3]=15.0;//海图下边界纬度(南纬为负)
m_fMaxCX = 8430;
m_fMaxCY = 10562;
m_strMapName = _T("中国东部海区");
ar << 123456;//保存文件类型标志
ar << m_strMapName;//海图名称
ar << m_fMapjw[0] << m_fMapjw[1] << m_fMapjw[2] << m_fMapjw[3];//本海图经纬度范围
ar << m_fMaxCX << m_fMaxCY ;//海图初始显示范围
ar << 4;//图层数量
CString layer;
layer=_T("海岸线");//海岸线层名称
ar << layer;
layer=_T("Coast");//海岸线层文件名(不含扩展名)
ar << layer;
layer=_T("等深线");//等深线层名称
ar << layer;
layer=_T("Isobath");//等深线层文件名(不含扩展名)
ar << layer;
layer=_T("岛屿");//岛屿层名称
ar << layer;
layer=_T("Island");//岛屿层文件名(不含扩展名)
ar << layer;
layer=_T("大城市");//大城市层名称
ar << layer;
layer=_T("City");//大城市层文件名(不含扩展名)
ar << layer;
*/
}
else
{
// TODO: add loading code here
InitData();//清理用户数据
//获得海图数据所在的路径
CString strPath=ar.GetFile()->GetFilePath();
int len=strPath.GetLength();
for(;strPath.GetAt(len-1) != '\\';len--);
strPath = strPath.Left(len);//strPath为全路径名
int filestyle;
ar >> filestyle;//读海图控制文件标志
if(filestyle != 123456)
{
AfxMessageBox("文件类型错:打开文件非海图控制文件!");
return;
}
ar >> m_strMapName;//取海图名
ar >> m_fMapjw[0] >> m_fMapjw[1] >> m_fMapjw[2] >> m_fMapjw[3];//取海图经纬度范围
ar >> m_fMaxCX >> m_fMaxCY;//取海图初始大小
int i, number;
ar >>number;//取海图总层数
CMapLayer *pMap;
//读各海图层数据
for(i=0;i<number;i++)
{
CString strLayername, strLayerfile;
ar >> strLayername;//取海图图层名
ar >> strLayerfile;//取海图文件名(无后缀)
strLayerfile = strPath + strLayerfile + _T(".MIF");
CFile file;
if(file.Open(LPCTSTR(strLayerfile), CFile::modeRead))
{
CArchive lar(&file, CArchive::load);
pMap = new CMapLayer(this, lar);
pMap->m_strLayerName = strLayername;
m_aLayers.Add(pMap);
m_nMaxPoint = m_nMaxPoint > pMap->m_nMaxPoint ? m_nMaxPoint : pMap->m_nMaxPoint;
}
}
m_pData = new long[m_nMaxPoint*2];//申请计算用临时内存
DrawMap(m_pMemDC);//在位图上绘制海图
SetLayerMenu();//设置屏幕菜单
}
}
void CDemo3Doc::ConvToXY(float jing, float wei, long& cx, long& cy)
{
cx = (long)((m_fMaxCX * (jing-m_fMapjw[0]))/(m_fMapjw[1]-m_fMapjw[0])+0.5);
cy = (long)((m_fMaxCY * (relfa(m_fMapjw[2])-relfa(wei)))/(relfa(m_fMapjw[2]) - relfa(m_fMapjw[3]))+0.5);
}
void CDemo3Doc::ConvToXYs(float* jw, long* xy, int n)
{
int i;
float jing, wei;
for(i=0;i<n;i++)
{
jing = *(jw + i*2);
wei = *(jw + i*2 + 1);
*(xy + i*2) = (long)((m_fMaxCX * (jing-m_fMapjw[0]))/(m_fMapjw[1]-m_fMapjw[0])+0.5);
*(xy + i*2+1) = (long)((m_fMaxCY * (relfa(m_fMapjw[2])-relfa(wei)))/(relfa(m_fMapjw[2]) - relfa(m_fMapjw[3]))+0.5);
}
}
void CDemo3Doc::ConvToJW(long cx, long cy, float& jing, float& wei)
{
jing = m_fMapjw[0] + cx*(m_fMapjw[1] - m_fMapjw[0]) / m_fMaxCX;
wei = (float)(absfa(relfa(m_fMapjw[2]) - cy * (relfa(m_fMapjw[2]) - relfa(m_fMapjw[3])) / m_fMaxCY));
for(; jing > 180.0 ; jing -= 360);
for(; jing < -180.0 ; jing += 360);
}
void CDemo3Doc::DrawMap(CDC* pDC)
{
int i;
int j = m_aLayers.GetSize();
CMapLayer* player;
//清空原位图
pDC->BitBlt(0, 0, m_nViewWidth, m_nVeiwHeight, NULL, 0, 0, WHITENESS);
//以下程序开始绘制海图
//由于海图中各图元重叠时会互相遮挡,必须分别绘制
//绘制顺序为:面图元,线图元,点图元(文字等)
for(i=0; i<j; i++)
{//遍历各海图层,绘区域图元
player = m_aLayers.GetAt(i);
if(player->m_bCanDraw)
{
player->Draw(pDC, IDS_POLYGON);
}
}
for(i=0; i<j; i++)
{//遍历各海图层,绘折线图元
player = m_aLayers.GetAt(i);
if(player->m_bCanDraw)
{
player->Draw(pDC, IDS_PLINE);
}
}
for(i=0; i<j; i++)
{//遍历各海图层,绘文字图元
player = m_aLayers.GetAt(i);
if(player->m_bCanDraw)
{
player->Draw(pDC, IDS_TEXT);
}
}
}
void CDemo3Doc::Zoom(float scale)
{
m_fMaxCX *= scale;
m_fMaxCY *= scale;
}
void CDemo3Doc::LPtoDPs(long* data, int n)
{
int i;
for(i=0; i<n; i++)
{
*(data + 2*i) += m_nOffsetX;
*(data + 2*i+1) += m_nOffsetY;
}
}
void CDemo3Doc::LPtoDP(long& x, long& y)
{
x += m_nOffsetX;
y += m_nOffsetY;
}
void CDemo3Doc::DPtoLP(long& x, long& y)
{
x -= m_nOffsetX;
y -= m_nOffsetY;
}
void CDemo3Doc::SetCenter(CPoint point)
{
m_nOffsetX = m_nViewWidth / 2 - point.x;
m_nOffsetY = m_nVeiwHeight / 2 - point.y;
}
void CDemo3Doc::MoveOffset(CPoint point)
{
m_nOffsetX += point.x;
m_nOffsetY += point.y;
}
void CDemo3Doc::SetLayerMenu(bool open)
{
int iPos;
CMenu *pMenu, *pLayerMenu = NULL;
CMenu* pTopMenu = AfxGetMainWnd()->GetMenu();//获得主菜单句柄
for (iPos = pTopMenu->GetMenuItemCount()-1; iPos >= 0; iPos--)
{//遍历主菜单栏中各项
pMenu = pTopMenu->GetSubMenu(iPos);//获得对应的子菜单
if (pMenu && pMenu->GetMenuItemID(0) == ID_MENUITEM_LAYER1)
{//检索指定的菜单项
pLayerMenu = pMenu;
break;
}
}
ASSERT(pLayerMenu != NULL);
//删除原有菜单
for (iPos = pLayerMenu->GetMenuItemCount()-1; iPos >= 0; iPos--)
pLayerMenu->DeleteMenu(iPos, MF_BYPOSITION);
if(!open)
{
pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER1, _T("(空)"));
return;
}
iPos = m_aLayers.GetSize();
if(iPos == 0)
pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER1, _T("(空)"));
if(iPos >0)
pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER1, m_aLayers.GetAt(0)->m_strLayerName);
if(iPos >1)
pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER2, m_aLayers.GetAt(1)->m_strLayerName);
if(iPos >2)
pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER3, m_aLayers.GetAt(2)->m_strLayerName);
if(iPos >3)
pLayerMenu->AppendMenu(MF_STRING, ID_MENUITEM_LAYER4, m_aLayers.GetAt(3)->m_strLayerName);
}
void CDemo3Doc::InitData()
{
if(m_aLayers.GetSize()>0)
{
int i;
for(i = m_aLayers.GetSize(); i>0; i--)
{
delete m_aLayers.GetAt(i-1);
}
m_aLayers.RemoveAll();
}
if(m_nMaxPoint)
{//清除绘图用整数数组
m_nMaxPoint = 0;
delete[] m_pData;
m_pData = NULL;
}
//设置初始偏移位置
m_nOffsetX = 0;
m_nOffsetY = 0;
//初始化文档标题
m_strMapName = _T("无海图");
}
void CDemo3Doc::DisplayLocationOnStatusBar(CPoint point)
{
if(!m_aLayers.GetSize())
{//未打开海图
return;
}
CStatusBar* pStatus;
pStatus = (CStatusBar*) AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
//AFX_IDW_STATUS_BAR 为系统预定义常量(StatusBar的缺省ID)
CPoint pt = point;
float jing, wei;
DPtoLP(pt.x, pt.y);//转换为屏幕坐标
ConvToJW(pt.x, pt.y, jing, wei);//转换为经纬度
CString strlon, strlat;
int degree = jing;
int minute = (jing - degree)*60;
int secend = (jing - degree)*3600 - minute*60;
if(jing<0)
strlon.Format(" 西经:%3d度 %2d分 %2d秒 ", -degree, -minute, -secend);
else
strlon.Format(" 东经:%3d度 %2d分 %2d秒 ", degree, minute, secend);
degree = wei;
minute = (wei - degree)*60;
secend = (wei - degree)*3600 - minute*60;
if(wei<0)
strlat.Format("南纬:%3d度 %2d分 %2d秒", -degree, -minute, -secend);
else
strlat.Format("北纬:%3d度 %2d分 %2d秒", degree, minute, secend);
pStatus->SetPaneText(0, strlon+strlat) ;
}
/////////////////////////////////////////////////////////////////////////////
// CDemo3Doc diagnostics
#ifdef _DEBUG
void CDemo3Doc::AssertValid() const
{
CDocument::AssertValid();
}
void CDemo3Doc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDemo3Doc commands
void CDemo3Doc::SetTitle(LPCTSTR lpszTitle)
{
// TODO: Add your specialized code here and/or call the base class
//设置文档标题
CDocument::SetTitle(LPCTSTR(m_strMapName));
}
void CDemo3Doc::ProcessPendingAccept()
{
CTcpSocket* pSocket = new CTcpSocket(this);
if (m_pListen->Accept(*pSocket))
{
m_lstConnectionList.AddTail(pSocket);
}
else
delete pSocket;
}
CTcpSocket* CDemo3Doc::ProcessPendingLink(char* RemoteHost, long RemotePort)
{
CTcpSocket* pSocket = new CTcpSocket(this);
pSocket->Create();
if (pSocket->Connect(RemoteHost, RemotePort))
{
m_lstConnectionList.AddTail(pSocket);
return pSocket;
}
else
{
pSocket->Close();
delete pSocket;
return NULL;
}
}
void CDemo3Doc::ProcessPendingRead(char* buf, int len)
{
switch(*(short*)buf)
{
case 0x10:
m_pShips->ReceiveHJ((TRACK0_10H*)buf);
break;
case 0x11:
m_pShips->ReceiveHJ1((TRACK1_11H*)buf);
break;
case 0x20:
{
REQUESTRESEND_20H* r = (REQUESTRESEND_20H*)buf;
if(r->Request)
m_nMustResend |= r->corp;//设置指定位
else
m_nMustResend &= ~ r->corp;//清零指定位
}
break;
case 0x21:
{
ANSWERRESEND_21H* a = (ANSWERRESEND_21H*)buf;
if(a->Answer)
m_nCanDisplay |= a->corp;//设置指定位
else
m_nCanDisplay &= ~ a->corp;//清零指定位
}
break;
default:
break;
}
}
void CDemo3Doc::CloseSocket(CTcpSocket* pSocket)
{
POSITION pos=m_lstConnectionList.Find(pSocket);
if(pos)
{
m_lstConnectionList.RemoveAt(pos);
}
BYTE Buffer[50];
pSocket->ShutDown();
while (pSocket->Receive(Buffer,50) > 0);
delete pSocket;
}
void CDemo3Doc::CloseAllTcp()
{
BYTE Buffer[50];
if(m_pListen)
{
m_pListen->Close();
delete m_pListen;
m_pListen = NULL;
}
if(m_pUdp)
{
m_pUdp->ShutDown();
while (m_pUdp->Receive(Buffer,50) > 0);
delete m_pUdp;
m_pUdp = NULL;
}
while(!m_lstConnectionList.IsEmpty())
{
CTcpSocket* pSocket = (CTcpSocket*)m_lstConnectionList.RemoveHead();
if (pSocket)
{
pSocket->ShutDown();
while (pSocket->Receive(Buffer,50) > 0);
delete pSocket;
}
}
}
bool CDemo3Doc::InitSocket(long tcpport, long udpport)
{
m_pUdp = new CUdpData(this);
if(!m_pUdp->Create(udpport, SOCK_DGRAM))
{//无法创建UDP网络通信端口
delete m_pUdp;
m_pUdp = NULL;
return false;
}
m_pListen = new CListen(this);
if (m_pListen->Create(tcpport))
{
if (m_pListen->Listen())
return TRUE;
else
{
delete m_pListen;
m_pListen = NULL;
}
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -