主题:求助VC大侠
我有个程序不懂,老师要我尽快弄懂,哪位大侠可以帮我看看整体结构是怎样的?能细点说明下更好!谢谢!
// GPSDlg.cpp : implementation file
//
#include "stdafx.h"
#include "GPS.h"
#include "GPSDlg.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CGPSApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CGPSDlg dialog
HANDLE hCom;
HANDLE POPTRIGER;
DCB Dcb;
DCB Dcbtriger;
double H,X0,Y0,Z0,X,Y,Z; //H海拔,XYZ大地直角坐标,Z0Y0Z0参考点
CGPSDlg::CGPSDlg(CWnd* pParent /*=NULL*/)
: CDialog(CGPSDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CGPSDlg)
Displace = 0.0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
bool Positionfixed=0;
void CGPSDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CGPSDlg)
DDX_Control(pDX, IDC_COMBCMD, m_CombCmd);
DDX_Text(pDX, IDC_DISPLACE, Displace);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CGPSDlg, CDialog)
//{{AFX_MSG_MAP(CGPSDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CLEARDISTANCE, OnCleardistance)
ON_MESSAGE(WM_USER,OnMyMessage)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGPSDlg message handlers
int OpenComm();
UINT ComReceiveTheadProc(LPVOID pParam);
BOOL CGPSDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
Positionfixed=0;
OpenComm();
AfxBeginThread(ComReceiveTheadProc, NULL,THREAD_PRIORITY_LOWEST);
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CGPSDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CGPSDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
bool TRIGER=0;
char gBuf[100];
LRESULT CGPSDlg::OnMyMessage(WPARAM wParam,LPARAM lParam)
{
SetDlgItemText(IDC_GPSINFO,gBuf);
int i,k;
char buf[100],str[20];
char UTC[20],Latitude[40],Longitude[40],Haiba[40];
double P0 = 0.017453292519943; //PI/180
CString str1;
strcpy(buf,gBuf);
for(i=0;i<6;i++) str[i]=buf[i];
str[6]=0;
SetDlgItemText(IDC_EXCEED,"^_^");
if((strcmp(str,"$GPGGA"))==0)
{
k=0;
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;i<15;i++){ UTC[i]=buf[k]; if(buf[k++] == ',') break;}
UTC[i]=0;
for(i=0;i<20;i++){ Latitude[i]=buf[k]; if(buf[k++] == ',') break;}
Latitude[i]=0;
for(i=0;i<10;i++){if(buf[k++] == ',') break;}
for(i=0;i<20;i++){ Longitude[i]=buf[k]; if(buf[k++] == ',') break;}
Longitude[i]=0;
for(i=0;;i++){if(buf[k++] == ',') break;}
buf[k]=='1'?SetDlgItemText(IDC_POS,"单点定位"):SetDlgItemText(IDC_POS,"末定位");
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
if(Positionfixed==0)
{ //因实验地海拔起伏不大,而船舶可能受波浪影响,上下起伏直接造成Displace误差,故只取一次值
for(i=0;;i++){Haiba[i]=buf[k]; if(buf[k++]==',') break;}
Haiba[i]=0;
H=atof(Haiba);
}
//计算位移
double lat1=atof(Latitude);
double lat=floor(lat1/100)*P0+(lat1-floor(lat1/100)*100)*P0/60;
double lon1=atof(Longitude);
double lon=floor(lon1/100)*P0+(lon1-floor(lon1/100)*100)*P0/60;
double a=6378137; //椭球参数
double e2=0.00669437999013;
//坐标转换
double N=a/sqrt(1-e2*sin(lat)*sin(lat));
X=(N+H)*cos(lat)*cos(lon);
Y=(N+H)*cos(lat)*sin(lon);
Z=(N*(1-e2)+H)*sin(lat);
if(Positionfixed==0)
{
X0=X;Y0=Y;Z0=Z;Positionfixed=1;
}
else
{//6米对地球半径来说太小,看成直线距离,也可以按弦、弧的方法再换算一次(没必要)
Displace=sqrt((X-X0)*(X-X0)+(Y-Y0)*(Y-Y0)+(Z-Z0)*(Z-Z0));
UpdateData(false);//更新界面显示
}
if(Displace>6)
{
DWORD Num;
TRIGER=1;
WriteFile(POPTRIGER,&TRIGER,1,&Num,NULL);
TRIGER=0;
//触发并且:
SetDlgItemText(IDC_EXCEED,"超出6米!");
X0=X;Y0=Y;Z0=Z;
}
SetDlgItemText(IDC_UTC,UTC);
SetDlgItemText(IDC_LATITUDE,Latitude);
SetDlgItemText(IDC_LONGITUDE,Longitude);
}
return 0;
}
UINT ComReceiveTheadProc(LPVOID pParam)
{//进程处理程序
unsigned char buf[100],buf1[2];
UINT Msg=WM_USER;
WPARAM wParam=NULL;
LPARAM lParam=0;
int i,num;
bool rev$,LF;
CString strm;
DWORD Num1;
HWND hWnd=theApp.m_pMainWnd->m_hWnd;
while(1)
{
num=0;
rev$=false;
LF=false;
while(!rev$)
{
Sleep(10);
ReadFile(hCom,buf1,1,&Num1,NULL);
//下句标志已找到NMEA字段头
if(Num1==1 && buf1[0]=='$')rev$=true;
};
buf[num++]=buf1[0];
while(!LF && num<80 )
{//逐bit读出数据直到该字段结束
ReadFile(hCom,buf1,1,&Num1,NULL);
if(Num1==1)
{
buf[num++]=buf1[0];
if(buf1[0]==0x0A) LF=true;
}
};
if(LF)
{
for(i=0;i<num;i++) gBuf[i]=buf[i];
// pView->PostMessage(Msg,wParam, lParam );
PostMessage(hWnd,Msg,wParam, lParam );
}
}
// HWND hWnd=(HWND)theApp.GetMainWnd();
return 1;
}
int OpenComm()
{//开两个串口,用于接收GPS数据和位移触发
hCom=CreateFile(
"COM9",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if(hCom==INVALID_HANDLE_VALUE)
{
char szMsg[40]="Can not open ";
MessageBox(NULL,"COM8",szMsg,MB_OK );
return 0;
}
GetCommState(hCom,&Dcb);
Dcb.BaudRate=CBR_38400;
//Dcb.BaudRate=CBR_9600;
// Dcb.BaudRate=CBR_4800;
Dcb.ByteSize=8;
Dcb.Parity=NOPARITY;
Dcb.StopBits=ONESTOPBIT;
Dcb.fOutxCtsFlow=FALSE;
Dcb.fOutxDsrFlow=FALSE;
Dcb.fDtrControl=DTR_CONTROL_ENABLE;
// Dcb.fDtrControl=DTR_CONTROL_DISABLE;
Dcb.fDsrSensitivity=FALSE;
Dcb.fRtsControl=RTS_CONTROL_ENABLE;
Dcb.fNull=FALSE;
SetCommState(hCom,&Dcb);
COMMTIMEOUTS Timeouts;
GetCommTimeouts(hCom,&Timeouts);
Timeouts.ReadIntervalTimeout =100;
// Timeouts.ReadTotalTimeoutMultiplier=2;
Timeouts.ReadTotalTimeoutMultiplier=20;
Timeouts.ReadTotalTimeoutConstant=20;
Timeouts.WriteTotalTimeoutMultiplier=20;
Timeouts.WriteTotalTimeoutConstant =200;
SetCommTimeouts(hCom,&Timeouts);
//打开触发串口
POPTRIGER=CreateFile(
"COM3",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if(POPTRIGER==INVALID_HANDLE_VALUE)
{
char szMsg[40]="Can not open ";
MessageBox(NULL,"COM3",szMsg,MB_OK );
return 0;
}
GetCommState(POPTRIGER,&Dcbtriger);
Dcbtriger.BaudRate=CBR_9600;
// Dcbtriger.BaudRate=CBR_4800;
Dcbtriger.ByteSize=8;
Dcbtriger.Parity=NOPARITY;
Dcbtriger.StopBits=ONESTOPBIT;
Dcbtriger.fOutxCtsFlow=FALSE;
Dcbtriger.fOutxDsrFlow=FALSE;
Dcbtriger.fDtrControl=DTR_CONTROL_ENABLE;
// Dcbtriger.fDtrControl=DTR_CONTROL_DISABLE;
Dcbtriger.fDsrSensitivity=FALSE;
Dcbtriger.fRtsControl=RTS_CONTROL_ENABLE;
Dcbtriger.fNull=FALSE;
SetCommState(POPTRIGER,&Dcbtriger);
COMMTIMEOUTS TRIGERTimeouts;
GetCommTimeouts(POPTRIGER,&TRIGERTimeouts);
TRIGERTimeouts.ReadIntervalTimeout =100;
// TRIGERTimeouts.ReadTotalTimeoutMultiplier=2;
TRIGERTimeouts.ReadTotalTimeoutMultiplier=20;
TRIGERTimeouts.ReadTotalTimeoutConstant=20;
TRIGERTimeouts.WriteTotalTimeoutMultiplier=20;
TRIGERTimeouts.WriteTotalTimeoutConstant =200;
SetCommTimeouts(POPTRIGER,&TRIGERTimeouts);
return 1;
}
void CGPSDlg::OnCleardistance()
{//位移清零
// TODO: Add your control notification handler code here
X0=X;Y0=Y;Z0=Z;Displace=0;
UpdateData(false);
}
// GPSDlg.cpp : implementation file
//
#include "stdafx.h"
#include "GPS.h"
#include "GPSDlg.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CGPSApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CGPSDlg dialog
HANDLE hCom;
HANDLE POPTRIGER;
DCB Dcb;
DCB Dcbtriger;
double H,X0,Y0,Z0,X,Y,Z; //H海拔,XYZ大地直角坐标,Z0Y0Z0参考点
CGPSDlg::CGPSDlg(CWnd* pParent /*=NULL*/)
: CDialog(CGPSDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CGPSDlg)
Displace = 0.0;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
bool Positionfixed=0;
void CGPSDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CGPSDlg)
DDX_Control(pDX, IDC_COMBCMD, m_CombCmd);
DDX_Text(pDX, IDC_DISPLACE, Displace);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CGPSDlg, CDialog)
//{{AFX_MSG_MAP(CGPSDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CLEARDISTANCE, OnCleardistance)
ON_MESSAGE(WM_USER,OnMyMessage)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGPSDlg message handlers
int OpenComm();
UINT ComReceiveTheadProc(LPVOID pParam);
BOOL CGPSDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
Positionfixed=0;
OpenComm();
AfxBeginThread(ComReceiveTheadProc, NULL,THREAD_PRIORITY_LOWEST);
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CGPSDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CGPSDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
bool TRIGER=0;
char gBuf[100];
LRESULT CGPSDlg::OnMyMessage(WPARAM wParam,LPARAM lParam)
{
SetDlgItemText(IDC_GPSINFO,gBuf);
int i,k;
char buf[100],str[20];
char UTC[20],Latitude[40],Longitude[40],Haiba[40];
double P0 = 0.017453292519943; //PI/180
CString str1;
strcpy(buf,gBuf);
for(i=0;i<6;i++) str[i]=buf[i];
str[6]=0;
SetDlgItemText(IDC_EXCEED,"^_^");
if((strcmp(str,"$GPGGA"))==0)
{
k=0;
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;i<15;i++){ UTC[i]=buf[k]; if(buf[k++] == ',') break;}
UTC[i]=0;
for(i=0;i<20;i++){ Latitude[i]=buf[k]; if(buf[k++] == ',') break;}
Latitude[i]=0;
for(i=0;i<10;i++){if(buf[k++] == ',') break;}
for(i=0;i<20;i++){ Longitude[i]=buf[k]; if(buf[k++] == ',') break;}
Longitude[i]=0;
for(i=0;;i++){if(buf[k++] == ',') break;}
buf[k]=='1'?SetDlgItemText(IDC_POS,"单点定位"):SetDlgItemText(IDC_POS,"末定位");
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
for(i=0;;i++){if(buf[k++] == ',') break;}
if(Positionfixed==0)
{ //因实验地海拔起伏不大,而船舶可能受波浪影响,上下起伏直接造成Displace误差,故只取一次值
for(i=0;;i++){Haiba[i]=buf[k]; if(buf[k++]==',') break;}
Haiba[i]=0;
H=atof(Haiba);
}
//计算位移
double lat1=atof(Latitude);
double lat=floor(lat1/100)*P0+(lat1-floor(lat1/100)*100)*P0/60;
double lon1=atof(Longitude);
double lon=floor(lon1/100)*P0+(lon1-floor(lon1/100)*100)*P0/60;
double a=6378137; //椭球参数
double e2=0.00669437999013;
//坐标转换
double N=a/sqrt(1-e2*sin(lat)*sin(lat));
X=(N+H)*cos(lat)*cos(lon);
Y=(N+H)*cos(lat)*sin(lon);
Z=(N*(1-e2)+H)*sin(lat);
if(Positionfixed==0)
{
X0=X;Y0=Y;Z0=Z;Positionfixed=1;
}
else
{//6米对地球半径来说太小,看成直线距离,也可以按弦、弧的方法再换算一次(没必要)
Displace=sqrt((X-X0)*(X-X0)+(Y-Y0)*(Y-Y0)+(Z-Z0)*(Z-Z0));
UpdateData(false);//更新界面显示
}
if(Displace>6)
{
DWORD Num;
TRIGER=1;
WriteFile(POPTRIGER,&TRIGER,1,&Num,NULL);
TRIGER=0;
//触发并且:
SetDlgItemText(IDC_EXCEED,"超出6米!");
X0=X;Y0=Y;Z0=Z;
}
SetDlgItemText(IDC_UTC,UTC);
SetDlgItemText(IDC_LATITUDE,Latitude);
SetDlgItemText(IDC_LONGITUDE,Longitude);
}
return 0;
}
UINT ComReceiveTheadProc(LPVOID pParam)
{//进程处理程序
unsigned char buf[100],buf1[2];
UINT Msg=WM_USER;
WPARAM wParam=NULL;
LPARAM lParam=0;
int i,num;
bool rev$,LF;
CString strm;
DWORD Num1;
HWND hWnd=theApp.m_pMainWnd->m_hWnd;
while(1)
{
num=0;
rev$=false;
LF=false;
while(!rev$)
{
Sleep(10);
ReadFile(hCom,buf1,1,&Num1,NULL);
//下句标志已找到NMEA字段头
if(Num1==1 && buf1[0]=='$')rev$=true;
};
buf[num++]=buf1[0];
while(!LF && num<80 )
{//逐bit读出数据直到该字段结束
ReadFile(hCom,buf1,1,&Num1,NULL);
if(Num1==1)
{
buf[num++]=buf1[0];
if(buf1[0]==0x0A) LF=true;
}
};
if(LF)
{
for(i=0;i<num;i++) gBuf[i]=buf[i];
// pView->PostMessage(Msg,wParam, lParam );
PostMessage(hWnd,Msg,wParam, lParam );
}
}
// HWND hWnd=(HWND)theApp.GetMainWnd();
return 1;
}
int OpenComm()
{//开两个串口,用于接收GPS数据和位移触发
hCom=CreateFile(
"COM9",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if(hCom==INVALID_HANDLE_VALUE)
{
char szMsg[40]="Can not open ";
MessageBox(NULL,"COM8",szMsg,MB_OK );
return 0;
}
GetCommState(hCom,&Dcb);
Dcb.BaudRate=CBR_38400;
//Dcb.BaudRate=CBR_9600;
// Dcb.BaudRate=CBR_4800;
Dcb.ByteSize=8;
Dcb.Parity=NOPARITY;
Dcb.StopBits=ONESTOPBIT;
Dcb.fOutxCtsFlow=FALSE;
Dcb.fOutxDsrFlow=FALSE;
Dcb.fDtrControl=DTR_CONTROL_ENABLE;
// Dcb.fDtrControl=DTR_CONTROL_DISABLE;
Dcb.fDsrSensitivity=FALSE;
Dcb.fRtsControl=RTS_CONTROL_ENABLE;
Dcb.fNull=FALSE;
SetCommState(hCom,&Dcb);
COMMTIMEOUTS Timeouts;
GetCommTimeouts(hCom,&Timeouts);
Timeouts.ReadIntervalTimeout =100;
// Timeouts.ReadTotalTimeoutMultiplier=2;
Timeouts.ReadTotalTimeoutMultiplier=20;
Timeouts.ReadTotalTimeoutConstant=20;
Timeouts.WriteTotalTimeoutMultiplier=20;
Timeouts.WriteTotalTimeoutConstant =200;
SetCommTimeouts(hCom,&Timeouts);
//打开触发串口
POPTRIGER=CreateFile(
"COM3",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if(POPTRIGER==INVALID_HANDLE_VALUE)
{
char szMsg[40]="Can not open ";
MessageBox(NULL,"COM3",szMsg,MB_OK );
return 0;
}
GetCommState(POPTRIGER,&Dcbtriger);
Dcbtriger.BaudRate=CBR_9600;
// Dcbtriger.BaudRate=CBR_4800;
Dcbtriger.ByteSize=8;
Dcbtriger.Parity=NOPARITY;
Dcbtriger.StopBits=ONESTOPBIT;
Dcbtriger.fOutxCtsFlow=FALSE;
Dcbtriger.fOutxDsrFlow=FALSE;
Dcbtriger.fDtrControl=DTR_CONTROL_ENABLE;
// Dcbtriger.fDtrControl=DTR_CONTROL_DISABLE;
Dcbtriger.fDsrSensitivity=FALSE;
Dcbtriger.fRtsControl=RTS_CONTROL_ENABLE;
Dcbtriger.fNull=FALSE;
SetCommState(POPTRIGER,&Dcbtriger);
COMMTIMEOUTS TRIGERTimeouts;
GetCommTimeouts(POPTRIGER,&TRIGERTimeouts);
TRIGERTimeouts.ReadIntervalTimeout =100;
// TRIGERTimeouts.ReadTotalTimeoutMultiplier=2;
TRIGERTimeouts.ReadTotalTimeoutMultiplier=20;
TRIGERTimeouts.ReadTotalTimeoutConstant=20;
TRIGERTimeouts.WriteTotalTimeoutMultiplier=20;
TRIGERTimeouts.WriteTotalTimeoutConstant =200;
SetCommTimeouts(POPTRIGER,&TRIGERTimeouts);
return 1;
}
void CGPSDlg::OnCleardistance()
{//位移清零
// TODO: Add your control notification handler code here
X0=X;Y0=Y;Z0=Z;Displace=0;
UpdateData(false);
}