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

📄 dmtp.cpp

📁 Open DMT Client C Source code
💻 CPP
字号:
// ----------------------------------------------------------------------------
// Copyright 2006-2007, Martin D. Flynn
// All rights reserved
// ----------------------------------------------------------------------------
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ----------------------------------------------------------------------------
// Change History:
//  2007/01/28  Martin D. Flynn
//     -Initial release
// ----------------------------------------------------------------------------

#include "stdafx.h"
#include "custom/defaults.h"

#include <aygshell.h>
#include <windows.h>
#include <windowsx.h>

#include "custom/gps.h"
#include "tools/strtools.h"
#include "tools/utctools.h"
#include "base/propman.h"
#include "base/events.h"

#include "DMTP.h"

// ----------------------------------------------------------------------------

#define MAX_LOADSTRING  100
#define ID_EDIT         1000
#define MENU_HEIGHT     26

// ----------------------------------------------------------------------------

// Global Variables:
static HINSTANCE        hInst = 0;			// The current instance
static HWND             hwndListBox = 0;
static HWND             hwndMain = 0;

// ----------------------------------------------------------------------------

// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void ShowStatusInfo(HWND hwnd);

int startupDMTP(int argc, char *argv[], int runInThread);

// ----------------------------------------------------------------------------

#define MAX_ARGC    30

int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPTSTR    lpCmdLine,
    int       nCmdShow)
{

    /* parse command line */
    char *argv[MAX_ARGC], *wceCmdLine = (char*)lpCmdLine, wceLineStr[512];
    int argc = 0, wceLineLen = 0;
    argv[argc++] = APPLICATION_NAME;
    for (; *wceCmdLine && (wceLineLen < (sizeof(wceLineStr) - 1));) {
        while (*wceCmdLine == ' ') { wceCmdLine += 2; } // skip prefixing spaces
        if (!*wceCmdLine) { break; } // end of line
        if (argc >= MAX_ARGC) { break; } // maximum args
        argv[argc++] = &wceLineStr[wceLineLen]; // next arg
        for (; *wceCmdLine && (wceLineLen < (sizeof(wceLineStr) - 1));) {
            if (*wceCmdLine == '\\') { // literal
                wceCmdLine += 2;  // wide characters
            } else
            if (*wceCmdLine == ' ') {
                break; // end of argument
            }
            if (*wceCmdLine) {
                wceLineStr[wceLineLen++] = *wceCmdLine;
                wceCmdLine += 2; // wide characters
            }
        }
        wceLineStr[wceLineLen++] = 0;
    }

    /* start DMTP */
    if (startupDMTP(argc,argv,TRUE) != 0) {
        return FALSE;
    }

	/* Perform application initialization */
	if (!InitInstance(hInstance, nCmdShow)) {
		return FALSE;
	}
	
	/* Main message loop */
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
	}
	
	return msg.wParam;
}

// Register the window class.
// COMMENTS:
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
	WNDCLASS	wc;
	wc.style			= CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc		= (WNDPROC) WndProc;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hInstance		= hInstance;
	wc.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_OPENDMTP));
	wc.hCursor			= 0;
	wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName		= 0;
	wc.lpszClassName	= szWindowClass;
	return RegisterClass(&wc);
}

// Save instance handle and creates main window
// COMMENTS:
//    In this function, we save the instance handle in a global variable and
//    create and display the main program window.
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	
    // Store instance handle in our global variable
	hInst = hInstance;		
    
	/* Window class */
	TCHAR szWindowClass[MAX_LOADSTRING];		// The window class name
	LoadString(hInstance, IDC_OPENDMTP, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance, szWindowClass);
	
    /* app title */
	TCHAR szTitle[MAX_LOADSTRING];			// The title bar text
    const char *version = "OpenDMTP " RELEASE_VERSION; // propGetString(PROP_STATE_FIRMWARE, "OpenDMTP");
    strWideCopy(szTitle, MAX_LOADSTRING, version, -1);
	//LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

	//If it is already running, then focus on the window
	HWND hExistingWnd = FindWindow(szWindowClass, szTitle);	
	if (hExistingWnd) {
		// set focus to foremost child window
		// The "| 0x01" is used to bring any owned windows to the foreground and
		// activate them.
        ShowStatusInfo(hwndListBox);
		SetForegroundWindow((HWND)((ULONG)hExistingWnd | 0x00000001));
        UpdateWindow(hExistingWnd);
		return 0;
	} 

	////////// Setting default main window size
	// This technique allows for you to create the main
	// window to allow for the postion of a menubar and/or
	// the SIP button at the bottom of the screen
	
	//Set default window creation sizd info
	SIPINFO si = {0};
	si.cbSize = sizeof(si);
	SHSipInfo(SPI_GETSIPINFO, 0, &si, 0);
	//Consider the menu at the bottom, please.
	int x = CW_USEDEFAULT, y = CW_USEDEFAULT;
	int iDelta = (si.fdwFlags & SIPF_ON) ? 0 : MENU_HEIGHT;
	int cx = si.rcVisibleDesktop.right - si.rcVisibleDesktop.left;
	int cy = si.rcVisibleDesktop.bottom - si.rcVisibleDesktop.top - iDelta;
	hwndMain = CreateWindow(szWindowClass, szTitle, WS_VISIBLE ,
		x, y, cx, cy, NULL, NULL, hInstance, NULL);
	if (!hwndMain) {	
		return FALSE;
	}
	
    /* show window */
	ShowWindow(hwndMain, nCmdShow);
	UpdateWindow(hwndMain);
	
	return TRUE;
}

