我将CPrintDialog 改成CPrintingDialog dlgPrintStatus(this); 出现以下错误 怎么解决呀 error C2065: 'CPrintingDialog' : undeclared identifier : error C2146: syntax error : missing ';' before identifier 'dlgPrintStatus' : error C2065: 'dlgPrintStatus' : undeclared identifier : error C2228: left of '.SetDlgItemTextA' must have class/struct/union type : error C2228: left of '.SetDlgItemTextA' must have class/struct/union type : error C2228: left of '.SetDlgItemTextA' must have class/struct/union type : error C2228: left of '.ShowWindow' must have class/struct/union type : error C2228: left of '.UpdateWindow' must have class/struct/union type : error C2228: left of '.DestroyWindow' must have class/struct/union type : error C2228: left of '.SetDlgItemTextA' must have class/struct/union type : error C2228: left of '.DestroyWindow' must have class/struct/union type
我就是想做个打印功能 可是总是出错 我将CPrintDialog 改成CPrintingDialog dlgPrintStatus(this); 出现以下错误 怎么解决呀 error C2065: 'CPrintingDialog' : undeclared identifier : error C2146: syntax error : missing ';' before identifier 'dlgPrintStatus' : error C2065: 'dlgPrintStatus' : undeclared identifier : error C2228: left of '.SetDlgItemTextA' must have class/struct/union type : error C2228: left of '.SetDlgItemTextA' must have class/struct/union type : error C2228: left of '.SetDlgItemTextA' must have class/struct/union type : error C2228: left of '.ShowWindow' must have class/struct/union type : error C2228: left of '.UpdateWindow' must have class/struct/union type : error C2228: left of '.DestroyWindow' must have class/struct/union type : error C2228: left of '.SetDlgItemTextA' must have class/struct/union type : error C2228: left of '.DestroyWindow' must have class/struct/union type
想做个打印功能 直接CPrintDialog 不就可以了嘛
我已经找到CPrintingDialog了 怎么用呀
BOOL g_bUserAbort; class CPrintingDialog : public CDialog { public: //{{AFX_DATA(CPrintingDialog) enum { IDD = AFX_IDD_PRINTDLG }; //}}AFX_DATA CPrintingDialog::CPrintingDialog(CWnd* pParent) { Create(CPrintingDialog::IDD, pParent); // modeless ! g_bUserAbort = FALSE; } virtual ~CPrintingDialog() { } virtual BOOL OnInitDialog(); virtual void OnCancel(); };BOOL CALLBACK _AfxAbortProc1(HDC, int) { MSG msg; while (!g_bUserAbort && ::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE)) { if( !AfxPumpMessage() ) return FALSE; // terminate if WM_QUIT received } return !g_bUserAbort; }BOOL CPrintingDialog::OnInitDialog() { SetWindowText(AfxGetAppName()); CenterWindow(); return CDialog::OnInitDialog(); }void CPrintingDialog::OnCancel() { g_bUserAbort = TRUE; // flag that user aborted print CDialog::OnCancel(); } #ifndef _USE_STATIC UINT AFXAPI AfxGetFileName(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax) { ASSERT(lpszTitle == NULL || AfxIsValidAddress(lpszTitle, _MAX_FNAME)); ASSERT(AfxIsValidString(lpszPathName)); // always capture the complete file name including extension (if present) LPTSTR lpszTemp = ::PathFindFileName(lpszPathName); // lpszTitle can be NULL which just returns the number of bytes if (lpszTitle == NULL) return lstrlen(lpszTemp)+1; // otherwise copy it into the buffer provided lstrcpyn(lpszTitle, lpszTemp, nMax); return 0; } UINT AFXAPI AfxGetFileTitle(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax) { ASSERT(lpszTitle == NULL || AfxIsValidAddress(lpszTitle, _MAX_FNAME)); ASSERT(AfxIsValidString(lpszPathName)); // use a temporary to avoid bugs in ::GetFileTitle when lpszTitle is NULL TCHAR szTemp[_MAX_PATH]; LPTSTR lpszTemp = lpszTitle; if (lpszTemp == NULL) { lpszTemp = szTemp; nMax = _countof(szTemp); } if (::GetFileTitle(lpszPathName, lpszTemp, (WORD)nMax) != 0) { // when ::GetFileTitle fails, use cheap imitation return AfxGetFileName(lpszPathName, lpszTitle, nMax); } return lpszTitle == NULL ? lstrlen(lpszTemp)+1 : 0; } #endif
BOOL g_bUserAbort; class CPrintingDialog : public CDialog { public: //{{AFX_DATA(CPrintingDialog) enum { IDD = AFX_IDD_PRINTDLG }; //}}AFX_DATA CPrintingDialog::CPrintingDialog(CWnd* pParent) { Create(CPrintingDialog::IDD, pParent); // modeless ! g_bUserAbort = FALSE; } virtual ~CPrintingDialog() { } virtual BOOL OnInitDialog(); virtual void OnCancel(); };BOOL CALLBACK _AfxAbortProc1(HDC, int) { MSG msg; while (!g_bUserAbort && ::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE)) { if( !AfxPumpMessage() ) return FALSE; // terminate if WM_QUIT received } return !g_bUserAbort; }BOOL CPrintingDialog::OnInitDialog() { SetWindowText(AfxGetAppName()); CenterWindow(); return CDialog::OnInitDialog(); }void CPrintingDialog::OnCancel() { g_bUserAbort = TRUE; // flag that user aborted print CDialog::OnCancel(); } #ifndef _USE_STATIC UINT AFXAPI AfxGetFileName(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax) { ASSERT(lpszTitle == NULL || AfxIsValidAddress(lpszTitle, _MAX_FNAME)); ASSERT(AfxIsValidString(lpszPathName)); // always capture the complete file name including extension (if present) LPTSTR lpszTemp = ::PathFindFileName(lpszPathName); // lpszTitle can be NULL which just returns the number of bytes if (lpszTitle == NULL) return lstrlen(lpszTemp)+1; // otherwise copy it into the buffer provided lstrcpyn(lpszTitle, lpszTemp, nMax); return 0; } UINT AFXAPI AfxGetFileTitle(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax) { ASSERT(lpszTitle == NULL || AfxIsValidAddress(lpszTitle, _MAX_FNAME)); ASSERT(AfxIsValidString(lpszPathName)); // use a temporary to avoid bugs in ::GetFileTitle when lpszTitle is NULL TCHAR szTemp[_MAX_PATH]; LPTSTR lpszTemp = lpszTitle; if (lpszTemp == NULL) { lpszTemp = szTemp; nMax = _countof(szTemp); } if (::GetFileTitle(lpszPathName, lpszTemp, (WORD)nMax) != 0) { // when ::GetFileTitle fails, use cheap imitation return AfxGetFileName(lpszPathName, lpszTitle, nMax); } return lpszTitle == NULL ? lstrlen(lpszTemp)+1 : 0; } #endif
void CMyView::OnFilePrint() { // get default print info CPrintInfo printInfo; ASSERT(printInfo.m_pPD != NULL); // must be set if (LOWORD(GetCurrentMessage()->wParam) == ID_FILE_PRINT_DIRECT) { CCommandLineInfo* pCmdInfo = AfxGetApp()->m_pCmdInfo; if (pCmdInfo != NULL) { if (pCmdInfo->m_nShellCommand == CCommandLineInfo::FilePrintTo) { printInfo.m_pPD->m_pd.hDC = ::CreateDC(pCmdInfo->m_strDriverName, pCmdInfo->m_strPrinterName, pCmdInfo->m_strPortName, NULL); if (printInfo.m_pPD->m_pd.hDC == NULL) { AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT); return; } } } printInfo.m_bDirect = TRUE; } if (OnPreparePrinting(&printInfo)) { // hDC must be set (did you remember to call DoPreparePrinting?) ASSERT(printInfo.m_pPD->m_pd.hDC != NULL); // gather file to print to if print-to-file selected CString strOutput; if (printInfo.m_pPD->m_pd.Flags & PD_PRINTTOFILE && !printInfo.m_bDocObject) { // construct CFileDialog for browsing CString strDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULTEXT)); CString strPrintDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULT)); CString strFilter(MAKEINTRESOURCE(AFX_IDS_PRINTFILTER)); CString strCaption(MAKEINTRESOURCE(AFX_IDS_PRINTCAPTION)); CFileDialog dlg(FALSE, strDef, strPrintDef, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter, NULL, 0); dlg.m_ofn.lpstrTitle = strCaption; if (dlg.DoModal() != IDOK) return; // set output device to resulting path name strOutput = dlg.GetPathName(); } // set up document info and start the document printing process CString strTitle; CDocument* pDoc = GetDocument(); if (pDoc != NULL) strTitle = pDoc->GetTitle(); else GetParentFrame()->GetWindowText(strTitle); DOCINFO docInfo; memset(&docInfo, 0, sizeof(DOCINFO)); docInfo.cbSize = sizeof(DOCINFO); docInfo.lpszDocName = strTitle; CString strPortName; if (strOutput.IsEmpty()) { docInfo.lpszOutput = NULL; strPortName = printInfo.m_pPD->GetPortName(); } else { docInfo.lpszOutput = strOutput; AfxGetFileTitle(strOutput, strPortName.GetBuffer(_MAX_PATH), _MAX_PATH); } //EnablePrintSpool(printInfo.m_pPD->GetDeviceName().LockBuffer(),FALSE); // setup the printing DC //int n = ExtEscape(printInfo.m_pPD->m_pd.hDC,PASSTHROUGH,0,NULL,0,NULL); CDC dcPrint; if (!printInfo.m_bDocObject) { dcPrint.Attach(printInfo.m_pPD->m_pd.hDC); // attach printer dc dcPrint.m_bPrinting = TRUE; } OnBeginPrinting(&dcPrint, &printInfo); if (!printInfo.m_bDocObject) dcPrint.SetAbortProc(_AfxAbortProc1); // disable main window while printing & init printing status dialog // Store the Handle of the Window in a temp so that it can be enabled // once the printing is finished CWnd * hwndTemp = AfxGetMainWnd(); hwndTemp->EnableWindow(FALSE); CPrintingDialog dlgPrintStatus(this); CString strTemp; dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, strTitle); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME, printInfo.m_pPD->GetDeviceName()); dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, strPortName); dlgPrintStatus.ShowWindow(SW_SHOW); dlgPrintStatus.UpdateWindow(); // start document printing process if (!printInfo.m_bDocObject) { printInfo.m_nJobNumber = dcPrint.StartDoc(&docInfo); if (printInfo.m_nJobNumber == SP_ERROR) { // enable main window before proceeding hwndTemp->EnableWindow(TRUE); // cleanup and show error message OnEndPrinting(&dcPrint, &printInfo); dlgPrintStatus.DestroyWindow(); dcPrint.Detach(); // will be cleaned up by CPrintInfo destructor AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT); return; } } // Guarantee values are in the valid range UINT nEndPage = printInfo.GetToPage(); UINT nStartPage = printInfo.GetFromPage(); if (nEndPage < printInfo.GetMinPage()) nEndPage = printInfo.GetMinPage(); if (nEndPage > printInfo.GetMaxPage()) nEndPage = printInfo.GetMaxPage(); if (nStartPage < printInfo.GetMinPage()) nStartPage = printInfo.GetMinPage(); if (nStartPage > printInfo.GetMaxPage()) nStartPage = printInfo.GetMaxPage(); if (m_PrintParam.bReverseOrder) { int nSwp = nStartPage; nStartPage = nEndPage; nEndPage = nSwp; }
int nStep = (nEndPage >= nStartPage) ? 1 : -1; nEndPage = (nEndPage == 0xffff) ? 0xffff : nEndPage + nStep; VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM)); // If it's a doc object, we don't loop page-by-page // because doc objects don't support that kind of levity. BOOL bError = FALSE; BOOL bQuit = FALSE; if (printInfo.m_bDocObject) { OnPrepareDC(&dcPrint, &printInfo); OnPrint(&dcPrint, &printInfo); } else { int nCount1 = 1; if (m_PrintParam.bByCopy) nCount1 = m_PrintParam.nCopies; while(nCount1 > 0) { if (bQuit) break; // begin page printing loop for (printInfo.m_nCurPage = nStartPage; printInfo.m_nCurPage != nEndPage; printInfo.m_nCurPage += nStep) { // check for end of print if (!printInfo.m_bContinuePrinting) { break; } int nCurPage = printInfo.m_nCurPage; int nCount = m_PrintParam.nCopies; if (m_PrintParam.bByCopy) nCount = 1; while(nCount > 0) { printInfo.m_nCurPage = nCurPage; OnPrepareDC(&dcPrint, &printInfo); if (!printInfo.m_bContinuePrinting) { break; } // write current page TCHAR szBuf[80]; int cnt = _sntprintf(szBuf, _countof(szBuf), strTemp, printInfo.m_nCurPage); if (cnt < 0 || cnt == _countof(szBuf)) { // No room for nul szBuf[_countof(szBuf)-1] = __T('\0'); } dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, szBuf); // set up drawing rect to entire page (in logical coordinates) printInfo.m_rectDraw.SetRect(0, 0, dcPrint.GetDeviceCaps(HORZRES), dcPrint.GetDeviceCaps(VERTRES)); dcPrint.DPtoLP(&printInfo.m_rectDraw); // attempt to start the current page if (dcPrint.StartPage() < 0) { bError = TRUE; break; } // must call OnPrepareDC on newer versions of Windows because // StartPage now resets the device attributes. OnPrepareDC(&dcPrint, &printInfo); ASSERT(printInfo.m_bContinuePrinting); // page successfully started, so now render the page OnPrint(&dcPrint, &printInfo); // If the user restarts the job when it's spooling, all // subsequent calls to EndPage returns < 0. The first time // GetLastError returns ERROR_PRINT_CANCELLED if (dcPrint.EndPage() < 0 && (GetLastError()!= ERROR_SUCCESS)) { HANDLE hPrinter; if (!OpenPrinter(LPTSTR(printInfo.m_pPD->GetDeviceName().GetBuffer()), &hPrinter, NULL)) { bError = TRUE; break; } DWORD cBytesNeeded; if(!GetJob(hPrinter,printInfo.m_nJobNumber,1,NULL,0,&cBytesNeeded)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { bError = TRUE; break; } } JOB_INFO_1 *pJobInfo; if((pJobInfo = (JOB_INFO_1 *)malloc(cBytesNeeded))== NULL) { bError = TRUE; break; } DWORD cBytesUsed; BOOL bRet = GetJob(hPrinter,printInfo.m_nJobNumber,1,LPBYTE(pJobInfo),cBytesNeeded,&cBytesUsed); DWORD dwJobStatus = pJobInfo->Status; free(pJobInfo); pJobInfo = NULL; // if job status is restart, just continue if(!bRet || !(dwJobStatus & JOB_STATUS_RESTART) ) { bError = TRUE; break; } } if(!_AfxAbortProc1(dcPrint.m_hDC, 0)) { bError = TRUE; break; } nCount--; } if (bError) bQuit = TRUE; } nCount1--; } } // cleanup document printing process if (!printInfo.m_bDocObject) { if (!bError) dcPrint.EndDoc(); else dcPrint.AbortDoc(); } hwndTemp->EnableWindow(); // enable main window OnEndPrinting(&dcPrint, &printInfo); // clean up after printing dlgPrintStatus.DestroyWindow(); dcPrint.Detach(); // will be cleaned up by CPrintInfo destructor } }
出现以下错误 怎么解决呀
error C2065: 'CPrintingDialog' : undeclared identifier
: error C2146: syntax error : missing ';' before identifier 'dlgPrintStatus'
: error C2065: 'dlgPrintStatus' : undeclared identifier
: error C2228: left of '.SetDlgItemTextA' must have class/struct/union type
: error C2228: left of '.SetDlgItemTextA' must have class/struct/union type
: error C2228: left of '.SetDlgItemTextA' must have class/struct/union type
: error C2228: left of '.ShowWindow' must have class/struct/union type
: error C2228: left of '.UpdateWindow' must have class/struct/union type
: error C2228: left of '.DestroyWindow' must have class/struct/union type
: error C2228: left of '.SetDlgItemTextA' must have class/struct/union type
: error C2228: left of '.DestroyWindow' must have class/struct/union type
可是总是出错
我将CPrintDialog 改成CPrintingDialog dlgPrintStatus(this);
出现以下错误 怎么解决呀
error C2065: 'CPrintingDialog' : undeclared identifier
: error C2146: syntax error : missing ';' before identifier 'dlgPrintStatus'
: error C2065: 'dlgPrintStatus' : undeclared identifier
: error C2228: left of '.SetDlgItemTextA' must have class/struct/union type
: error C2228: left of '.SetDlgItemTextA' must have class/struct/union type
: error C2228: left of '.SetDlgItemTextA' must have class/struct/union type
: error C2228: left of '.ShowWindow' must have class/struct/union type
: error C2228: left of '.UpdateWindow' must have class/struct/union type
: error C2228: left of '.DestroyWindow' must have class/struct/union type
: error C2228: left of '.SetDlgItemTextA' must have class/struct/union type
: error C2228: left of '.DestroyWindow' must have class/struct/union type
怎么用呀
BOOL g_bUserAbort;
class CPrintingDialog : public CDialog
{
public:
//{{AFX_DATA(CPrintingDialog)
enum { IDD = AFX_IDD_PRINTDLG };
//}}AFX_DATA
CPrintingDialog::CPrintingDialog(CWnd* pParent)
{
Create(CPrintingDialog::IDD, pParent); // modeless !
g_bUserAbort = FALSE;
}
virtual ~CPrintingDialog() { } virtual BOOL OnInitDialog();
virtual void OnCancel();
};BOOL CALLBACK _AfxAbortProc1(HDC, int)
{
MSG msg;
while (!g_bUserAbort &&
::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
{
if( !AfxPumpMessage() )
return FALSE; // terminate if WM_QUIT received
}
return !g_bUserAbort;
}BOOL CPrintingDialog::OnInitDialog()
{
SetWindowText(AfxGetAppName());
CenterWindow();
return CDialog::OnInitDialog();
}void CPrintingDialog::OnCancel()
{
g_bUserAbort = TRUE; // flag that user aborted print
CDialog::OnCancel();
}
#ifndef _USE_STATIC
UINT AFXAPI AfxGetFileName(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax)
{
ASSERT(lpszTitle == NULL ||
AfxIsValidAddress(lpszTitle, _MAX_FNAME));
ASSERT(AfxIsValidString(lpszPathName)); // always capture the complete file name including extension (if present)
LPTSTR lpszTemp = ::PathFindFileName(lpszPathName); // lpszTitle can be NULL which just returns the number of bytes
if (lpszTitle == NULL)
return lstrlen(lpszTemp)+1; // otherwise copy it into the buffer provided
lstrcpyn(lpszTitle, lpszTemp, nMax);
return 0;
}
UINT AFXAPI AfxGetFileTitle(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax)
{
ASSERT(lpszTitle == NULL ||
AfxIsValidAddress(lpszTitle, _MAX_FNAME));
ASSERT(AfxIsValidString(lpszPathName)); // use a temporary to avoid bugs in ::GetFileTitle when lpszTitle is NULL
TCHAR szTemp[_MAX_PATH];
LPTSTR lpszTemp = lpszTitle;
if (lpszTemp == NULL)
{
lpszTemp = szTemp;
nMax = _countof(szTemp);
}
if (::GetFileTitle(lpszPathName, lpszTemp, (WORD)nMax) != 0)
{
// when ::GetFileTitle fails, use cheap imitation
return AfxGetFileName(lpszPathName, lpszTitle, nMax);
}
return lpszTitle == NULL ? lstrlen(lpszTemp)+1 : 0;
}
#endif
BOOL g_bUserAbort;
class CPrintingDialog : public CDialog
{
public:
//{{AFX_DATA(CPrintingDialog)
enum { IDD = AFX_IDD_PRINTDLG };
//}}AFX_DATA
CPrintingDialog::CPrintingDialog(CWnd* pParent)
{
Create(CPrintingDialog::IDD, pParent); // modeless !
g_bUserAbort = FALSE;
}
virtual ~CPrintingDialog() { } virtual BOOL OnInitDialog();
virtual void OnCancel();
};BOOL CALLBACK _AfxAbortProc1(HDC, int)
{
MSG msg;
while (!g_bUserAbort &&
::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE))
{
if( !AfxPumpMessage() )
return FALSE; // terminate if WM_QUIT received
}
return !g_bUserAbort;
}BOOL CPrintingDialog::OnInitDialog()
{
SetWindowText(AfxGetAppName());
CenterWindow();
return CDialog::OnInitDialog();
}void CPrintingDialog::OnCancel()
{
g_bUserAbort = TRUE; // flag that user aborted print
CDialog::OnCancel();
}
#ifndef _USE_STATIC
UINT AFXAPI AfxGetFileName(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax)
{
ASSERT(lpszTitle == NULL ||
AfxIsValidAddress(lpszTitle, _MAX_FNAME));
ASSERT(AfxIsValidString(lpszPathName)); // always capture the complete file name including extension (if present)
LPTSTR lpszTemp = ::PathFindFileName(lpszPathName); // lpszTitle can be NULL which just returns the number of bytes
if (lpszTitle == NULL)
return lstrlen(lpszTemp)+1; // otherwise copy it into the buffer provided
lstrcpyn(lpszTitle, lpszTemp, nMax);
return 0;
}
UINT AFXAPI AfxGetFileTitle(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax)
{
ASSERT(lpszTitle == NULL ||
AfxIsValidAddress(lpszTitle, _MAX_FNAME));
ASSERT(AfxIsValidString(lpszPathName)); // use a temporary to avoid bugs in ::GetFileTitle when lpszTitle is NULL
TCHAR szTemp[_MAX_PATH];
LPTSTR lpszTemp = lpszTitle;
if (lpszTemp == NULL)
{
lpszTemp = szTemp;
nMax = _countof(szTemp);
}
if (::GetFileTitle(lpszPathName, lpszTemp, (WORD)nMax) != 0)
{
// when ::GetFileTitle fails, use cheap imitation
return AfxGetFileName(lpszPathName, lpszTitle, nMax);
}
return lpszTitle == NULL ? lstrlen(lpszTemp)+1 : 0;
}
#endif
void CMyView::OnFilePrint()
{
// get default print info
CPrintInfo printInfo;
ASSERT(printInfo.m_pPD != NULL); // must be set if (LOWORD(GetCurrentMessage()->wParam) == ID_FILE_PRINT_DIRECT)
{
CCommandLineInfo* pCmdInfo = AfxGetApp()->m_pCmdInfo; if (pCmdInfo != NULL)
{
if (pCmdInfo->m_nShellCommand == CCommandLineInfo::FilePrintTo)
{
printInfo.m_pPD->m_pd.hDC = ::CreateDC(pCmdInfo->m_strDriverName,
pCmdInfo->m_strPrinterName, pCmdInfo->m_strPortName, NULL);
if (printInfo.m_pPD->m_pd.hDC == NULL)
{
AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
return;
}
}
} printInfo.m_bDirect = TRUE;
} if (OnPreparePrinting(&printInfo))
{
// hDC must be set (did you remember to call DoPreparePrinting?)
ASSERT(printInfo.m_pPD->m_pd.hDC != NULL); // gather file to print to if print-to-file selected
CString strOutput;
if (printInfo.m_pPD->m_pd.Flags & PD_PRINTTOFILE && !printInfo.m_bDocObject)
{
// construct CFileDialog for browsing
CString strDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULTEXT));
CString strPrintDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULT));
CString strFilter(MAKEINTRESOURCE(AFX_IDS_PRINTFILTER));
CString strCaption(MAKEINTRESOURCE(AFX_IDS_PRINTCAPTION));
CFileDialog dlg(FALSE, strDef, strPrintDef,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter, NULL, 0);
dlg.m_ofn.lpstrTitle = strCaption; if (dlg.DoModal() != IDOK)
return; // set output device to resulting path name
strOutput = dlg.GetPathName();
} // set up document info and start the document printing process
CString strTitle;
CDocument* pDoc = GetDocument();
if (pDoc != NULL)
strTitle = pDoc->GetTitle();
else
GetParentFrame()->GetWindowText(strTitle);
DOCINFO docInfo;
memset(&docInfo, 0, sizeof(DOCINFO));
docInfo.cbSize = sizeof(DOCINFO);
docInfo.lpszDocName = strTitle;
CString strPortName;
if (strOutput.IsEmpty())
{
docInfo.lpszOutput = NULL;
strPortName = printInfo.m_pPD->GetPortName();
}
else
{
docInfo.lpszOutput = strOutput;
AfxGetFileTitle(strOutput,
strPortName.GetBuffer(_MAX_PATH), _MAX_PATH);
}
//EnablePrintSpool(printInfo.m_pPD->GetDeviceName().LockBuffer(),FALSE); // setup the printing DC
//int n = ExtEscape(printInfo.m_pPD->m_pd.hDC,PASSTHROUGH,0,NULL,0,NULL);
CDC dcPrint;
if (!printInfo.m_bDocObject)
{
dcPrint.Attach(printInfo.m_pPD->m_pd.hDC); // attach printer dc
dcPrint.m_bPrinting = TRUE;
}
OnBeginPrinting(&dcPrint, &printInfo); if (!printInfo.m_bDocObject)
dcPrint.SetAbortProc(_AfxAbortProc1); // disable main window while printing & init printing status dialog
// Store the Handle of the Window in a temp so that it can be enabled
// once the printing is finished
CWnd * hwndTemp = AfxGetMainWnd();
hwndTemp->EnableWindow(FALSE);
CPrintingDialog dlgPrintStatus(this); CString strTemp;
dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, strTitle);
dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME,
printInfo.m_pPD->GetDeviceName());
dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, strPortName);
dlgPrintStatus.ShowWindow(SW_SHOW);
dlgPrintStatus.UpdateWindow(); // start document printing process
if (!printInfo.m_bDocObject)
{
printInfo.m_nJobNumber = dcPrint.StartDoc(&docInfo);
if (printInfo.m_nJobNumber == SP_ERROR)
{
// enable main window before proceeding
hwndTemp->EnableWindow(TRUE); // cleanup and show error message
OnEndPrinting(&dcPrint, &printInfo);
dlgPrintStatus.DestroyWindow();
dcPrint.Detach(); // will be cleaned up by CPrintInfo destructor
AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
return;
}
} // Guarantee values are in the valid range
UINT nEndPage = printInfo.GetToPage();
UINT nStartPage = printInfo.GetFromPage(); if (nEndPage < printInfo.GetMinPage())
nEndPage = printInfo.GetMinPage();
if (nEndPage > printInfo.GetMaxPage())
nEndPage = printInfo.GetMaxPage(); if (nStartPage < printInfo.GetMinPage())
nStartPage = printInfo.GetMinPage();
if (nStartPage > printInfo.GetMaxPage())
nStartPage = printInfo.GetMaxPage();
if (m_PrintParam.bReverseOrder)
{
int nSwp = nStartPage;
nStartPage = nEndPage;
nEndPage = nSwp;
}
int nStep = (nEndPage >= nStartPage) ? 1 : -1;
nEndPage = (nEndPage == 0xffff) ? 0xffff : nEndPage + nStep; VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM)); // If it's a doc object, we don't loop page-by-page
// because doc objects don't support that kind of levity. BOOL bError = FALSE;
BOOL bQuit = FALSE;
if (printInfo.m_bDocObject)
{
OnPrepareDC(&dcPrint, &printInfo);
OnPrint(&dcPrint, &printInfo);
}
else
{
int nCount1 = 1;
if (m_PrintParam.bByCopy)
nCount1 = m_PrintParam.nCopies;
while(nCount1 > 0)
{
if (bQuit)
break;
// begin page printing loop
for (printInfo.m_nCurPage = nStartPage;
printInfo.m_nCurPage != nEndPage; printInfo.m_nCurPage += nStep)
{
// check for end of print
if (!printInfo.m_bContinuePrinting)
{
break;
}
int nCurPage = printInfo.m_nCurPage;
int nCount = m_PrintParam.nCopies;
if (m_PrintParam.bByCopy)
nCount = 1;
while(nCount > 0)
{
printInfo.m_nCurPage = nCurPage;
OnPrepareDC(&dcPrint, &printInfo);
if (!printInfo.m_bContinuePrinting)
{
break;
}
// write current page
TCHAR szBuf[80];
int cnt = _sntprintf(szBuf, _countof(szBuf), strTemp, printInfo.m_nCurPage);
if (cnt < 0 || cnt == _countof(szBuf))
{ // No room for nul
szBuf[_countof(szBuf)-1] = __T('\0');
}
dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, szBuf); // set up drawing rect to entire page (in logical coordinates)
printInfo.m_rectDraw.SetRect(0, 0,
dcPrint.GetDeviceCaps(HORZRES),
dcPrint.GetDeviceCaps(VERTRES));
dcPrint.DPtoLP(&printInfo.m_rectDraw); // attempt to start the current page
if (dcPrint.StartPage() < 0)
{
bError = TRUE;
break;
} // must call OnPrepareDC on newer versions of Windows because
// StartPage now resets the device attributes.
OnPrepareDC(&dcPrint, &printInfo);
ASSERT(printInfo.m_bContinuePrinting); // page successfully started, so now render the page
OnPrint(&dcPrint, &printInfo); // If the user restarts the job when it's spooling, all
// subsequent calls to EndPage returns < 0. The first time
// GetLastError returns ERROR_PRINT_CANCELLED
if (dcPrint.EndPage() < 0 && (GetLastError()!= ERROR_SUCCESS))
{
HANDLE hPrinter;
if (!OpenPrinter(LPTSTR(printInfo.m_pPD->GetDeviceName().GetBuffer()), &hPrinter, NULL))
{
bError = TRUE;
break;
} DWORD cBytesNeeded;
if(!GetJob(hPrinter,printInfo.m_nJobNumber,1,NULL,0,&cBytesNeeded))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
bError = TRUE;
break;
}
} JOB_INFO_1 *pJobInfo;
if((pJobInfo = (JOB_INFO_1 *)malloc(cBytesNeeded))== NULL)
{
bError = TRUE;
break;
} DWORD cBytesUsed; BOOL bRet = GetJob(hPrinter,printInfo.m_nJobNumber,1,LPBYTE(pJobInfo),cBytesNeeded,&cBytesUsed); DWORD dwJobStatus = pJobInfo->Status; free(pJobInfo);
pJobInfo = NULL; // if job status is restart, just continue
if(!bRet || !(dwJobStatus & JOB_STATUS_RESTART) )
{
bError = TRUE;
break;
}
} if(!_AfxAbortProc1(dcPrint.m_hDC, 0))
{
bError = TRUE;
break;
}
nCount--;
}
if (bError)
bQuit = TRUE;
}
nCount1--;
}
} // cleanup document printing process
if (!printInfo.m_bDocObject)
{
if (!bError)
dcPrint.EndDoc();
else
dcPrint.AbortDoc();
} hwndTemp->EnableWindow(); // enable main window OnEndPrinting(&dcPrint, &printInfo); // clean up after printing
dlgPrintStatus.DestroyWindow(); dcPrint.Detach(); // will be cleaned up by CPrintInfo destructor
}
}