我有个程序不懂,老师要我尽快弄懂,哪位大侠可以帮我看看整体结构是怎样的?能细点说明下更好!谢谢!
// 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);
}