// Processe messages for the main window.
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	RECT rc;
	
	switch (message) {
        
		case WM_CREATE: 
			//Create a MenuBar
			SHMENUBARINFO mbi;
			memset(&mbi, 0, sizeof(SHMENUBARINFO));
			mbi.cbSize     = sizeof(SHMENUBARINFO);
			mbi.hwndParent = hWnd;
			mbi.nToolBarId = IDM_MAIN_MENU;
			mbi.hInstRes   = hInst;
			mbi.nBmpId     = 0;
			mbi.cBmpImages = 0;	
			SHCreateMenuBar(&mbi);
			if (!SHCreateMenuBar(&mbi))  {
				MessageBox(hWnd, L"SHCreateMenuBar Failed", L"Error", MB_OK);
			}
			//Create Edit control
			GetClientRect(hWnd, &rc);
			hwndListBox = CreateWindow(_T("listbox") , NULL, WS_CHILD | WS_VSCROLL | WS_HSCROLL, 
			rc.left, rc.top, rc.right, rc.bottom , 
			hWnd, (HMENU)ID_EDIT, hInst, NULL);
			if (hwndListBox){
				ShowStatusInfo(hwndListBox);
				ShowWindow(hwndListBox, SW_SHOW);
				UpdateWindow(hWnd);
			}
            break;
			
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
            
		case WM_COMMAND:
			if (LOWORD(wParam) == IDM_ITEM_QUIT) {
				DestroyWindow(hWnd);
			} else
			if (LOWORD(wParam) == IDM_ITEM_REFRESH) {
				ShowStatusInfo(hwndListBox);
				UpdateWindow(hWnd);
			}
			break;
            
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
            
	}
    
	return 0;
}

// ----------------------------------------------------------------------------

static TCHAR *DIRECTION[] = { L"N", L"NE", L"E", L"SE", L"S", L"SW", L"W", L"NW" };

void ShowStatusInfo(HWND hwnd) 
{
    YMDHMS_t yh;
	TCHAR szbufW[MAX_PATH];

    if (!hwnd) {
        return;
    }
    
    /* need to clear what's here */
    SendMessage(hwnd, LB_RESETCONTENT, 0L, 0L);

    /* header */
    wsprintf(szbufW, _T("OpenDMTP Status:"));
    SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)szbufW);

    /* blank line */
    wsprintf(szbufW, _T(" "));
    SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)szbufW);

    /* aquire latest GPS */
    GPS_t gps;
    gpsAquire(&gps, 0L);
    utBool hasGPS = ((gps.point.latitude != 0.0) || (gps.point.longitude != 0.0))? utTrue : utFalse;
    
    /* last fix time */
    if (gps.fixtime > 0L) {
        TIME_ZONE_INFORMATION tz;
        memset(&tz, 0, sizeof(tz));
        DWORD rtn = GetTimeZoneInformation(&tz);
        UInt32 bias = tz.Bias + ((rtn == TIME_ZONE_ID_DAYLIGHT)? tz.DaylightBias : tz.StandardBias);
        UInt32 fixtime = gps.fixtime - (bias * 60L);
        WCHAR *tzName = (rtn == TIME_ZONE_ID_DAYLIGHT)? tz.DaylightName : tz.StandardName;
        utcSecondsToYmdHms(&yh, fixtime);
        wsprintf(szbufW, _T("FixTime:  %02d/%02d/%02d %02d:%02d:%02d"), 
            yh.wYear, yh.wMonth , yh.wDay,
            yh.wHour, yh.wMinute, yh.wSecond);
    } else {
        wsprintf(szbufW, _T("FixTime:  n/a"));
    }
    SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)szbufW);
    
    /* latitude/longitude */
    if (hasGPS) {
        wsprintf(szbufW, _T("Lat/Lon:  %.4lf / %.4lf"), gps.point.latitude, gps.point.longitude);
    } else {
        wsprintf(szbufW, _T("Lat/Lon:  n/a"));
    }
    SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)szbufW);

    /* speed/heading */
    if (hasGPS) {
        double minKPH = propGetDouble(PROP_GPS_MIN_SPEED, 10.0);
        double mph = (gps.speedKPH >= minKPH)? (gps.speedKPH * MILES_PER_KILOMETER) : 0.0;
        const TCHAR *hd = (mph > 0.0)? DIRECTION[(int)((gps.heading / 45.0) + 0.5) % 8] : L"";
        wsprintf(szbufW, _T("Speed  :  %.1lf mph  %s"), mph, hd);
    } else {
        wsprintf(szbufW, _T("Speed  :  n/a"));
    }
    SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)szbufW);
    
    /* altitude */
    if (hasGPS) {
        double feet = gps.altitude * FEET_PER_METER;
        wsprintf(szbufW, _T("Altitude:  %.0lf ft"), feet);
    } else {
        wsprintf(szbufW, _T("Altitude:  n/a"));
    }
    SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)szbufW);

    /* blank line */
    wsprintf(szbufW, _T(" "));
    SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)szbufW);

    /* GPS diagnostics? */

    /* pending event count */
    Int32 queuedEvents = evGetPacketCount();
    Int32 totalEvents = evGetTotalPacketCount();
    wsprintf(szbufW, _T("Events  :  %ld / %ld"), queuedEvents, totalEvents);
    SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)szbufW);

    /* last connection time */
    
}

⌨️ 快捷键说明

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