コード例 #1
0
BOOL CSIPropertyPage::PageProc(HWND /*hwnd*/, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
	// Catch events and handle
	switch (uMessage)
	{
	case WM_INITDIALOG:
	{
		InitWorkfileView();
		return TRUE;
	}
	case WM_NOTIFY:
	{
		LPNMHDR point = (LPNMHDR)lParam;
		int code = point->code;

		// Respond to tooltip notification
		if (code == LVN_GETINFOTIP) {

			LPNMLVGETINFOTIP pGetInfoTip = (LPNMLVGETINFOTIP)lParam;

			if (pGetInfoTip != NULL)
			{
				std::wstring buffer;

				// Ensure buffer is the correct size
				buffer.resize(pGetInfoTip->cchTextMax);

				// Retrieve the property value that will appear in the tool tip
				ListView_GetItemText(m_list, pGetInfoTip->iItem, 1, &buffer[0], buffer.size());

				// Copy the value into the buffer
				wcsncpy(pGetInfoTip->pszText, buffer.c_str(), buffer.length());
			}
		}
		else if (code == LVN_COLUMNCLICK) 
		{
			// Respond to column click for sorting
			OnColumnClick((LPNMLISTVIEW)lParam);
		}

		return TRUE;
	}
	case WM_DESTROY:
		return TRUE;
	}

	return FALSE;
}
コード例 #2
0
void CGameListCtrl::Update()
{
	int scrollPos = wxWindow::GetScrollPos(wxVERTICAL);
	// Don't let the user refresh it while a game is running
	if (Core::GetState() != Core::CORE_UNINITIALIZED)
		return;

	if (m_imageListSmall)
	{
		delete m_imageListSmall;
		m_imageListSmall = NULL;
	}

	// NetPlay : Set/Reset the GameList string
	m_gameList.clear();
	m_gamePath.clear();

	Hide();

	ScanForISOs();

	ClearAll();

	if (m_ISOFiles.size() != 0)
	{
		// Don't load bitmaps unless there are games to list
		InitBitmaps();

		// add columns
		InsertColumn(COLUMN_DUMMY,_T(""));
		InsertColumn(COLUMN_PLATFORM, _T(""));
		InsertColumn(COLUMN_BANNER, _("Banner"));
		InsertColumn(COLUMN_TITLE, _("Title"));

		// Instead of showing the notes + the company, which is unknown with
		// wii titles We show in the same column : company for GC games and
		// description for wii/wad games
		InsertColumn(COLUMN_NOTES, _("Notes"));
		InsertColumn(COLUMN_COUNTRY, _T(""));
		InsertColumn(COLUMN_SIZE, _("Size"));
		InsertColumn(COLUMN_EMULATION_STATE, _("State"));

#ifdef __WXMSW__
		const int platform_padding = 0;
#else
		const int platform_padding = 8;
#endif
		
		// set initial sizes for columns
		SetColumnWidth(COLUMN_DUMMY,0);
		SetColumnWidth(COLUMN_PLATFORM, 35 + platform_padding);
		SetColumnWidth(COLUMN_BANNER, 96 + platform_padding);
		SetColumnWidth(COLUMN_TITLE, 200 + platform_padding);
		SetColumnWidth(COLUMN_NOTES, 200 + platform_padding);
		SetColumnWidth(COLUMN_COUNTRY, 32 + platform_padding);
		SetColumnWidth(COLUMN_EMULATION_STATE, 50 + platform_padding);

		// add all items
		for (int i = 0; i < (int)m_ISOFiles.size(); i++)
		{
			InsertItemInReportView(i);
			if (m_ISOFiles[i]->IsCompressed())
				SetItemTextColour(i, wxColour(0xFF0000));
		}

		// Sort items by Title
		if (!sorted)
			last_column = 0;
		sorted = false;
		wxListEvent event;
		event.m_col = SConfig::GetInstance().m_ListSort2;
		OnColumnClick(event);

		event.m_col = SConfig::GetInstance().m_ListSort;
		OnColumnClick(event);
		sorted = true;

		SetColumnWidth(COLUMN_SIZE, wxLIST_AUTOSIZE);
	}
	else
	{
		wxString errorString;
		// We just check for one hide setting to be enabled, as we may only
		// have GC games for example, and hide them, so we should show the
		// second message instead
		if ((SConfig::GetInstance().m_ListGC  &&
			SConfig::GetInstance().m_ListWii  &&
			SConfig::GetInstance().m_ListWad) &&
			(SConfig::GetInstance().m_ListJap &&
			SConfig::GetInstance().m_ListUsa  &&
			SConfig::GetInstance().m_ListPal))
		{
			errorString = _("Dolphin could not find any GC/Wii ISOs.  Doubleclick here to browse for files...");
		}
		else
		{
			errorString = _("Dolphin is currently set to hide all games.  Doubleclick here to show all games...");
		}
		InsertColumn(0, _("No ISOs or WADS found"));
		long index = InsertItem(0, errorString);
		SetItemFont(index, *wxITALIC_FONT);
		SetColumnWidth(0, wxLIST_AUTOSIZE);
	}
	if (GetSelectedISO() == NULL)
		main_frame->UpdateGUI();
	Show();

	AutomaticColumnWidth();
	ScrollLines(scrollPos);
	SetFocus();
}
コード例 #3
0
ファイル: GameListCtrl.cpp プロジェクト: LordNed/dolphin
void CGameListCtrl::Update()
{
	int scrollPos = wxWindow::GetScrollPos(wxVERTICAL);
	// Don't let the user refresh it while a game is running
	if (Core::GetState() != Core::CORE_UNINITIALIZED)
		return;

	if (m_imageListSmall)
	{
		delete m_imageListSmall;
		m_imageListSmall = nullptr;
	}

	Hide();

	ScanForISOs();

	ClearAll();

	if (m_ISOFiles.size() != 0)
	{
		// Don't load bitmaps unless there are games to list
		InitBitmaps();

		// add columns
		InsertColumn(COLUMN_DUMMY, "");
		InsertColumn(COLUMN_PLATFORM, "");
		InsertColumn(COLUMN_BANNER, _("Banner"));
		InsertColumn(COLUMN_TITLE, _("Title"));

		InsertColumn(COLUMN_MAKER, _("Maker"));
		InsertColumn(COLUMN_FILENAME, _("File"));
		InsertColumn(COLUMN_ID, _("ID"));
		InsertColumn(COLUMN_COUNTRY, "");
		InsertColumn(COLUMN_SIZE, _("Size"));
		InsertColumn(COLUMN_EMULATION_STATE, _("State"));

#ifdef __WXMSW__
		const int platform_padding = 0;
#else
		const int platform_padding = 8;
#endif

		const int platform_icon_padding = 1;

		// set initial sizes for columns
		SetColumnWidth(COLUMN_DUMMY, 0);
		SetColumnWidth(COLUMN_PLATFORM, SConfig::GetInstance().m_showSystemColumn ? 32 + platform_icon_padding + platform_padding : 0);
		SetColumnWidth(COLUMN_BANNER, SConfig::GetInstance().m_showBannerColumn ? 96 + platform_padding : 0);
		SetColumnWidth(COLUMN_TITLE, 175 + platform_padding);
		SetColumnWidth(COLUMN_MAKER, SConfig::GetInstance().m_showMakerColumn ? 150 + platform_padding : 0);
		SetColumnWidth(COLUMN_FILENAME, SConfig::GetInstance().m_showFileNameColumn ? 100 + platform_padding : 0);
		SetColumnWidth(COLUMN_ID, SConfig::GetInstance().m_showIDColumn ? 75 + platform_padding : 0);
		SetColumnWidth(COLUMN_COUNTRY, SConfig::GetInstance().m_showRegionColumn ? 32 + platform_padding : 0);
		SetColumnWidth(COLUMN_EMULATION_STATE, SConfig::GetInstance().m_showStateColumn ? 48 + platform_padding : 0);

		// add all items
		for (int i = 0; i < (int)m_ISOFiles.size(); i++)
		{
			InsertItemInReportView(i);
			if (SConfig::GetInstance().m_ColorCompressed && m_ISOFiles[i]->IsCompressed())
				SetItemTextColour(i, wxColour(0xFF0000));
		}

		// Sort items by Title
		if (!sorted)
			last_column = 0;
		sorted = false;
		wxListEvent event;
		event.m_col = SConfig::GetInstance().m_ListSort2;
		OnColumnClick(event);

		event.m_col = SConfig::GetInstance().m_ListSort;
		OnColumnClick(event);
		sorted = true;

		SetColumnWidth(COLUMN_SIZE, SConfig::GetInstance().m_showSizeColumn ? wxLIST_AUTOSIZE : 0);
	}
	else
	{
		wxString errorString;
		// We just check for one hide setting to be enabled, as we may only
		// have GC games for example, and hide them, so we should show the
		// first message instead
		if (IsHidingItems())
		{
			errorString = _("Dolphin is currently set to hide all games. Double-click here to show all games...");
		}
		else
		{
			errorString = _("Dolphin could not find any GameCube/Wii ISOs or WADs. Double-click here to set a games directory...");
		}
		InsertColumn(0, "");
		long index = InsertItem(0, errorString);
		SetItemFont(index, *wxITALIC_FONT);
		SetColumnWidth(0, wxLIST_AUTOSIZE);
	}
	if (GetSelectedISO() == nullptr)
		main_frame->UpdateGUI();
	Show();

	AutomaticColumnWidth();
	ScrollLines(scrollPos);
	SetFocus();
}
コード例 #4
0
LRESULT RegisteredUsersDialog::RegisteredUsersDialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch(uMsg) {
        case WM_WINDOWPOSCHANGED: {
            RECT rcParent;
            ::GetClientRect(m_hWndWindowItems[WINDOW_HANDLE], &rcParent);

            ::SetWindowPos(m_hWndWindowItems[CB_FILTER], nullptr, (rcParent.right / 2)+3, (rcParent.bottom - GuiSettingManager::m_iOneLineGB - 3) + GuiSettingManager::m_iGroupBoxMargin,
                rcParent.right - (rcParent.right/2) - 14, GuiSettingManager::m_iEditHeight, SWP_NOZORDER);
            ::SetWindowPos(m_hWndWindowItems[EDT_FILTER], nullptr, 11, (rcParent.bottom - GuiSettingManager::m_iOneLineGB - 3) + GuiSettingManager::m_iGroupBoxMargin, (rcParent.right / 2) - 14, GuiSettingManager::m_iEditHeight, SWP_NOZORDER);
            ::SetWindowPos(m_hWndWindowItems[GB_FILTER], nullptr, 3, rcParent.bottom - GuiSettingManager::m_iOneLineGB - 3, rcParent.right - 6, GuiSettingManager::m_iOneLineGB, SWP_NOZORDER);
            ::SetWindowPos(m_hWndWindowItems[LV_REGS], nullptr, 0, 0, rcParent.right - 6, rcParent.bottom - GuiSettingManager::m_iOneLineGB - GuiSettingManager::m_iEditHeight - 11, SWP_NOMOVE | SWP_NOZORDER);
            ::SetWindowPos(m_hWndWindowItems[BTN_ADD_REG], nullptr, 0, 0, rcParent.right - 4, GuiSettingManager::m_iEditHeight, SWP_NOMOVE | SWP_NOZORDER);

            return 0;
        }
        case WM_COMMAND:
            switch(LOWORD(wParam)) {
                case (BTN_ADD_REG+100): {
                    RegisteredUserDialog::m_Ptr = new (std::nothrow) RegisteredUserDialog();

                    if(RegisteredUserDialog::m_Ptr != nullptr) {
                        RegisteredUserDialog::m_Ptr->DoModal(m_hWndWindowItems[WINDOW_HANDLE]);
                    }

                    return 0;
                }
                case IDC_CHANGE_REG: {
                    ChangeReg();
                    return 0;
                }
                case IDC_REMOVE_REGS:
                    RemoveRegs();
                    return 0;
                case CB_FILTER:
                    if(HIWORD(wParam) == CBN_SELCHANGE) {
                        if(::GetWindowTextLength(m_hWndWindowItems[EDT_FILTER]) != 0) {
                            FilterRegs();
                        }
                    }

                    break;
                case IDOK: { // NM_RETURN
                    HWND hWndFocus = ::GetFocus();

                    if(hWndFocus == m_hWndWindowItems[LV_REGS]) {
                        ChangeReg();
                        return 0;
                    } else if(hWndFocus == m_hWndWindowItems[EDT_FILTER]) {
                        FilterRegs();
                        return 0;
                    }

                    break;
                }
                case IDCANCEL:
                    ::PostMessage(m_hWndWindowItems[WINDOW_HANDLE], WM_CLOSE, 0, 0);
					return 0;
            }

            break;
        case WM_CONTEXTMENU:
            OnContextMenu((HWND)wParam, lParam);
            break;
        case WM_NOTIFY:
            if(((LPNMHDR)lParam)->hwndFrom == m_hWndWindowItems[LV_REGS]) {
                if(((LPNMHDR)lParam)->code == LVN_COLUMNCLICK) {
                    OnColumnClick((LPNMLISTVIEW)lParam);
                } else if(((LPNMHDR)lParam)->code == NM_DBLCLK) {
                    if(((LPNMITEMACTIVATE)lParam)->iItem == -1) {
                        break;
                    }

                    RegUser * pReg = reinterpret_cast<RegUser *>(ListViewGetItem(m_hWndWindowItems[LV_REGS],  ((LPNMITEMACTIVATE)lParam)->iItem));

                    RegisteredUserDialog::m_Ptr = new (std::nothrow) RegisteredUserDialog();

                    if(RegisteredUserDialog::m_Ptr != nullptr) {
                        RegisteredUserDialog::m_Ptr->DoModal(m_hWndWindowItems[WINDOW_HANDLE], pReg);
                    }

                    return 0;
                }
            }

            break;
        case WM_GETMINMAXINFO: {
            MINMAXINFO *mminfo = (MINMAXINFO*)lParam;
            mminfo->ptMinTrackSize.x = ScaleGui(GuiSettingManager::m_Ptr->GetDefaultInteger(GUISETINT_REGS_WINDOW_WIDTH));
            mminfo->ptMinTrackSize.y = ScaleGui(GuiSettingManager::m_Ptr->GetDefaultInteger(GUISETINT_REGS_WINDOW_HEIGHT));

            return 0;
        }
        case WM_CLOSE: {
            RECT rcRegs;
            ::GetWindowRect(m_hWndWindowItems[WINDOW_HANDLE], &rcRegs);

            GuiSettingManager::m_Ptr->SetInteger(GUISETINT_REGS_WINDOW_WIDTH, rcRegs.right - rcRegs.left);
            GuiSettingManager::m_Ptr->SetInteger(GUISETINT_REGS_WINDOW_HEIGHT, rcRegs.bottom - rcRegs.top);

            GuiSettingManager::m_Ptr->SetInteger(GUISETINT_REGS_NICK, (int)::SendMessage(m_hWndWindowItems[LV_REGS], LVM_GETCOLUMNWIDTH, 0, 0));
            GuiSettingManager::m_Ptr->SetInteger(GUISETINT_REGS_PASSWORD, (int)::SendMessage(m_hWndWindowItems[LV_REGS], LVM_GETCOLUMNWIDTH, 1, 0));
            GuiSettingManager::m_Ptr->SetInteger(GUISETINT_REGS_PROFILE, (int)::SendMessage(m_hWndWindowItems[LV_REGS], LVM_GETCOLUMNWIDTH, 2, 0));

            ::EnableWindow(::GetParent(m_hWndWindowItems[WINDOW_HANDLE]), TRUE);
            ServerManager::m_hWndActiveDialog = nullptr;

            break;
        }
        case WM_NCDESTROY: {
            HWND hWnd = m_hWndWindowItems[WINDOW_HANDLE];
            delete this;
            return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
        }
        case WM_SETFOCUS:
            if((UINT)::SendMessage(m_hWndWindowItems[LV_REGS], LVM_GETSELECTEDCOUNT, 0, 0) != 0) {
                ::SetFocus(m_hWndWindowItems[LV_REGS]);
            } else {
                ::SetFocus(m_hWndWindowItems[EDT_FILTER]);
            }

            return 0;
        case WM_ACTIVATE:
            if(LOWORD(wParam) != WA_INACTIVE) {
                ServerManager::m_hWndActiveDialog = m_hWndWindowItems[WINDOW_HANDLE];
            }

            break;
    }

	return ::DefWindowProc(m_hWndWindowItems[WINDOW_HANDLE], uMsg, wParam, lParam);
}
コード例 #5
0
ファイル: TinyListView.cpp プロジェクト: 91yuan/TinyUI
	void TinyListView::LvnColumnClick(INT iSubItem)
	{
		OnColumnClick(iSubItem);
	}
コード例 #6
0
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;
}