?? gps.cpp
字號:
/*
Module : GPS.CPP
Purpose: "C" style Implementation to GPS32
Created: PJN / 28-12-1997
History: PJN / 20-01-1998 1. A number of problems were discovered when GPSLIB was being
used in a UNICODE build. These problems have been fixed
2. Mak file now includes all the possible build options
3. Mak file no longer hard codes output to d:\winnt\system32
4. Included release binaries in distribution
PJN / 26-08-1998 1. Small change to stdafx.h to include afxcview.h in gps32exe
2. The GpsShowControlPanel function now actually works
3. Minor tweaks to the GPS Mak files
4. Removed a number of unused symbols
5. Change ID of a number of GPS32EXE menu items to avoid conflict
with new VC 6 defines.
6. Updated all Version Infos to 1.02
7. Removed a level 4 warning from the Test app.
8. Removed unused toolbar from GPS CPL file
9. GPS cpl file now uses standard F2 accelerator for Rename
10. GPS32EXE toolbar is now shown flat
11. Number of extra TRACE statements have been added to
aid in debugging.
PJN / 11-08-1999 1. Now uses the WINAPI calling convention meaning that GPSLIB is now
callable from VB.
2. Now also ships a GPS.BAS file for use of GPSLIB in VB
PJN / 27-09-2001 1. Fixed a problem where the background serial port thread using causing
heavy CPU utilization.
2. Updated the project settings so that all binaries get build to the Bin
directory and all Lib files get created in a Lib directory
3. Updated the version info's in all the binaries
4. Updated the copyright message in the code modules
PJN / 21-08-2002 1. Fixed a synchronisation problem between the worker thread and the
GpsGetPosition method. Thanks to Bill Oatman for spotting this problem.
Copyright (c) 1997 - 2002 by PJ Naughter. (Web: www.naughter.com, Email: pjna@naughter.com)
All rights reserved.
Copyright / Usage Details:
You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise)
when your product is released in binary form. You are allowed to modify the source code in any way you want
except you cannot modify the copyright details at the top of each module. If you want to distribute source
code with your application, then you are only allowed to distribute versions released by the author. This is
to maintain a single distribution point for the source code.
*/
///////////////////////////////// Includes //////////////////////////////////
#include "stdafx.h"
#include "gps.h"
#include "serport.h"
#include "resource.h"
#include "nmea.h"
#include "math.h"
#include "gpssetup.h"
////////////////////////////////// Macros / Defines //////////////////////////
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif
////////////////////////////////// Locals /////////////////////////////////////
class GPSHandle
{
public:
GPSHandle();
~GPSHandle();
GPSPOSITION m_Position; //the actual data
CEvent* m_pKillEvent; //Event to signal thread to exit
CEvent* m_pStartEvent; //Is the background thread running
GPSDEVINFO m_DevInfo; //Settings of the comms port to use
BOOL m_bRunning; //Is the background thread running
CWinThread* m_pThread; //The pointer to the background thread
CCriticalSection m_csPosition; //Critical section used to serialized access to m_Position
};
BOOL GetGpsDevice(DWORD dwDevice, LPGPSDEVINFO lpGpsDevInfo);
BOOL SetGpsDevice(DWORD dwDevice, LPCGPSDEVINFO lpGpsDevInfo, BOOL bCheckDefault = TRUE);
BOOL SetGpsNumDevices(DWORD dwDevices);
UINT GpsMonitorThead(LPVOID pParam);
////////////////////////////////// Implementation /////////////////////////////
GPSHandle::GPSHandle()
{
ZeroMemory(&m_Position, sizeof(GPSPOSITION));
m_pKillEvent = new CEvent(FALSE, TRUE);
m_pStartEvent = new CEvent(FALSE, TRUE);
m_pThread = NULL;
}
GPSHandle::~GPSHandle()
{
delete m_pStartEvent;
m_pStartEvent = NULL;
delete m_pKillEvent;
m_pKillEvent = NULL;
}
BOOL GetGpsDevice(DWORD dwDevice, LPGPSDEVINFO lpGpsDevInfo)
{
BOOL bSuccess = FALSE;
HKEY hKey;
CString sValueKey;
sValueKey.Format(_T("SOFTWARE\\PJ Naughter\\GPS32\\%d"), dwDevice);
LONG nError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sValueKey, 0, KEY_ALL_ACCESS, &hKey);
if (nError == ERROR_SUCCESS)
{
DWORD dwType;
DWORD dwSize;
RegQueryValueEx(hKey, _T("DeviceName"), 0, &dwType, NULL, &dwSize);
TCHAR* pszName = new TCHAR[dwSize / sizeof(TCHAR)];
RegQueryValueEx(hKey, _T("DeviceName"), 0, &dwType, (LPBYTE) pszName, &dwSize);
_tcscpy(lpGpsDevInfo->szDeviceName, pszName);
delete [] pszName;
RegQueryValueEx(hKey, _T("DefaultReceiver"), 0, &dwType, (LPBYTE) &lpGpsDevInfo->bDefaultReceiver, &dwSize);
RegQueryValueEx(hKey, _T("Port"), 0, &dwType, (LPBYTE) &lpGpsDevInfo->wCommPort, &dwSize);
RegQueryValueEx(hKey, _T("BaudRate"), 0, &dwType, (LPBYTE) &lpGpsDevInfo->dwCommBaudRate, &dwSize);
RegQueryValueEx(hKey, _T("DataBits"), 0, &dwType, (LPBYTE) &lpGpsDevInfo->wCommDataBits, &dwSize);
RegQueryValueEx(hKey, _T("StopBits"), 0, &dwType, (LPBYTE) &lpGpsDevInfo->wCommStopBits, &dwSize);
bSuccess = TRUE;
RegCloseKey(hKey);
}
else
{
TRACE(_T("GetGpsDevice, Failed to open a registry key, Error was: %d\n"), nError);
}
return bSuccess;
}
BOOL GpsSetNumDevices(DWORD dwDevices)
{
BOOL bSuccess = FALSE;
HKEY hKey;
DWORD dwDisposition;
LONG nError = RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\PJ Naughter\\GPS32"), 0, _T(""),
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
if (nError == ERROR_SUCCESS)
{
RegSetValueEx(hKey, _T("NumberOfDevices"), 0, REG_DWORD, (CONST BYTE*) &dwDevices, sizeof(DWORD));
RegCloseKey(hKey);
bSuccess = TRUE;
}
else
{
TRACE(_T("GpsSetNumDevices, Failed in call to create a registry key, Error was: %d\n"), nError);
}
return bSuccess;
}
BOOL SetGpsDevice(DWORD dwDevice, LPCGPSDEVINFO lpDevice, BOOL bCheckDefault)
{
//Fix up the case where we have just made this device
//the default by removing the default flag from all
//other devices
if (bCheckDefault && lpDevice->bDefaultReceiver)
{
//make all other devices non default
for (DWORD i=0; i<GpsGetNumDevices(); i++)
{
GPSDEVINFO devInfo;
GetGpsDevice(i, &devInfo);
devInfo.bDefaultReceiver = FALSE;
SetGpsDevice(i, &devInfo, FALSE);
}
}
BOOL bSuccess = FALSE;
HKEY hKey;
DWORD dwDisposition;
CString sValueKey;
sValueKey.Format(_T("SOFTWARE\\PJ Naughter\\GPS32\\%d"), dwDevice);
LONG nError = RegCreateKeyEx(HKEY_LOCAL_MACHINE, sValueKey, 0, _T(""), REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
if (nError == ERROR_SUCCESS)
{
RegSetValueEx(hKey, _T("DeviceName"), 0, REG_SZ, (CONST BYTE*) lpDevice->szDeviceName, _tcslen(lpDevice->szDeviceName));
RegSetValueEx(hKey, _T("DefaultReceiver"), 0, REG_DWORD, (CONST BYTE*) &lpDevice->bDefaultReceiver, sizeof(BOOL));
DWORD dwData = lpDevice->wCommPort;
RegSetValueEx(hKey, _T("Port"), 0, REG_DWORD, (CONST BYTE*) &dwData, sizeof(DWORD));
RegSetValueEx(hKey, _T("BaudRate"), 0, REG_DWORD, (CONST BYTE*) &lpDevice->dwCommBaudRate, sizeof(DWORD));
dwData = lpDevice->wCommDataBits;
RegSetValueEx(hKey, _T("DataBits"), 0, REG_DWORD, (CONST BYTE*) &dwData, sizeof(DWORD));
dwData = lpDevice->wCommStopBits;
RegSetValueEx(hKey, _T("StopBits"), 0, REG_DWORD, (CONST BYTE*) &dwData, sizeof(DWORD));
RegCloseKey(hKey);
bSuccess = TRUE;
}
else
{
TRACE(_T("SetGPSDevice, Failed in call to create a registry key, Error was: %d\n"), nError);
}
//make sure that at least one device is default
if (bCheckDefault && !lpDevice->bDefaultReceiver)
{
DWORD dwDevices = GpsGetNumDevices();
GPSDEVINFO* pGpsDevInfo = new GPSDEVINFO[dwDevices];
dwDevices = GpsEnumDevices(pGpsDevInfo, dwDevices);
BOOL bFound = FALSE;
for (DWORD i=0; i<dwDevices && !bFound; i++)
{
if (pGpsDevInfo[i].bDefaultReceiver)
bFound = TRUE;
}
delete [] pGpsDevInfo;
if (!bFound)
{
TRACE(_T("SetGpsDevice, Found no device with default receiver attribute\n"));
TRACE(_T(" making first device the default\n"));
GPSDEVINFO devInfo;
GetGpsDevice(0, &devInfo);
devInfo.bDefaultReceiver = TRUE;
SetGpsDevice(0, &devInfo, FALSE);
}
}
return bSuccess;
}
BOOL WINAPI GpsSetDevice(LPCTSTR lpszEntry, LPCGPSDEVINFO lpGpsDevInfo)
{
//Find the device with the corresponding entry name
DWORD dwDevices = GpsGetNumDevices();
GPSDEVINFO* pGpsDevInfo = new GPSDEVINFO[dwDevices];
dwDevices = GpsEnumDevices(pGpsDevInfo, dwDevices);
BOOL bFound = FALSE;
for (DWORD i=0; i<dwDevices && !bFound; i++)
{
if (_tcsicmp(lpszEntry, pGpsDevInfo[i].szDeviceName) == 0)
bFound = TRUE;
}
delete [] pGpsDevInfo;
if (!bFound)
{
TRACE(_T("GpsSetDevice, Failed to find GpsEntry for %s\n"), lpszEntry);
return FALSE;
}
return SetGpsDevice(i-1, lpGpsDevInfo);
}
BOOL WINAPI GpsShowControlPanel()
{
#ifdef _DEBUG
#ifdef _UNICODE
UINT nExec = ::WinExec("GPS103UD.EXE", SW_SHOW);
#else
UINT nExec = ::WinExec("GPS103D.EXE", SW_SHOW);
#endif
#else
#ifdef _UNICODE
UINT nExec = ::WinExec("GPS103U.EXE", SW_SHOW);
#else
UINT nExec = ::WinExec("GPS103.EXE", SW_SHOW);
#endif
#endif
if (nExec <= 31)
TRACE(_T("GpsShowControlPanel, Failed in call to WinExec GPS executable, WinExec returns: %d"), nExec);
return (nExec > 31);
}
BOOL WINAPI GpsCreateEntry(HWND hWnd)
{
BOOL bSuccess = FALSE;
CWnd* pParent = CWnd::FromHandle(hWnd);
CInstallPropertySheet propSheet(IDS_GPS_SETUP, pParent);
propSheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;
int nResponse = propSheet.DoModal();
if (nResponse == ID_WIZFINISH)
{
DWORD dwDevices = GpsGetNumDevices();
GPSDEVINFO GpsInfo;
_tcscpy(GpsInfo.szDeviceName, propSheet.m_Page3.m_sName);
GpsInfo.bDefaultReceiver = (propSheet.m_Page3.m_nMakeDefault == 0);
GpsInfo.wCommPort = (WORD) propSheet.m_Page2.m_dwPort;
GpsInfo.dwCommBaudRate = propSheet.m_Page2.m_dwBaudRate;
GpsInfo.wCommDataBits = 8;
GpsInfo.wCommParity = GpsParityNone;
GpsInfo.wCommStopBits = GpsStopBits1;
bSuccess = SetGpsDevice(dwDevices, &GpsInfo);
//increment the number of devices parameter
GpsSetNumDevices(dwDevices + 1);
}
return bSuccess;
}
DWORD WINAPI GpsGetNumDevices()
{
DWORD dwDevices = 0;
DWORD dwType;
DWORD dwSize = sizeof(DWORD);
HKEY hKey;
LONG nError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\PJ Naughter\\GPS32"),
0, KEY_ALL_ACCESS, &hKey);
if (nError == ERROR_SUCCESS)
{
RegQueryValueEx(hKey, _T("NumberOfDevices"), 0, &dwType, (LPBYTE) &dwDevices, &dwSize);
RegCloseKey(hKey);
}
else
{
TRACE(_T("GpsGetNumDevices, Failed in call to open the registry, Error was: %d\n"), nError);
}
return dwDevices;
}
DWORD WINAPI GpsEnumDevices(LPGPSDEVINFO lpRasDevInfo, DWORD dwRequestedDevices)
{
DWORD dwDevicesToRetreive = min(GpsGetNumDevices(), dwRequestedDevices);
for (DWORD i=0; i<dwDevicesToRetreive; i++)
GetGpsDevice(i, &lpRasDevInfo[i]);
return dwDevicesToRetreive;
}
BOOL WINAPI GpsDeleteEntry(LPCTSTR lpszEntry)
{
//Find the device with the corresponding entry name
DWORD dwDevices = GpsGetNumDevices();
GPSDEVINFO* pGpsDevInfo = new GPSDEVINFO[dwDevices];
dwDevices = GpsEnumDevices(pGpsDevInfo, dwDevices);
for (DWORD i=0; i<dwDevices && !bFound; i++)
{
if (_tcsicmp(lpszEntry, pGpsDevInfo[i].szDeviceName) == 0)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -