MySQL database export (dbexport.h / dbexport.cpp): - New files dbexport.h / dbexport.cpp implement late-bound MySQL export. libmysql.dll is loaded at runtime via LoadLibrary/GetProcAddress so no MySQL SDK is required at compile time; the app runs normally if the DLL is absent. - After each print job, match data is exported to a MySQL server before PrintDlg() is called: one row in 'match', one row per player in 'player_result', one row per attacker/victim pair in 'pvp'. An optional 'event' table records every individual SRecScore entry (off by default). Tables are created automatically (CREATE TABLE IF NOT EXISTS) on first connect. - Config stored in mw4print.ini (app directory), section [MySQLExport]: Enabled, Host, Port, Database, Username, Password, ExportEvents. - Config loaded at startup (OnCreate); DB_LoadConfig() / DB_SaveConfig(). - Connection timeout set to 5 seconds so the app does not hang if the server is unreachable. - libmysql.dll (MySQL Connector/C 32-bit) added to Gameleap/mw4/ so the deploy script copies it to MW4/ alongside mw4print.exe. Database Settings dialog (File > Database Settings... / Ctrl+D): - MFC dialog: enable checkbox, Host/Port/Database/Username/Password fields, Export Events checkbox, Test Connection button with live status label, OK/Cancel. OK persists settings to mw4print.ini immediately. Configurable banner text (File > Banner Setting...): - The 'WWW.MECHJOCK.COM' URL string printed at the bottom of every score sheet is now configurable. Stored as BannerText= in options.ini under [battle tech print] (same section/file as the other print layout params). File > Banner Setting... opens a dialog to edit it; OK saves to options.ini and takes effect on the next print job with no restart needed. Default value is the original MECHJOCK string if the key is absent.
676 lines
18 KiB
C++
676 lines
18 KiB
C++
// ChildView.cpp : implementation of the CChildView class
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "mw4print.h"
|
|
#include "ChildView.h"
|
|
#include "cspcfd.h"
|
|
|
|
#include "MechLabHeaders.h"
|
|
#include "GameTypes.h"
|
|
|
|
#include "mw4dummy.h"
|
|
#include "recscore.h"
|
|
#include "dbexport.h"
|
|
typedef unsigned long UINT4;
|
|
typedef unsigned char* POINTER;
|
|
#include "logreport.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#include "mw4dummy.cpp"
|
|
#include "recscore.cpp"
|
|
#include "dbexport.cpp"
|
|
#include "logreport.cpp"
|
|
|
|
#define IDT_TIMER 1000
|
|
|
|
BEGIN_MESSAGE_MAP(CChildView,CWnd )
|
|
//{{AFX_MSG_MAP(CChildView)
|
|
ON_WM_PAINT()
|
|
ON_WM_CREATE()
|
|
ON_WM_DESTROY()
|
|
ON_WM_TIMER()
|
|
//}}AFX_MSG_MAP
|
|
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
|
|
ON_COMMAND(ID_FILE_LOGREPORT, OnFileLogReport)
|
|
ON_COMMAND(ID_FILE_LOG2DATES, OnFileLog2Dates)
|
|
ON_COMMAND(ID_FILE_DBSETTINGS, OnFileDbSettings)
|
|
ON_COMMAND(ID_FILE_BANNERSETTING, OnFileBannerSetting)
|
|
END_MESSAGE_MAP()
|
|
|
|
BEGIN_MESSAGE_MAP(CDlgDBSettings, CDialog)
|
|
ON_BN_CLICKED(IDC_DB_TEST, OnTestConnection)
|
|
END_MESSAGE_MAP()
|
|
|
|
BEGIN_MESSAGE_MAP(CDlgGet2Dates, CDialog)
|
|
//{{AFX_MSG_MAP(CDlgGet2Dates)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
bool _stdcall RunExec(const CStr& strExec)
|
|
{
|
|
if (strExec.GetLength() > 0) {
|
|
CStr strDir;
|
|
int nStart = 0, nLen;
|
|
const char* pcszExec = strExec.String();
|
|
if (*pcszExec == '"') {
|
|
nStart++;
|
|
nLen = strExec.Find('"');
|
|
if (nLen != -1) {
|
|
nLen--;
|
|
}
|
|
} else {
|
|
nLen = strExec.Find(' ');
|
|
}
|
|
strDir.Assign(&pcszExec[nStart], nLen);
|
|
strDir.AsDirectory(TRUE);
|
|
|
|
char szBuf[512];
|
|
strcpy(szBuf, strExec.String());
|
|
STARTUPINFO si;
|
|
memset(&si, 0, sizeof(si));
|
|
si.cb = sizeof(si);
|
|
si.dwX = si.dwY = si.dwXSize = si.dwYSize = CW_USEDEFAULT;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
return !!CreateProcess(NULL, szBuf, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_PROCESS_GROUP | HIGH_PRIORITY_CLASS, NULL, strDir.String(), &si, &pi);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
CMyPrintInfo::CMyPrintInfo(const char* pcszFile, bool bIncludeBot)
|
|
: m_strFile(pcszFile), m_bIncludeBot(bIncludeBot), m_bPrinted(false)
|
|
{
|
|
}
|
|
|
|
CLogInfo::CLogInfo()
|
|
{
|
|
m_nState = 1; // 0: no error(ok!!!), 1: (@err=1), error, 2: launched(@Launched=1)...
|
|
m_strTime = 0; // Time=%02d:%02d
|
|
m_nPlayerCount = 0; // Player Count=%d
|
|
}
|
|
|
|
CLogResult::CLogResult()
|
|
{
|
|
m_nTotalPlayers = 0;
|
|
m_nGames = 0;
|
|
m_nUnfinished = 0;
|
|
m_nErrGames = 0;
|
|
m_dwRet = 0;
|
|
}
|
|
|
|
void CLogResult::GetLogResult(const CString& str)
|
|
{
|
|
m_nGames = 0, m_nTotalPlayers = 0, m_nUnfinished = 0, m_nErrGames = 0;
|
|
m_dwRet = 0;
|
|
|
|
SLogReport* pRPT = SLogReport::OpenLogReport(str, *(SYSTEMTIME*)NULL, FALSE);
|
|
if (pRPT) {
|
|
SLogItem* pStart = pRPT->GetFirst();
|
|
SLogItem* pEnd = pRPT->GetLast();
|
|
while(pStart < pEnd)
|
|
{
|
|
if ((0 < pStart->m_nPlayers) && (pStart->m_nPlayers <= 16)) {
|
|
if (pStart->m_nLaunched) {
|
|
m_nUnfinished++;
|
|
} else if (pStart->m_nErr) {
|
|
m_nErrGames++;
|
|
} else {
|
|
m_nGames++;
|
|
m_nTotalPlayers += pStart->m_nPlayers;
|
|
}
|
|
}
|
|
pStart = pStart->GetNext();
|
|
}
|
|
} else {
|
|
CStr strFile(str);
|
|
|
|
strFile.ChangeExt(".log", TRUE);
|
|
|
|
int nBufferSize = (36 + 1) * 2000;
|
|
char* psz = (char*)malloc(nBufferSize);
|
|
DoLogReport(strFile, psz, nBufferSize);
|
|
free(psz);
|
|
}
|
|
if (pRPT) {
|
|
m_dwRet = pRPT->m_dwSigns;
|
|
SLogReport::FreeLogReport(pRPT);
|
|
}
|
|
}
|
|
|
|
void CLogResult::DoLogReport(const CStr& str, char* psz, int nBufferSize)
|
|
{
|
|
TARRAYREF(CLogInfo) aLogs;
|
|
char szBuf[256];
|
|
|
|
GetPrivateProfileString(NULL, NULL, "", psz, nBufferSize, str);
|
|
while(*psz)
|
|
{
|
|
int nPlayerCount = GetPrivateProfileInt(psz, "Player Count", 0, str);
|
|
if ((0 < nPlayerCount) && (nPlayerCount <= 16)) {
|
|
int nState;
|
|
if (GetPrivateProfileInt(psz, "@err", 0, str)) {
|
|
nState = 1;
|
|
} else if (GetPrivateProfileInt(psz, "@Launched", 0, str)) {
|
|
nState = 2;
|
|
} else {
|
|
nState = 0;
|
|
}
|
|
GetPrivateProfileString(psz, "Time", "", szBuf, sizeof(szBuf), str);
|
|
CLogInfo& log = aLogs.Add();
|
|
log.m_nState = nState;
|
|
log.m_strTime = szBuf;
|
|
log.m_nPlayerCount = nPlayerCount;
|
|
}
|
|
psz = &psz[strlen(psz) + 1];
|
|
}
|
|
int i, nSize = aLogs.GetSize();
|
|
|
|
for(i = 0; i < nSize; i++)
|
|
{
|
|
const CLogInfo& log = aLogs.GetAt(i);
|
|
if (log.m_nState == 2) {
|
|
m_nUnfinished++;
|
|
} else if (log.m_nState == 1) {
|
|
m_nErrGames++;
|
|
} else {
|
|
ASSERT(log.m_nState == 0);
|
|
m_nGames++;
|
|
m_nTotalPlayers += log.m_nPlayerCount;
|
|
}
|
|
}
|
|
}
|
|
|
|
CShortDate::CShortDate(const CTime& t)
|
|
{
|
|
m_nYear = t.GetYear();
|
|
m_nMonth = t.GetMonth();
|
|
m_nDay = t.GetDay();
|
|
}
|
|
|
|
int CShortDate::Compare(const CShortDate& that)
|
|
{
|
|
ASSERT(this && &that);
|
|
|
|
int nDif;
|
|
|
|
nDif = m_nYear - that.m_nYear;
|
|
if (nDif == 0) {
|
|
nDif = m_nMonth - that.m_nMonth;
|
|
if (nDif == 0) {
|
|
nDif = m_nDay - that.m_nDay;
|
|
}
|
|
}
|
|
|
|
return nDif;
|
|
}
|
|
|
|
void CShortDate::IncADay()
|
|
{
|
|
int nDayEnd = GetDayEnd(m_nYear, m_nMonth);
|
|
if (++m_nDay >= nDayEnd) {
|
|
m_nDay = 1;
|
|
if (++m_nMonth >= 12) {
|
|
m_nMonth = 1;
|
|
m_nYear++;
|
|
}
|
|
}
|
|
}
|
|
|
|
CDlgGet2Dates::CDlgGet2Dates(SYSTEMTIME& SysTime, CWnd* pParent /*=NULL*/)
|
|
: CDialog(CDlgGet2Dates::IDD, pParent), m_Start(SysTime), m_End(SysTime)
|
|
{
|
|
//{{AFX_DATA_INIT(CDlgGet2Dates)
|
|
//}}AFX_DATA_INIT
|
|
//m_Start = 0;
|
|
//m_End = 0;
|
|
}
|
|
|
|
void CDlgGet2Dates::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CDlgGet2Dates)
|
|
//}}AFX_DATA_MAP
|
|
DDX_DateTimeCtrl(pDX, IDC_DNT_END, m_End);
|
|
DDX_DateTimeCtrl(pDX, IDC_DNT_START, m_Start);
|
|
}
|
|
|
|
BOOL CDlgGet2Dates::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
// TODO: Add extra initialization here
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
CChildView::CChildView()
|
|
{
|
|
m_uTimer = 0;
|
|
}
|
|
|
|
CChildView::~CChildView()
|
|
{
|
|
}
|
|
|
|
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
|
|
{
|
|
if (!CWnd::PreCreateWindow(cs))
|
|
return FALSE;
|
|
|
|
cs.dwExStyle |= WS_EX_CLIENTEDGE;
|
|
cs.style &= ~WS_BORDER;
|
|
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
|
|
::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CChildView::OnPaint()
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
// TODO: Add your message handler code here
|
|
|
|
// Do not call CWnd::OnPaint() for painting messages
|
|
}
|
|
|
|
bool CChildView::DoCopyData(HWND hwnd, const MW4PRINT_COPYDATASTRUCT& cd)
|
|
{
|
|
hWindow = m_hWnd;
|
|
if ((cd.dwData == MW4PRINT_COPYDATA_META) && (cd.cbData == sizeof(cd) - sizeof(COPYDATASTRUCT)) && cd.lpData) {
|
|
const GUID& guid = *(const GUID*)cd.lpData; // do not use cd.m_GUID
|
|
const char* pcsz = (const char*)&(&guid)[1]; // do not use cd.m_szFile
|
|
|
|
#ifdef _DEBUG
|
|
g_bPRTest = true;
|
|
#else // _DEBUG
|
|
g_bPRTest = false;
|
|
#endif // _DEBUG
|
|
CMyPrintInfo* p = new CMyPrintInfo(pcsz, g_bPRTest);
|
|
m_lstMPIs.AddTail(p);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
{
|
|
if (CWnd ::OnCreate(lpCreateStruct) == -1)
|
|
return -1;
|
|
|
|
DB_LoadConfig();
|
|
|
|
m_uTimer = SetTimer(IDT_TIMER, 1 * 1000, NULL);
|
|
if (!m_uTimer)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CChildView::OnDestroy()
|
|
{
|
|
if (m_uTimer) {
|
|
KillTimer(m_uTimer);
|
|
m_uTimer = 0;
|
|
}
|
|
CWnd ::OnDestroy();
|
|
}
|
|
|
|
void CChildView::OnTimer(UINT nIDEvent)
|
|
{
|
|
// TODO: Add your message handler code here and/or call default
|
|
if (nIDEvent == IDT_TIMER) {
|
|
CMyPrintInfo* p = m_lstMPIs.GetHead();
|
|
while(p) {
|
|
if (!p->m_bPrinted) {
|
|
hWindow = m_hWnd;
|
|
g_bPRTest = p->m_bIncludeBot;
|
|
if (g_RSF.LoadPR(p->m_strFile)) {
|
|
int nErr = g_RSF.DoPrint();
|
|
if (nErr == 0) {
|
|
p->m_bPrinted = true;
|
|
m_lstMPIs.Cut(p);
|
|
delete p;
|
|
}
|
|
}
|
|
g_RSF.Reset();
|
|
break;
|
|
}
|
|
p = p->m_pNext;
|
|
}
|
|
}
|
|
|
|
CWnd ::OnTimer(nIDEvent);
|
|
}
|
|
|
|
void CChildView::OnFileBannerSetting()
|
|
{
|
|
CDlgBannerSetting dlg(this);
|
|
dlg.DoModal();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgBannerSetting
|
|
|
|
CDlgBannerSetting::CDlgBannerSetting(CWnd* pParent)
|
|
: CDialog(CDlgBannerSetting::IDD, pParent)
|
|
{
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CDlgBannerSetting, CDialog)
|
|
END_MESSAGE_MAP()
|
|
|
|
void CDlgBannerSetting::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
}
|
|
|
|
BOOL CDlgBannerSetting::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
SetDlgItemText(IDC_BANNER_TEXT, g_szPrintBanner);
|
|
return TRUE;
|
|
}
|
|
|
|
void CDlgBannerSetting::OnOK()
|
|
{
|
|
GetDlgItemText(IDC_BANNER_TEXT, g_szPrintBanner, sizeof(g_szPrintBanner));
|
|
|
|
// Persist to options.ini so it survives a restart.
|
|
char szINI[MAX_PATH];
|
|
sprintf(szINI, "%s\\options.ini", AssetsDirectory1);
|
|
WritePrivateProfileString("battle tech print", "BannerText", g_szPrintBanner, szINI);
|
|
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
void CChildView::OnFileDbSettings()
|
|
{
|
|
CDlgDBSettings dlg(this);
|
|
dlg.DoModal();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgDBSettings
|
|
|
|
CDlgDBSettings::CDlgDBSettings(CWnd* pParent)
|
|
: CDialog(CDlgDBSettings::IDD, pParent)
|
|
{
|
|
}
|
|
|
|
void CDlgDBSettings::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
}
|
|
|
|
BOOL CDlgDBSettings::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
CheckDlgButton(IDC_DB_ENABLED, g_dbConfig.bEnabled ? BST_CHECKED : BST_UNCHECKED);
|
|
CheckDlgButton(IDC_DB_EXPORTEVENTS, g_dbConfig.bExportEvents ? BST_CHECKED : BST_UNCHECKED);
|
|
|
|
SetDlgItemText(IDC_DB_HOST, g_dbConfig.szHost);
|
|
SetDlgItemInt (IDC_DB_PORT, g_dbConfig.nPort, FALSE);
|
|
SetDlgItemText(IDC_DB_DATABASE, g_dbConfig.szDatabase);
|
|
SetDlgItemText(IDC_DB_USERNAME, g_dbConfig.szUsername);
|
|
SetDlgItemText(IDC_DB_PASSWORD, g_dbConfig.szPassword);
|
|
|
|
SetDlgItemText(IDC_DB_STATUS, "");
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CDlgDBSettings::OnOK()
|
|
{
|
|
g_dbConfig.bEnabled = IsDlgButtonChecked(IDC_DB_ENABLED) == BST_CHECKED;
|
|
g_dbConfig.bExportEvents = IsDlgButtonChecked(IDC_DB_EXPORTEVENTS) == BST_CHECKED;
|
|
|
|
GetDlgItemText(IDC_DB_HOST, g_dbConfig.szHost, sizeof(g_dbConfig.szHost));
|
|
g_dbConfig.nPort = (int)GetDlgItemInt(IDC_DB_PORT, NULL, FALSE);
|
|
GetDlgItemText(IDC_DB_DATABASE, g_dbConfig.szDatabase, sizeof(g_dbConfig.szDatabase));
|
|
GetDlgItemText(IDC_DB_USERNAME, g_dbConfig.szUsername, sizeof(g_dbConfig.szUsername));
|
|
GetDlgItemText(IDC_DB_PASSWORD, g_dbConfig.szPassword, sizeof(g_dbConfig.szPassword));
|
|
|
|
DB_SaveConfig();
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
void CDlgDBSettings::OnTestConnection()
|
|
{
|
|
// Read fields into a temporary config so we test what's in the UI,
|
|
// not necessarily what was last saved.
|
|
SDBConfig saved = g_dbConfig;
|
|
|
|
GetDlgItemText(IDC_DB_HOST, g_dbConfig.szHost, sizeof(g_dbConfig.szHost));
|
|
g_dbConfig.nPort = (int)GetDlgItemInt(IDC_DB_PORT, NULL, FALSE);
|
|
GetDlgItemText(IDC_DB_DATABASE, g_dbConfig.szDatabase, sizeof(g_dbConfig.szDatabase));
|
|
GetDlgItemText(IDC_DB_USERNAME, g_dbConfig.szUsername, sizeof(g_dbConfig.szUsername));
|
|
GetDlgItemText(IDC_DB_PASSWORD, g_dbConfig.szPassword, sizeof(g_dbConfig.szPassword));
|
|
|
|
SetDlgItemText(IDC_DB_STATUS, "Testing...");
|
|
UpdateWindow();
|
|
|
|
char szError[512] = "";
|
|
bool bOK = DB_TestConnection(szError, sizeof(szError));
|
|
SetDlgItemText(IDC_DB_STATUS, bOK ? "OK - Connected successfully." : szError);
|
|
|
|
g_dbConfig = saved; // restore; OnOK() will save the final values
|
|
}
|
|
|
|
void CChildView::OnFileOpen()
|
|
{
|
|
// TODO: Add your command handler code here
|
|
const char* pcszFilters = "Battle Tech Print File(*.pr)|*.pr|All Files(*.*)|*.*|";
|
|
CSpcFileDialog FD(TRUE, ".pr", NULL, OFN_HIDEREADONLY, pcszFilters, this);
|
|
FD.SetTitle("Open : *.Pr");
|
|
FD.SetFilterIndex(1);
|
|
FD.EnableHook("Include &Bot");
|
|
//FD.SetCustomFilter();
|
|
if (FD.DoModal() == IDOK) {
|
|
#ifdef _DEBUG
|
|
g_bPRTest = true;
|
|
#else // !_DEBUG
|
|
g_bPRTest = (FD.m_ofn.Flags & OFN_READONLY) ? true: false;
|
|
#endif // _DEBUG
|
|
CString str(FD.GetPathName());
|
|
CMyPrintInfo* p = new CMyPrintInfo(str, g_bPRTest);
|
|
m_lstMPIs.AddTail(p);
|
|
}
|
|
}
|
|
|
|
void CChildView::OnFileLogReport()
|
|
{
|
|
// TODO: Add your command handler code here
|
|
SYSTEMTIME SysTime;
|
|
GetLocalTime(&SysTime); // GetSystemTime
|
|
|
|
char szPath[MAX_PATH];
|
|
|
|
AdjustSysTimeForLog(SysTime);
|
|
sprintf(szPath, "c:\\mw4files\\%02d_%02d_%d.rpt", SysTime.wMonth, SysTime.wDay, SysTime.wYear);
|
|
|
|
const char* pcszFilters = "Battle Tech Report File(*.rpt)|*.rpt|All Files(*.*)|*.*|";
|
|
CSpcFileDialog FD(TRUE, ".rpt", szPath, OFN_HIDEREADONLY, pcszFilters, this);
|
|
FD.SetTitle("Open : *.Rpt");
|
|
FD.SetFilterIndex(1);
|
|
if (FD.DoModal() == IDOK) {
|
|
CString str(FD.GetPathName());
|
|
|
|
CLogResult lr;
|
|
|
|
lr.GetLogResult(str);
|
|
|
|
int nPos = str.ReverseFind('\\');
|
|
if (nPos == -1) {
|
|
nPos = str.ReverseFind('/');
|
|
}
|
|
CStr strFile(&((const char*)str)[nPos + 1]);
|
|
strFile.ChangeExt("", TRUE);
|
|
|
|
char szBuf[256 * 3];
|
|
sprintf(szBuf, "%s\n\n%d total players, %d Games", strFile.String(), lr.m_nTotalPlayers, lr.m_nGames);
|
|
if (lr.m_nUnfinished) {
|
|
sprintf(&szBuf[strlen(szBuf)], "\n\nUnfinished Games: %d", lr.m_nUnfinished);
|
|
}
|
|
if (lr.m_nErrGames) {
|
|
sprintf(&szBuf[strlen(szBuf)], "\n\nError Games: %d", lr.m_nErrGames);
|
|
}
|
|
if (lr.m_dwRet == LRPT_FILE_ERR)
|
|
strcat(szBuf, "\n\nPrevious LogData lost!!!");
|
|
else if (lr.m_dwRet == LRPT_FILE_ERR2)
|
|
strcat(szBuf, "\n\nLogData broken!!!");
|
|
|
|
MessageBox(szBuf, "Log Report");
|
|
}
|
|
}
|
|
|
|
void CChildView::OnFileLog2Dates()
|
|
{
|
|
SYSTEMTIME SysTime;
|
|
GetLocalTime(&SysTime); // GetSystemTime
|
|
|
|
CDlgGet2Dates dlg(SysTime, this);
|
|
|
|
BOOL bSuccess = FALSE;
|
|
while(dlg.DoModal() == IDOK)
|
|
{
|
|
CString str;
|
|
|
|
CShortDate Start(dlg.m_Start);
|
|
CShortDate End(dlg.m_End);
|
|
|
|
if (Start.Compare(End) > 0) {
|
|
MessageBox("Start date should be <= End Date");
|
|
continue;
|
|
}
|
|
if (Start.m_nYear < 2002) {
|
|
MessageBox("Start year should be >= 2002");
|
|
continue;
|
|
}
|
|
|
|
CStrArray aStrs;
|
|
BOOL bDone = false;
|
|
|
|
int nTotalPlayers = 0;
|
|
int nGames = 0;
|
|
int nUnfinished = 0;
|
|
int nErrGames = 0;
|
|
int nErr1 = 0;
|
|
int nErr2 = 0;
|
|
int nDays = 0;
|
|
|
|
do
|
|
{
|
|
if (Start.Compare(End) == 0)
|
|
bDone = TRUE;
|
|
|
|
CString strDate;
|
|
strDate.Format("c:\\mw4files\\%02d_%02d_%d.rpt", Start.m_nMonth, Start.m_nDay, Start.m_nYear);
|
|
|
|
CLogResult lr;
|
|
lr.GetLogResult(strDate);
|
|
|
|
nTotalPlayers += lr.m_nTotalPlayers;
|
|
nGames += lr.m_nGames;
|
|
nUnfinished += lr.m_nUnfinished;
|
|
nErrGames += lr.m_nErrGames;
|
|
int n1 = 0, n2 = 0;
|
|
if (lr.m_dwRet == LRPT_FILE_ERR) {
|
|
nErr1++;
|
|
n1++;
|
|
} else if (lr.m_dwRet == LRPT_FILE_ERR2) {
|
|
nErr2++;
|
|
n2++;
|
|
}
|
|
|
|
// comment out below if-block for off day!!!
|
|
CStr& str = aStrs.Add();
|
|
//if (lr.m_nTotalPlayers || lr.m_nGames || lr.m_nUnfinished || lr.m_nErrGames || n1 || n2) {
|
|
str.Format("%02d/%02d/%04d, %6d, %5d, %5d, %5d, %4d, %4d\r\n",
|
|
Start.m_nMonth, Start.m_nDay, Start.m_nYear,
|
|
lr.m_nTotalPlayers, lr.m_nGames, lr.m_nUnfinished, lr.m_nErrGames,
|
|
n1, n2);
|
|
//} else {
|
|
// str.Format("%02d/%02d/%04d no records\r\n", Start.m_nMonth, Start.m_nDay, Start.m_nYear);
|
|
//}
|
|
Start.IncADay();
|
|
nDays++;
|
|
} while(!bDone);
|
|
CStr& strD = aStrs.Add();
|
|
strD.Format("===================================================\r\n"
|
|
"mm/dd/year, #Plyrs, Games, Unfin, #Errs, Lost, Brkn\r\n");
|
|
|
|
CStr& strT = aStrs.Add();
|
|
strT.Format("%5d days, %6d, %5d, %5d, %5d, %4d, %4d\r\n",
|
|
nDays, nTotalPlayers, nGames, nUnfinished, nErrGames,
|
|
nErr1, nErr2);
|
|
|
|
int nTotal = aStrs.GetTotalLength();
|
|
HANDLE hMem = GlobalAlloc(GMEM_MOVEABLE, nTotal);
|
|
if (hMem) {
|
|
LPVOID p = GlobalLock(hMem);
|
|
if (p) {
|
|
char* psz = (char*)p;
|
|
CStr* pStart = &aStrs.GetAt(0);
|
|
CStr* pEnd = &pStart[aStrs.GetSize()];
|
|
while(pStart < pEnd)
|
|
{
|
|
strcpy(psz, pStart->String());
|
|
psz += pStart->GetLength();
|
|
pStart++;
|
|
}
|
|
*psz = '\0';
|
|
|
|
HANDLE handle = CreateFile("c:\\mw4files\\report.txt",
|
|
GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (handle) {
|
|
DWORD dwWritten;
|
|
WriteFile(handle, p, psz - (char*)p, &dwWritten, NULL);
|
|
CloseHandle(handle);
|
|
|
|
CStr strExec;
|
|
#if 0
|
|
//char szBuf[256];
|
|
//GetWindowsDirectory(szBuf, sizeof(szBuf));
|
|
//strExec.Format("\"%s\\system32\\notepad.exe\" /p c:\\mw4files\\report.txt", szBuf);
|
|
#else
|
|
strExec.Format("c:\\mw4files\\notepad.exe /p c:\\mw4files\\report.txt", AssetsDirectory1);
|
|
//strExec.Format("\"%s\\notepad.exe\" /p c:\\mw4files\\report.txt", AssetsDirectory1);
|
|
#endif
|
|
RunExec(strExec);
|
|
}
|
|
|
|
if (OpenClipboard()) {
|
|
EmptyClipboard();
|
|
if (SetClipboardData(CF_TEXT, hMem)) {
|
|
bSuccess = TRUE;
|
|
hMem = NULL;
|
|
}
|
|
CloseClipboard();
|
|
}
|
|
}
|
|
if (hMem) {
|
|
GlobalFree(hMem);
|
|
hMem = NULL;
|
|
}
|
|
}
|
|
if (bSuccess) {
|
|
MessageBox("LOG data is printed & placed in (CLIPBOARD & c:\\mw4files\\report.txt)");
|
|
} else {
|
|
//MessageBox("");
|
|
}
|
|
break;
|
|
}
|
|
}
|