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
CMyPrintInfo* p = new CMyPrintInfo(pcsz, g_bPRTest);
m_lstMPIs.AddTail(p);
DbgLog("DoCopyData: queued file '%s' bIncludeBot=%d", pcsz, (int)g_bPRTest);
return true;
}
@@ -309,8 +310,10 @@ int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
return -1;
DB_LoadConfig();
DbgLog("OnCreate: DB_LoadConfig done, bEnabled=%d", (int)g_dbConfig.bEnabled);
m_uTimer = SetTimer(IDT_TIMER, 1 * 1000, NULL);
DbgLog("OnCreate: timer id=%u", m_uTimer);
if (!m_uTimer)
return -1;
@@ -331,17 +334,27 @@ 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();
if (p) DbgLog("OnTimer: head item='%s' bPrinted=%d", (const char*)p->m_strFile, (int)p->m_bPrinted);
while(p) {
if (!p->m_bPrinted) {
hWindow = m_hWnd;
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();
DbgLog("OnTimer: DoPrint returned %d", nErr);
if (nErr == 0) {
p->m_bPrinted = true;
m_lstMPIs.Cut(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();
break;
@@ -514,6 +527,7 @@ void CChildView::OnFileOpen()
g_bPRTest = (FD.m_ofn.Flags & OFN_READONLY) ? true: false;
#endif // _DEBUG
CString str(FD.GetPathName());
DbgLog("OnFileOpen: queuing file '%s' bIncludeBot=%d", (const char*)str, (int)g_bPRTest);
CMyPrintInfo* p = new CMyPrintInfo(str, g_bPRTest);
m_lstMPIs.AddTail(p);
}
@@ -1,6 +1,27 @@
ReplicatorID ReplicatorID::Null;
char AssetsDirectory1[MAX_PATH];
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(
void *stream_start,
@@ -1,5 +1,8 @@
#define MW4PRINT
extern bool g_bDebugLog;
void DbgLog(const char* fmt, ...);
#define Check_Pointer(x)
#define Check_Object(x)
#define Verify(x)
@@ -55,6 +55,14 @@ BOOL CMW4PrintApp::InitInstance()
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
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
+41 -2
View File
@@ -2557,6 +2557,9 @@ int CRecScoreFull::DoPrint() const
int nErr = 0;
int i, nPlayers = 0;
#ifdef MW4PRINT
DbgLog("DoPrint: entry");
#endif
LoadPrintParams();
PCRecScoreObject aRSOs[64];
@@ -2567,6 +2570,9 @@ int CRecScoreFull::DoPrint() const
nPlayers++;
pO = pO->m_pNext;
}
#ifdef MW4PRINT
DbgLog("DoPrint: nPlayers=%d", nPlayers);
#endif
if (nPlayers > 0) {
qsort(&aRSOs[0], nPlayers, sizeof(PCRecScoreObject), compare_RSO);
int nTotals = GetTotalRECs();
@@ -2579,7 +2585,13 @@ int CRecScoreFull::DoPrint() const
pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
pd.nCopies = 1;
#ifdef MW4PRINT
DbgLog("DoPrint: calling PrintDlg(PD_RETURNDEFAULT|PD_RETURNDC) hwndOwner=%p", (void*)hWindow);
#endif
if (PrintDlg(&pd)) {
#ifdef MW4PRINT
DbgLog("DoPrint: PrintDlg OK, hDC=%p", (void*)pd.hDC);
#endif
gosASSERT(pd.hDC != NULL);
int naTeams[8];
@@ -2609,9 +2621,12 @@ int CRecScoreFull::DoPrint() const
#ifdef MW4PRINT
// ---- Database export (before printing) ----
// Export match data to the external MySQL database if configured.
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
@@ -2652,7 +2667,13 @@ int CRecScoreFull::DoPrint() const
rcDraw.bottom -= LP2PP(DPI.y, s_rcMargin4NPA.bottom);
InflateRect(&rcDraw, -3, -3);
#ifdef MW4PRINT
DbgLog("DoPrint: calling SetupFonts DPI=%dx%d", (int)DPI.x, (int)DPI.y);
#endif
if (SetupFonts(DPI)) {
#ifdef MW4PRINT
DbgLog("DoPrint: SetupFonts OK, calling StartDoc");
#endif
if (StartDoc(pd.hDC, &docInfo) > 0) {
int nLastTeam = -1;
int nRow = 1;
@@ -2702,16 +2723,28 @@ int CRecScoreFull::DoPrint() const
nRow++;
}
if (nErr != 0) {
#ifdef MW4PRINT
DbgLog("DoPrint: print loop error nErr=%d, calling AbortDoc", nErr);
#endif
AbortDoc(pd.hDC);
} else {
#ifdef MW4PRINT
DbgLog("DoPrint: print loop OK, calling EndDoc");
#endif
EndDoc(pd.hDC);
}
} else {
nErr = -3;
#ifdef MW4PRINT
DbgLog("DoPrint: StartDoc FAILED nErr=-3");
#endif
}
CleanFonts();
} else {
nErr = -2;
#ifdef MW4PRINT
DbgLog("DoPrint: SetupFonts FAILED nErr=-2");
#endif
}
delete [] pInfoTable;
@@ -2719,9 +2752,15 @@ int CRecScoreFull::DoPrint() const
pd.hDC = NULL;
} else {
nErr = -1;
#ifdef MW4PRINT
DbgLog("DoPrint: PrintDlg FAILED nErr=-1, CommDlgExtendedError=%08lX", CommDlgExtendedError());
#endif
}
}
#ifdef MW4PRINT
DbgLog("DoPrint: returning %d", nErr);
#endif
return nErr;
}