bool CSQLiteLapDB::InitRaceSession(int* piRaceId, LPCTSTR lpszRaceName) { bool fSuccess = true; CSfArtSQLiteQuery sfQuery(m_sfDB); if(sfQuery.Init(L"insert into races (name,date) values (?,?)")) { sfQuery.BindValue(lpszRaceName); sfQuery.BindValue(GetSecondsSince1970()); if(sfQuery.Next() || sfQuery.IsDone()) { // inserted new data, hooray! long long lastInsert = m_sfDB.GetLastInsertId(); *piRaceId = lastInsert; return true; } } return false; }
LRESULT CDlgTimingScoring::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static int tmStartRace, tmEndRace; // Variables for setting up receive time / live car position HL_hWnd = GetDlgItem(hWnd,IDC_TIMINGSCORING); // Hot Laps listview TS_hWnd = GetDlgItem(hWnd,IDC_RACESCORING); // Race Timing listview switch(uMsg) { case WM_INITDIALOG: { // Initialize the results array for (int i=0;i<50;i++) { swprintf(m_ScoringData[i].db_strRaceName, NUMCHARS(m_ScoringData[i].db_strRaceName),L""); swprintf(m_ScoringData[i].db_szTotTime, NUMCHARS(m_ScoringData[i].db_szTotTime),L""); } // tmStartRace = NULL; // tmEndRace = NULL; // Set the initial End Race time to NULL // Set up the Hot Lap timing list box vector<wstring> lstCols; vector<int> lstWidths; lstCols.push_back(L"Pos"); lstCols.push_back(L"Name"); lstCols.push_back(L"Comment"); lstCols.push_back(L"Laptime"); lstWidths.push_back(40); lstWidths.push_back(210); lstWidths.push_back(85); lstWidths.push_back(85); // HL_hWnd = GetDlgItem(hWnd,IDC_TIMINGSCORING); // Hot Laps listview sfListBox.Init(HL_hWnd,lstCols,lstWidths); // Now set up the Scoring list box vector<wstring> scoringLstCols; vector<int> scoringLstWidths; scoringLstCols.push_back(L"Pos"); scoringLstCols.push_back(L"Name"); scoringLstCols.push_back(L"Lap/Time Ahead"); scoringLstWidths.push_back(30); scoringLstWidths.push_back(145); scoringLstWidths.push_back(95); sfListBox.Init(TS_hWnd,scoringLstCols,scoringLstWidths); HWND hWnd_Comment = GetDlgItem(hWnd, IDC_RACE_COMMENT); SetDlgItemText(hWnd, IDC_RACE_COMMENT, szTitle); TimingScoringProc((LPVOID)&m_szPath, hWnd); break; } case WM_NOTIFY: { // check for column click notification and sort the list view accordingly if ( ( ((LPNMHDR)lParam)->idFrom == IDC_RACESCORING) && ( ((LPNMHDR)lParam)->code == LVN_COLUMNCLICK) ) { // TS_hWnd = GetDlgItem(hWnd,IDC_RACESCORING); OnColumnClick((LPNMLISTVIEW)lParam, TS_hWnd ); } else if ( ( ((LPNMHDR)lParam)->idFrom == IDC_TIMINGSCORING) && ( ((LPNMHDR)lParam)->code == LVN_COLUMNCLICK) ) { // HL_hWnd = GetDlgItem(hWnd,IDC_TIMINGSCORING); OnColumnClick((LPNMLISTVIEW)lParam, HL_hWnd ); } return TRUE; } case WM_COMMAND: { switch(LOWORD(wParam)) { case IDRESCAN: { TimingScoringProc((LPVOID)&m_szPath, hWnd); if (tmStartRace) { CRaceScoring((LPVOID) &m_szPath, hWnd, tmStartRace, tmEndRace); } m_pResults->fCancelled = false; return TRUE; } case IDCANCEL: { m_pResults->fCancelled = true; for (int i=0;i<50;i++) { m_sfResult->m_RaceId[i] = -1; } EndDialog(hWnd,0); return TRUE; } case IDSTARTRACE: { TCHAR szText[MAX_PATH] = {NULL}; TCHAR szTemp[MAX_PATH] = {NULL}; if (tmEndRace == NULL && tmStartRace != NULL) { MessageBox(hWnd, L"Race already in progress!\n\nYou must end that race before starting a new one", L"***ERROR***", MB_OK); } else { if (tmStartRace > 0) // There is already a time marker stored, verify user wants to change this { DWORD dRet = MessageBox(hWnd, L"You already have a race stored!\n\nAre you sure you want to start a new race?\n\nPrevious race results will be lost if you haven't saved them", L"WARNING", MB_YESNO); if(dRet == IDNO) { // Do nothing m_pResults->fCancelled = true; return TRUE; } } tmEndRace = NULL; // Remove any end of race marker when new race begins. INT format tmStartRace = GetSecondsSince1970(); // Set the start time for this race session. Unixtime in INT format // tmStartRace = 1376100527; // Used for the TestRaces database only // swprintf(szText, NUMCHARS(szText), L"Race Started\n\nTime = %i", tmStartRace); // MessageBox(hWnd, szText, L"Started", MB_OK); MessageBox(hWnd, L"Race started", L"Started", MB_OK); HWND prog_hWnd = GetDlgItem(hWnd, IDC_RACE_PROGRESS); swprintf(szText, NUMCHARS(szText), L"<<<< Race In Progress >>>>"); SendMessage(prog_hWnd, WM_SETTEXT, 0, (LPARAM)szText); } m_pResults->fCancelled = false; return TRUE; } case IDENDRACE: { if (tmStartRace != NULL) { TCHAR szText[MAX_PATH] = {NULL}; TCHAR szTemp[MAX_PATH] = {NULL}; if (tmEndRace > 0) // There is already a time marker stored, verify user wants to change this { DWORD dRet = MessageBox(hWnd, L"You already have a race stored!\n\nAre you sure you want to change the end time for this race?\n\nPrevious race results will be lost if you haven't saved them", L"WARNING", MB_YESNO); if(dRet == IDNO) { // Do nothing m_pResults->fCancelled = true; return TRUE; } } tmEndRace = GetSecondsSince1970(); // Set the end time for this race session. Unixtime in INT format // tmEndRace = 1376100699; // Used for the TestRaces database only // swprintf(szText, NUMCHARS(szText), L"Race End = %i", tmEndRace); // MessageBox(hWnd, szText, L"Ended", MB_OK); HWND prog_hWnd = GetDlgItem(hWnd, IDC_RACE_PROGRESS); swprintf(szText, NUMCHARS(szText), L">>>> Race Ended <<<<"); SendMessage(prog_hWnd, WM_SETTEXT, 0, (LPARAM)szText); ::FormatTimeMinutesSecondsMs((tmEndRace - tmStartRace), szText, NUMCHARS(szText) ); TimingScoringProc((LPVOID)&m_szPath, hWnd); // Refresh the results one last time if (tmStartRace) { CRaceScoring((LPVOID) &m_szPath, hWnd, tmStartRace, tmEndRace); } swprintf(szTemp, NUMCHARS(szTemp), szText); _snwprintf(szText, NUMCHARS(szText), L"Race has ended\n\nRace duration: %s", szTemp); MessageBox(hWnd, szText, L"Ended", MB_OK); } else { MessageBox(hWnd, L"Race scoring has not been started", L"***ERROR***", MB_OK); } m_pResults->fCancelled = false; return TRUE; } case IDC_RACE_RERUN: { // Let's set up for displaying the T&S page int m_RaceId[50] = {NULL}; // Show the race-selection dialog and let the User pick which ones to use on T&S page RACERERUN_RESULT sfResult; if (sfResult.iStart <= 0 || tmStartRace > 0) sfResult.iStart = tmStartRace; if (sfResult.iEnd <= 0 || tmEndRace > 0) sfResult.iEnd = tmEndRace; CRaceRerunDlg dlgRace(&sfResult); ArtShowDialog<IDD_RACE_RERUN>(&dlgRace); if(!sfResult.fCancelled) { // Get the Start and End race markers and store them for race scoring tmStartRace = sfResult.iStart; tmEndRace = sfResult.iEnd; TimingScoringProc((LPVOID)&m_szPath, hWnd); // Refresh the results one last time if (tmStartRace) { CRaceScoring((LPVOID) &m_szPath, hWnd, tmStartRace, tmEndRace); } } return TRUE; } case IDC_RACE_SAVE: { if (tmEndRace == NULL && tmStartRace != NULL) { MessageBox(hWnd, L"Race in progress!\n\nYou must end the race before saving your results", L"***ERROR***", MB_OK); } else if (tmEndRace == NULL && tmStartRace == NULL) { MessageBox(hWnd, L"No race data to save", L"***ERROR***", MB_OK); } else { TCHAR szText[MAX_PATH] = {NULL}; TCHAR szTemp[MAX_PATH] = {NULL}; // Save the results into a text file if(tmEndRace > 0) { // swprintf(szText, NUMCHARS(szText), L"Race Start = %i\n\nRace End = %i", tmStartRace, tmEndRace); // MessageBox(hWnd, szText, L"Saving", MB_OK); TCHAR szFilename[MAX_PATH] = {NULL}; wcscat(szFilename,L"TimingScoring.txt"); while (true) { if(ArtGetSaveFileName(hWnd, L"Choose Output file", szFilename, NUMCHARS(szFilename),L"TXT Files (*.txt)\0*.TXT\0\0")) { // let's make sure there's a .txt suffix on that bugger. if(!str_ends_with(szFilename,L".txt") && !str_ends_with(szFilename,L".TXT") ) { wcsncat(szFilename,L".txt", NUMCHARS(szFilename)); } const bool fFileIsNew = !DoesFileExist(szFilename); if(fFileIsNew) { break; // Exit loop, as file name is valid and new } else { DWORD dwRet = MessageBox(NULL,L"A file already exists with that name.\n\nAre you sure you want to overwrite it?",L"WARNING", MB_APPLMODAL | MB_ICONWARNING | MB_YESNO | MB_TOPMOST | MB_DEFBUTTON2); if (dwRet == IDYES) { break; // User wants to overwrite file, so exit loop and proceed } } } else { return 0; // User cancelled the save operation, so leave subroutine } } // Open up the file and write the information to it wofstream out; out.open(szFilename); // First the race title information HWND hWnd_Comment = GetDlgItem(hWnd, IDC_RACE_COMMENT); int len; len = GetWindowTextLength(hWnd_Comment); GetDlgItemText(hWnd, IDC_RACE_COMMENT, szTitle, len+1); out<<szTitle<<endl<<endl; out<<L"File Name: "<<m_szPath<<endl; // Let's save the start/end markers so the race can be recreated if needed _snwprintf(szText, NUMCHARS(szText), L"Race start marker:\t%i", tmStartRace); out<<szText<<endl; _snwprintf(szText, NUMCHARS(szText), L"Race ending marker:\t%i", tmEndRace); out<<szText<<endl; // Now the race duration ::FormatTimeMinutesSecondsMs((tmEndRace - tmStartRace), szText, NUMCHARS(szText) ); // swprintf(szText, _tcslen(szText) - 2, L"%s", szText); // Remove the fractional time swprintf(szTemp, NUMCHARS(szTemp), szText); _snwprintf(szText, NUMCHARS(szText), L"Race duration:\t%s", szTemp); out<<szText<<endl<<endl; out<<L"ID\tName\t\t\t\t\tLap/Time Ahead"<<endl; out<<L"====================================================================="<<endl; for(int i = 0; i < 25; i++) { if (m_ScoringData[i].db_iRaceId <= 0 || m_ScoringData[i].db_iUnixFirstTime == 0) break; int Temp = m_ScoringData[i].db_iUnixFirstTime + m_ScoringData[i].db_iUnixLastTime; ::FormatTimeMinutesSecondsMs(Temp, szTemp, NUMCHARS(szTemp) ); out << m_ScoringData[i].db_iRaceId << L"\t"; out << m_ScoringData[i].db_strRaceName << L"\t"; out << m_ScoringData[i].db_szTotTime << endl; } out<<endl; // Now let's push out all of the Top 40 Hot Laps to the file out<<endl<<endl; out<<L"\t\tTop 40 Hot Laps"<<endl; out<<L"Pos\tName\t\t\t\t\tComment\tLap Time"<<endl; out<<L"====================================================================="<<endl; for(int i = 0; i < 40; i++) { if (_wtoi(m_ScoringData[i].lstPos) <= 0) break; out << m_ScoringData[i].lstPos << L"\t"; out << m_ScoringData[i].lstRaceName << L"\t"; out << m_ScoringData[i].lstComment << L"\t\t"; out << m_ScoringData[i].lstLapTimes << endl; } out<<endl; out.close(); // Close the file MessageBox(hWnd, L"Race Results Saved", L"Saved", MB_OK); m_pResults->fCancelled = false; return TRUE; } else { swprintf(szText, NUMCHARS(szText), L"Race Start = %i\n\nRace End = %i", tmStartRace, tmEndRace); MessageBox(hWnd, szText, MB_OK, NULL); } } } } break; } // end WM_COMMAND case WM_CLOSE: { m_pResults->fCancelled = true; for (int i=0;i<50;i++) { m_sfResult->m_RaceId[i] = -1; } EndDialog(hWnd,0); break; } } return FALSE; }