mw4print: add -debug flag for step-by-step diagnostic logging

Adds runtime diagnostic logging to track down why printing is broken.
Pass -debug (or /debug) on the command line; all output goes to
mw4print-debug.txt next to the exe (append mode, timestamped lines).
No effect on normal operation when the flag is absent.

What is logged:
- Startup: AssetsDirectory1 path and full command line
- OnCreate: DB config loaded, timer created
- DoCopyData / OnFileOpen: each file queued for printing with filename
- OnTimer: which file is being processed each second, LoadPR result
- DoPrint: nPlayers count, PrintDlg call + result (on failure logs
  CommDlgExtendedError hex code), DB export call/result, SetupFonts
  result, StartDoc result, EndDoc vs AbortDoc, final return code

The CommDlgExtendedError value on a PrintDlg failure will identify the
root cause (e.g. CDERR_NODEFAULTPRN = no default printer configured).

Co-authored-by: Claude Sonnet 4.6 (Anthropic) <noreply@anthropic.com>
Co-authored-by: GitHub Copilot <copilot@github.com>
This commit is contained in:
2026-08-07 21:53:02 -05:00
co-authored by Claude Sonnet 4.6 GitHub Copilot
parent 10301ee5dd
commit 3256c103a2
5 changed files with 88 additions and 3 deletions
+15 -1
View File
@@ -296,6 +296,7 @@ bool CChildView::DoCopyData(HWND hwnd, const MW4PRINT_COPYDATASTRUCT& cd)
#endif // _DEBUG #endif // _DEBUG
CMyPrintInfo* p = new CMyPrintInfo(pcsz, g_bPRTest); CMyPrintInfo* p = new CMyPrintInfo(pcsz, g_bPRTest);
m_lstMPIs.AddTail(p); m_lstMPIs.AddTail(p);
DbgLog("DoCopyData: queued file '%s' bIncludeBot=%d", pcsz, (int)g_bPRTest);
return true; return true;
} }
@@ -309,8 +310,10 @@ int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
return -1; return -1;
DB_LoadConfig(); DB_LoadConfig();
DbgLog("OnCreate: DB_LoadConfig done, bEnabled=%d", (int)g_dbConfig.bEnabled);
m_uTimer = SetTimer(IDT_TIMER, 1 * 1000, NULL); m_uTimer = SetTimer(IDT_TIMER, 1 * 1000, NULL);
DbgLog("OnCreate: timer id=%u", m_uTimer);
if (!m_uTimer) if (!m_uTimer)
return -1; return -1;
@@ -331,17 +334,27 @@ void CChildView::OnTimer(UINT nIDEvent)
// TODO: Add your message handler code here and/or call default // TODO: Add your message handler code here and/or call default
if (nIDEvent == IDT_TIMER) { if (nIDEvent == IDT_TIMER) {
CMyPrintInfo* p = m_lstMPIs.GetHead(); CMyPrintInfo* p = m_lstMPIs.GetHead();
if (p) DbgLog("OnTimer: head item='%s' bPrinted=%d", (const char*)p->m_strFile, (int)p->m_bPrinted);
while(p) { while(p) {
if (!p->m_bPrinted) { if (!p->m_bPrinted) {
hWindow = m_hWnd; hWindow = m_hWnd;
g_bPRTest = p->m_bIncludeBot; g_bPRTest = p->m_bIncludeBot;
if (g_RSF.LoadPR(p->m_strFile)) { DbgLog("OnTimer: calling LoadPR for '%s'", (const char*)p->m_strFile);
bool bLoaded = g_RSF.LoadPR(p->m_strFile);
DbgLog("OnTimer: LoadPR returned %d", (int)bLoaded);
if (bLoaded) {
int nErr = g_RSF.DoPrint(); int nErr = g_RSF.DoPrint();
DbgLog("OnTimer: DoPrint returned %d", nErr);
if (nErr == 0) { if (nErr == 0) {
p->m_bPrinted = true; p->m_bPrinted = true;
m_lstMPIs.Cut(p); m_lstMPIs.Cut(p);
delete p; delete p;
DbgLog("OnTimer: item printed and removed from queue");
} else {
DbgLog("OnTimer: DoPrint FAILED nErr=%d, item stays in queue", nErr);
} }
} else {
DbgLog("OnTimer: LoadPR FAILED for '%s'", (const char*)p->m_strFile);
} }
g_RSF.Reset(); g_RSF.Reset();
break; break;
@@ -514,6 +527,7 @@ void CChildView::OnFileOpen()
g_bPRTest = (FD.m_ofn.Flags & OFN_READONLY) ? true: false; g_bPRTest = (FD.m_ofn.Flags & OFN_READONLY) ? true: false;
#endif // _DEBUG #endif // _DEBUG
CString str(FD.GetPathName()); CString str(FD.GetPathName());
DbgLog("OnFileOpen: queuing file '%s' bIncludeBot=%d", (const char*)str, (int)g_bPRTest);
CMyPrintInfo* p = new CMyPrintInfo(str, g_bPRTest); CMyPrintInfo* p = new CMyPrintInfo(str, g_bPRTest);
m_lstMPIs.AddTail(p); m_lstMPIs.AddTail(p);
} }
@@ -1,6 +1,27 @@
ReplicatorID ReplicatorID::Null; ReplicatorID ReplicatorID::Null;
char AssetsDirectory1[MAX_PATH]; char AssetsDirectory1[MAX_PATH];
HWND hWindow; HWND hWindow;
bool g_bDebugLog = false;
void DbgLog(const char* fmt, ...)
{
if (!g_bDebugLog) return;
char szPath[MAX_PATH];
sprintf(szPath, "%s\\mw4print-debug.txt", AssetsDirectory1);
FILE* f = fopen(szPath, "at");
if (f) {
SYSTEMTIME st;
GetLocalTime(&st);
fprintf(f, "[%02d:%02d:%02d.%03d] ",
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
va_list args;
va_start(args, fmt);
vfprintf(f, fmt, args);
va_end(args);
fputc('\n', f);
fclose(f);
}
}
MemoryStream::MemoryStream( MemoryStream::MemoryStream(
void *stream_start, void *stream_start,
@@ -1,5 +1,8 @@
#define MW4PRINT #define MW4PRINT
extern bool g_bDebugLog;
void DbgLog(const char* fmt, ...);
#define Check_Pointer(x) #define Check_Pointer(x)
#define Check_Object(x) #define Check_Object(x)
#define Verify(x) #define Verify(x)
@@ -55,6 +55,14 @@ BOOL CMW4PrintApp::InitInstance()
AssetsDirectory1[0] = '\0'; AssetsDirectory1[0] = '\0';
} }
const char* pszCmd = GetCommandLine();
if (strstr(pszCmd, "-debug") || strstr(pszCmd, "/debug")) {
g_bDebugLog = true;
DbgLog("=== mw4print started ===");
DbgLog("AssetsDirectory1: %s", AssetsDirectory1);
DbgLog("CommandLine: %s", pszCmd);
}
#ifdef _AFXDLL #ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL Enable3dControls(); // Call this when using MFC in a shared DLL
#else #else
+41 -2
View File
@@ -2557,6 +2557,9 @@ int CRecScoreFull::DoPrint() const
int nErr = 0; int nErr = 0;
int i, nPlayers = 0; int i, nPlayers = 0;
#ifdef MW4PRINT
DbgLog("DoPrint: entry");
#endif
LoadPrintParams(); LoadPrintParams();
PCRecScoreObject aRSOs[64]; PCRecScoreObject aRSOs[64];
@@ -2567,6 +2570,9 @@ int CRecScoreFull::DoPrint() const
nPlayers++; nPlayers++;
pO = pO->m_pNext; pO = pO->m_pNext;
} }
#ifdef MW4PRINT
DbgLog("DoPrint: nPlayers=%d", nPlayers);
#endif
if (nPlayers > 0) { if (nPlayers > 0) {
qsort(&aRSOs[0], nPlayers, sizeof(PCRecScoreObject), compare_RSO); qsort(&aRSOs[0], nPlayers, sizeof(PCRecScoreObject), compare_RSO);
int nTotals = GetTotalRECs(); int nTotals = GetTotalRECs();
@@ -2579,7 +2585,13 @@ int CRecScoreFull::DoPrint() const
pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC; pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
pd.nCopies = 1; pd.nCopies = 1;
#ifdef MW4PRINT
DbgLog("DoPrint: calling PrintDlg(PD_RETURNDEFAULT|PD_RETURNDC) hwndOwner=%p", (void*)hWindow);
#endif
if (PrintDlg(&pd)) { if (PrintDlg(&pd)) {
#ifdef MW4PRINT
DbgLog("DoPrint: PrintDlg OK, hDC=%p", (void*)pd.hDC);
#endif
gosASSERT(pd.hDC != NULL); gosASSERT(pd.hDC != NULL);
int naTeams[8]; int naTeams[8];
@@ -2609,9 +2621,12 @@ int CRecScoreFull::DoPrint() const
#ifdef MW4PRINT #ifdef MW4PRINT
// ---- Database export (before printing) ---- // ---- Database export (before printing) ----
// Export match data to the external MySQL database if configured.
if (g_dbConfig.bEnabled) { if (g_dbConfig.bEnabled) {
DB_ExportMatch(*this, aRSOs, nPlayers, naTeams, nTeamCount, params); DbgLog("DoPrint: calling DB_ExportMatch");
bool bDbOK = DB_ExportMatch(*this, aRSOs, nPlayers, naTeams, nTeamCount, params);
DbgLog("DoPrint: DB_ExportMatch returned %d", (int)bDbOK);
} else {
DbgLog("DoPrint: DB export disabled, skipping");
} }
// ------------------------------------------- // -------------------------------------------
#endif // MW4PRINT #endif // MW4PRINT
@@ -2652,7 +2667,13 @@ int CRecScoreFull::DoPrint() const
rcDraw.bottom -= LP2PP(DPI.y, s_rcMargin4NPA.bottom); rcDraw.bottom -= LP2PP(DPI.y, s_rcMargin4NPA.bottom);
InflateRect(&rcDraw, -3, -3); InflateRect(&rcDraw, -3, -3);
#ifdef MW4PRINT
DbgLog("DoPrint: calling SetupFonts DPI=%dx%d", (int)DPI.x, (int)DPI.y);
#endif
if (SetupFonts(DPI)) { if (SetupFonts(DPI)) {
#ifdef MW4PRINT
DbgLog("DoPrint: SetupFonts OK, calling StartDoc");
#endif
if (StartDoc(pd.hDC, &docInfo) > 0) { if (StartDoc(pd.hDC, &docInfo) > 0) {
int nLastTeam = -1; int nLastTeam = -1;
int nRow = 1; int nRow = 1;
@@ -2702,16 +2723,28 @@ int CRecScoreFull::DoPrint() const
nRow++; nRow++;
} }
if (nErr != 0) { if (nErr != 0) {
#ifdef MW4PRINT
DbgLog("DoPrint: print loop error nErr=%d, calling AbortDoc", nErr);
#endif
AbortDoc(pd.hDC); AbortDoc(pd.hDC);
} else { } else {
#ifdef MW4PRINT
DbgLog("DoPrint: print loop OK, calling EndDoc");
#endif
EndDoc(pd.hDC); EndDoc(pd.hDC);
} }
} else { } else {
nErr = -3; nErr = -3;
#ifdef MW4PRINT
DbgLog("DoPrint: StartDoc FAILED nErr=-3");
#endif
} }
CleanFonts(); CleanFonts();
} else { } else {
nErr = -2; nErr = -2;
#ifdef MW4PRINT
DbgLog("DoPrint: SetupFonts FAILED nErr=-2");
#endif
} }
delete [] pInfoTable; delete [] pInfoTable;
@@ -2719,9 +2752,15 @@ int CRecScoreFull::DoPrint() const
pd.hDC = NULL; pd.hDC = NULL;
} else { } else {
nErr = -1; nErr = -1;
#ifdef MW4PRINT
DbgLog("DoPrint: PrintDlg FAILED nErr=-1, CommDlgExtendedError=%08lX", CommDlgExtendedError());
#endif
} }
} }
#ifdef MW4PRINT
DbgLog("DoPrint: returning %d", nErr);
#endif
return nErr; return nErr;
} }