Thomas Stockbruegger
asked on
Need some help with LPDEVMODE and printing
Hello,
I have a printer with 3 printer tray. One with white paper, one with red paper, one with green paper.
I would like to print one copy in red and green.
with dev->dmDefaultSource=DMBIN _AUTO;
or dev->dmDefaultSource=0; I will print white
dev->dmDefaultSource=1 I will print red
dev->dmDefaultSource=2 I will print green
Is it possible to change that....so when all white pages are done then the printer will do the same in red and green.
The only thing I come up with is to call 3 functions with different dev->dmDefaultSource values.
It is possilbe to change that in only one function =OnBnClickedButton_Printin g()
500 points with a solution.
Thank you for your help. Printing is difficult.
Best regards,
Thomas
void CAuftragsHistory_Liefersch ein_Dialog ::OnBnClic kedButton_ Printing()
{
HANDLE hDevMode;
HANDLE hDevNames;
if (GetPrinterDevice(_T("\\\\ DSERVER\\B rother HL-7050 series"), &hDevNames, &hDevMode)) //
{
AfxGetApp()->SelectPrinter (hDevNames , hDevMode);
CPrintDialog dlgPrint(FALSE,PD_PAGENUMS |PD_USEDEV MODECOPIES ANDCOLLATE , this);
//------------------------ --- Papier Auswahl DEVMODE -------------------------- --------
if(AfxGetApp()->GetPrinter DeviceDefa ults(&dlgP rint.m_pd) )
{
LPDEVMODE dev=dlgPrint.GetDevMode();
GlobalUnlock(dev);
dev->dmOrientation=DMORIEN T_PORTRAIT ; //Hochformat
dev->dmPaperSize=DMPAPER_A 4;
dev->dmCopies=1;
dev->dmDefaultSource=DMBIN _AUTO;
//Wichtig !!!dmFields setzen
dev->dmFields |=DM_PAPERLENGTH|DM_PAPERW IDTH|DM_OR IENTATION| DM_DEFAULT SOURCE;
}
dlgPrint.m_pd.Flags &= ~PD_RETURNDC; // Reset flag set by constructor.
//------------------------ ---------- ---------- ---------- ---------- ---------- -
// Force the CPrintDialog to use our device mode & name.
dlgPrint.m_pd.hDevMode = CopyHandle(hDevMode);
dlgPrint.m_pd.hDevNames = CopyHandle(hDevNames);
//if(dlgPrint.DoModal()==I DOK) //Ohne CPrintDialogBox
// {
GlobalFree(hDevMode);
GlobalFree(hDevNames);
hDevMode = CopyHandle(dlgPrint.m_pd.h DevMode); // Save new copies.
hDevNames = CopyHandle(dlgPrint.m_pd.h DevNames); // Save new copies.
CDC dc;
HDC hDCPrint = dlgPrint.CreatePrinterDC() ;
//------------------
dc.Attach(hDCPrint);
//------------------
dc.m_bPrinting=TRUE;
//------------------------ ---------- --
DOCINFO Print;
memset( &Print, 0, sizeof(DOCINFO) );
Print.cbSize = sizeof (DOCINFO);
Print.lpszDocName = "Drucken im Dialog";
Print.lpszOutput = (LPTSTR) NULL;
Print.lpszDatatype = (LPTSTR) NULL;
Print.fwType = 0;
//------------------------ ---------- -
BOOL bPrintingOK = dc.StartDoc(&Print);
CPrintInfo pInfo;
pInfo.m_rectDraw.SetRect(0 ,0,dc.GetD eviceCaps( HORZRES), dc.GetDeviceCaps(VERTRES)) ;
//~~~~~~~~~~~~~~~~~~~~~~~~ ~
OnBeginPrinting(&dc,&pInfo ); // call prepare
//~~~~~~~~~~~~~~~~~~~~~~~~ ~
for(UINT page=pInfo.GetMinPage();pa ge<=pInfo. GetMaxPage () &&bPrintingOK ; page++)
{
//begin a new page
dc.StartPage();
pInfo.m_nCurPage=page;
//~~~~~~~~~~~~~~~~~~~~~~~~ ~
OnPrint(&dc,&pInfo); // call Print your Page
//~~~~~~~~~~~~~~~~~~~~~~~~ ~
bPrintingOK=(dc.EndPage()> 0);
}
//~~~~~~~~~~~~~~~~~~~~~~~~ ~
OnEndPrinting(&dc,&pInfo); // call your clean up
//~~~~~~~~~~~~~~~~~~~~~~~~ ~
if(bPrintingOK)
{
dc.EndDoc();
}
else
{
dc.AbortDoc();
}
dc.DeleteDC();
// }// Ohne CPrintDialogBox
GlobalFree(dlgPrint.m_pd.h DevMode);
GlobalFree(dlgPrint.m_pd.h DevNames);
}
}
I have a printer with 3 printer tray. One with white paper, one with red paper, one with green paper.
I would like to print one copy in red and green.
with dev->dmDefaultSource=DMBIN
or dev->dmDefaultSource=0; I will print white
dev->dmDefaultSource=1 I will print red
dev->dmDefaultSource=2 I will print green
Is it possible to change that....so when all white pages are done then the printer will do the same in red and green.
The only thing I come up with is to call 3 functions with different dev->dmDefaultSource values.
It is possilbe to change that in only one function =OnBnClickedButton_Printin
500 points with a solution.
Thank you for your help. Printing is difficult.
Best regards,
Thomas
void CAuftragsHistory_Liefersch
{
HANDLE hDevMode;
HANDLE hDevNames;
if (GetPrinterDevice(_T("\\\\
{
AfxGetApp()->SelectPrinter
CPrintDialog dlgPrint(FALSE,PD_PAGENUMS
//------------------------
if(AfxGetApp()->GetPrinter
{
LPDEVMODE dev=dlgPrint.GetDevMode();
GlobalUnlock(dev);
dev->dmOrientation=DMORIEN
dev->dmPaperSize=DMPAPER_A
dev->dmCopies=1;
dev->dmDefaultSource=DMBIN
//Wichtig !!!dmFields setzen
dev->dmFields |=DM_PAPERLENGTH|DM_PAPERW
}
dlgPrint.m_pd.Flags &= ~PD_RETURNDC; // Reset flag set by constructor.
//------------------------
// Force the CPrintDialog to use our device mode & name.
dlgPrint.m_pd.hDevMode = CopyHandle(hDevMode);
dlgPrint.m_pd.hDevNames = CopyHandle(hDevNames);
//if(dlgPrint.DoModal()==I
// {
GlobalFree(hDevMode);
GlobalFree(hDevNames);
hDevMode = CopyHandle(dlgPrint.m_pd.h
hDevNames = CopyHandle(dlgPrint.m_pd.h
CDC dc;
HDC hDCPrint = dlgPrint.CreatePrinterDC()
//------------------
dc.Attach(hDCPrint);
//------------------
dc.m_bPrinting=TRUE;
//------------------------
DOCINFO Print;
memset( &Print, 0, sizeof(DOCINFO) );
Print.cbSize = sizeof (DOCINFO);
Print.lpszDocName = "Drucken im Dialog";
Print.lpszOutput = (LPTSTR) NULL;
Print.lpszDatatype = (LPTSTR) NULL;
Print.fwType = 0;
//------------------------
BOOL bPrintingOK = dc.StartDoc(&Print);
CPrintInfo pInfo;
pInfo.m_rectDraw.SetRect(0
//~~~~~~~~~~~~~~~~~~~~~~~~
OnBeginPrinting(&dc,&pInfo
//~~~~~~~~~~~~~~~~~~~~~~~~
for(UINT page=pInfo.GetMinPage();pa
{
//begin a new page
dc.StartPage();
pInfo.m_nCurPage=page;
//~~~~~~~~~~~~~~~~~~~~~~~~
OnPrint(&dc,&pInfo); // call Print your Page
//~~~~~~~~~~~~~~~~~~~~~~~~
bPrintingOK=(dc.EndPage()>
}
//~~~~~~~~~~~~~~~~~~~~~~~~
OnEndPrinting(&dc,&pInfo);
//~~~~~~~~~~~~~~~~~~~~~~~~
if(bPrintingOK)
{
dc.EndDoc();
}
else
{
dc.AbortDoc();
}
dc.DeleteDC();
// }// Ohne CPrintDialogBox
GlobalFree(dlgPrint.m_pd.h
GlobalFree(dlgPrint.m_pd.h
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
My first thoughts are it would end up with code being repeated (because you need to print the page three times within that loop), unless there is a real requirement it is probably easier to print the complete document to one paper colour, then another, then another.
Note: It ought to work and I might have misunderstood your intention.
Note: It ought to work and I might have misunderstood your intention.
ASKER
okay...thats okay...so my coding (a little more) was okay.
by the way how difficult is that?
"unless there is a real requirement it is probably easier to print the complete document to one paper colour, then another, then another"
by the way how difficult is that?
"unless there is a real requirement it is probably easier to print the complete document to one paper colour, then another, then another"
ASKER
Andy,
by the way when I call my function I got an error.
But not allways...sometimes...can you help me ?
afxcrit.cpp
1.BMP
by the way when I call my function I got an error.
But not allways...sometimes...can you help me ?
afxcrit.cpp
1.BMP
Print the complete document at one go, three times, to different trays.
void CAuftragsHistory_Liefersch ein_Dialog ::OnBnClic kedButton_ Printing()
{
PrintToTray(0);
PrintToTray(1);
PrintToTray(2);
}
void CAuftragsHistory_Liefersch
{
PrintToTray(0);
PrintToTray(1);
PrintToTray(2);
}
Are you multithreading for the printing?
ASKER
This is how I call the 3 function (only with different values 0-1-2)
void CAuftragsHistory_Liefersch ein_Dialog ::OnBnClic kedButton_ Drucken()
{
int iLieferscheinNr=atoi(m_str Liefersche inNr);//Me mberVariab le
m_button_Drucken.EnableWin dow(false) ;//disable
Sleep(1000);
//===============
VERIFY(Drucken_weiss());
Sleep(1000);
if(iLieferscheinNr<200000) MessageBox(" Drucke Lieferschein " +m_strLieferscheinNr);
if(iLieferscheinNr>200000) MessageBox(" Drucke Warenbegleitschein " +m_strLieferscheinNr);
//===============
Sleep(1000);
VERIFY(Drucken_rot());
//===============
Sleep(1000);
VERIFY(Drucken_gruen());
//===============
Sleep(1000);
m_button_Drucken.EnableWin dow(true); //not disable
}
void CAuftragsHistory_Liefersch
{
int iLieferscheinNr=atoi(m_str
m_button_Drucken.EnableWin
Sleep(1000);
//===============
VERIFY(Drucken_weiss());
Sleep(1000);
if(iLieferscheinNr<200000)
if(iLieferscheinNr>200000)
//===============
Sleep(1000);
VERIFY(Drucken_rot());
//===============
Sleep(1000);
VERIFY(Drucken_gruen());
//===============
Sleep(1000);
m_button_Drucken.EnableWin
}
Why do you have the Sleep statements?
I assume the three Drucken_xxx functions are effectively what you had originally (three pieces of identical code apart from specifying which printer tray)
I assume the three Drucken_xxx functions are effectively what you had originally (three pieces of identical code apart from specifying which printer tray)
ASKER
because I thought that will erase the error
Why do you have the Sleep statements?
I assume the three Drucken_xxx functions are effectively what you had originally (three pieces of identical code apart from specifying which printer tray) = yes
you see that I don´t use the printdialog
//if(dlgPrint.DoModal()==I
// {
but when I use the dialog, until now I have no error
Please let me know, thanks.
ASKER
ASKER
Hello Andy,
this is my code for GetPrinterDevice....perhap s the error comes from here?
please help, thanks
//######################## ########## ########## ########## ########## ########## ########## ###
bool CAuftragsHistory_Liefersch ein_Dialog ::GetPrint erDevice(L PTSTR pszPrinterName, HGLOBAL* phDevNames, HGLOBAL* phDevMode)
{
// if NULL is passed, then assume we are setting app object's
// devmode and devnames
if (phDevMode == NULL || phDevNames == NULL)
{
MessageBox("EPSON LQ-680Pro Port 2 Wiegekarte-1error");
return FALSE;
}
// Open printer
HANDLE hPrinter;
if (OpenPrinter(pszPrinterNam e, &hPrinter, NULL) == FALSE)
{
MessageBox("EPSON LQ-680Pro Port 2 Wiegekarte-2error");
return FALSE;
}
// obtain PRINTER_INFO_2 structure and close printer
DWORD dwBytesReturned, dwBytesNeeded;
GetPrinter(hPrinter, 2, NULL, 0, &dwBytesNeeded);
PRINTER_INFO_2* p2 = (PRINTER_INFO_2*)GlobalAll oc(GPTR,
dwBytesNeeded);
if (GetPrinter(hPrinter, 2, (LPBYTE)p2, dwBytesNeeded,&dwBytesRetu rned) == 0)
{
GlobalFree(p2);
ClosePrinter(hPrinter);
MessageBox("EPSON LQ-680Pro Port 2 Wiegekarte-3error");
return FALSE;
}
ClosePrinter(hPrinter);
// Allocate a global handle for DEVMODE
HGLOBAL hDevMode = GlobalAlloc(GHND, sizeof(*p2->pDevMode) + p2->pDevMode->dmDriverExtr a);
ASSERT(hDevMode);
DEVMODE* pDevMode = (DEVMODE*)GlobalLock(hDevM ode);
ASSERT(pDevMode);
// copy DEVMODE data from PRINTER_INFO_2::pDevMode
memcpy(pDevMode, p2->pDevMode, sizeof(*p2->pDevMode) + p2->pDevMode->dmDriverExtr a);
GlobalUnlock(hDevMode);
// Compute size of DEVNAMES structure from PRINTER_INFO_2's data
DWORD drvNameLen = lstrlen(p2->pDriverName)+1 ; // driver name
DWORD ptrNameLen = lstrlen(p2->pPrinterName)+ 1; // printer name
DWORD porNameLen = lstrlen(p2->pPortName)+1; // port name
// Allocate a global handle big enough to hold DEVNAMES.
HGLOBAL hDevNames = GlobalAlloc(GHND, sizeof(DEVNAMES) +(drvNameLen + ptrNameLen + porNameLen)*sizeof(TCHAR)) ;
ASSERT(hDevNames);
DEVNAMES* pDevNames = (DEVNAMES*)GlobalLock(hDev Names);
ASSERT(pDevNames);
// Copy the DEVNAMES information from PRINTER_INFO_2
// tcOffset = TCHAR Offset into structure
int tcOffset = sizeof(DEVNAMES)/sizeof(TC HAR);
ASSERT(sizeof(DEVNAMES) == tcOffset*sizeof(TCHAR));
pDevNames->wDriverOffset = tcOffset;
memcpy((LPTSTR)pDevNames + tcOffset, p2->pDriverName,drvNameLen *sizeof(TC HAR));
tcOffset += drvNameLen;
pDevNames->wDeviceOffset = tcOffset;
memcpy((LPTSTR)pDevNames + tcOffset, p2->pPrinterName,ptrNameLe n*sizeof(T CHAR));
tcOffset += ptrNameLen;
pDevNames->wOutputOffset = tcOffset;
memcpy((LPTSTR)pDevNames + tcOffset, p2->pPortName,porNameLen*s izeof(TCHA R));
pDevNames->wDefault = 0;
GlobalUnlock(hDevNames);
GlobalFree(p2); // free PRINTER_INFO_2
// set the new hDevMode and hDevNames
*phDevMode = hDevMode;
*phDevNames = hDevNames;
return TRUE;
}
//######################## ########## ########## ########## ########## ########## ########## ###
HANDLE CAuftragsHistory_Liefersch ein_Dialog ::CopyHand le(HANDLE h)
{
// Return a handle to a copy of the data
// that the passed handle was for.
if (!h) return NULL;
BYTE* lpCopy;
BYTE* lp;
HANDLE hCopy;
DWORD dwLen = GlobalSize(h);
if (hCopy = GlobalAlloc(GHND, dwLen))
{
lpCopy = (BYTE*)GlobalLock(hCopy);
lp = (BYTE*)GlobalLock(h);
CopyMemory(lpCopy,lp,dwLen );
GlobalUnlock(hCopy);
GlobalUnlock(h);
}
return hCopy;
}
//######################## ########## ########## ########## ########## ########## ########## ###
this is my code for GetPrinterDevice....perhap
please help, thanks
//########################
bool CAuftragsHistory_Liefersch
{
// if NULL is passed, then assume we are setting app object's
// devmode and devnames
if (phDevMode == NULL || phDevNames == NULL)
{
MessageBox("EPSON LQ-680Pro Port 2 Wiegekarte-1error");
return FALSE;
}
// Open printer
HANDLE hPrinter;
if (OpenPrinter(pszPrinterNam
{
MessageBox("EPSON LQ-680Pro Port 2 Wiegekarte-2error");
return FALSE;
}
// obtain PRINTER_INFO_2 structure and close printer
DWORD dwBytesReturned, dwBytesNeeded;
GetPrinter(hPrinter, 2, NULL, 0, &dwBytesNeeded);
PRINTER_INFO_2* p2 = (PRINTER_INFO_2*)GlobalAll
dwBytesNeeded);
if (GetPrinter(hPrinter, 2, (LPBYTE)p2, dwBytesNeeded,&dwBytesRetu
{
GlobalFree(p2);
ClosePrinter(hPrinter);
MessageBox("EPSON LQ-680Pro Port 2 Wiegekarte-3error");
return FALSE;
}
ClosePrinter(hPrinter);
// Allocate a global handle for DEVMODE
HGLOBAL hDevMode = GlobalAlloc(GHND, sizeof(*p2->pDevMode) + p2->pDevMode->dmDriverExtr
ASSERT(hDevMode);
DEVMODE* pDevMode = (DEVMODE*)GlobalLock(hDevM
ASSERT(pDevMode);
// copy DEVMODE data from PRINTER_INFO_2::pDevMode
memcpy(pDevMode, p2->pDevMode, sizeof(*p2->pDevMode) + p2->pDevMode->dmDriverExtr
GlobalUnlock(hDevMode);
// Compute size of DEVNAMES structure from PRINTER_INFO_2's data
DWORD drvNameLen = lstrlen(p2->pDriverName)+1
DWORD ptrNameLen = lstrlen(p2->pPrinterName)+
DWORD porNameLen = lstrlen(p2->pPortName)+1; // port name
// Allocate a global handle big enough to hold DEVNAMES.
HGLOBAL hDevNames = GlobalAlloc(GHND, sizeof(DEVNAMES) +(drvNameLen + ptrNameLen + porNameLen)*sizeof(TCHAR))
ASSERT(hDevNames);
DEVNAMES* pDevNames = (DEVNAMES*)GlobalLock(hDev
ASSERT(pDevNames);
// Copy the DEVNAMES information from PRINTER_INFO_2
// tcOffset = TCHAR Offset into structure
int tcOffset = sizeof(DEVNAMES)/sizeof(TC
ASSERT(sizeof(DEVNAMES) == tcOffset*sizeof(TCHAR));
pDevNames->wDriverOffset = tcOffset;
memcpy((LPTSTR)pDevNames + tcOffset, p2->pDriverName,drvNameLen
tcOffset += drvNameLen;
pDevNames->wDeviceOffset = tcOffset;
memcpy((LPTSTR)pDevNames + tcOffset, p2->pPrinterName,ptrNameLe
tcOffset += ptrNameLen;
pDevNames->wOutputOffset = tcOffset;
memcpy((LPTSTR)pDevNames + tcOffset, p2->pPortName,porNameLen*s
pDevNames->wDefault = 0;
GlobalUnlock(hDevNames);
GlobalFree(p2); // free PRINTER_INFO_2
// set the new hDevMode and hDevNames
*phDevMode = hDevMode;
*phDevNames = hDevNames;
return TRUE;
}
//########################
HANDLE CAuftragsHistory_Liefersch
{
// Return a handle to a copy of the data
// that the passed handle was for.
if (!h) return NULL;
BYTE* lpCopy;
BYTE* lp;
HANDLE hCopy;
DWORD dwLen = GlobalSize(h);
if (hCopy = GlobalAlloc(GHND, dwLen))
{
lpCopy = (BYTE*)GlobalLock(hCopy);
lp = (BYTE*)GlobalLock(h);
CopyMemory(lpCopy,lp,dwLen
GlobalUnlock(hCopy);
GlobalUnlock(h);
}
return hCopy;
}
//########################
This is getting really away from the original question.
I don't know if I have the time to study your code in detail - occasional errors are usually very difficult to track down.
Again - are you using multiple threads? If yes then that might be the cause.
I don't know if I have the time to study your code in detail - occasional errors are usually very difficult to track down.
Again - are you using multiple threads? If yes then that might be the cause.
ASKER
Again - are you using multiple threads? If yes then that might be the cause.
Sorry...but I don´t know if yes or no, what is multiple threads
Sorry...but I don´t know if yes or no, what is multiple threads
AfxBeginThread, CreateThread
If you don't know then probably not
If you don't know then probably not
ASKER
okay...then I do not use it
ASKER
Andy,
the strange thing is that the stop and exeptions only happens with the GetPrinterDevice
I did printing before with the printdialog and default printer with no error at all.
The only thing I had to do is to enable the Property button of the printerdialog, because otherwise it sometimes crashed.
The printer I use here is the default printer....the printing must be done without the dialog.
Is there a other way to print here without the GetPrinterDevice...if that is the cause of the error, and without the printdialog?
the strange thing is that the stop and exeptions only happens with the GetPrinterDevice
I did printing before with the printdialog and default printer with no error at all.
The only thing I had to do is to enable the Property button of the printerdialog, because otherwise it sometimes crashed.
The printer I use here is the default printer....the printing must be done without the dialog.
Is there a other way to print here without the GetPrinterDevice...if that is the cause of the error, and without the printdialog?
I'll try to think about it.
ASKER
okay...I appreciate your help....printing is very strange....thank you
ASKER
Andy,
one other hint......
if I change if (GetPrinterDevice(_T("\\\\ DSERVER\\B rother HL-7050 series"), &hDevNames, &hDevMode)) //
to if (GetPrinterDevice(_T("Powe rPDF 2005"), &hDevNames, &hDevMode)) //
to print a PDF with GetPrinterDevice ... I can press the button 100´s times wiht no error at all
HANDLE hDevMode;
HANDLE hDevNames;
if (GetPrinterDevice(_T("Powe rPDF 2005"), &hDevNames, &hDevMode)) // {
AfxGetApp()->SelectPrinter (hDevNames , hDevMode);
CPrintDialog dlgPrint(FALSE,PD_PAGENUMS |PD_USEDEV MODECOPIES ANDCOLLATE , this);
one other hint......
if I change if (GetPrinterDevice(_T("\\\\
to if (GetPrinterDevice(_T("Powe
to print a PDF with GetPrinterDevice ... I can press the button 100´s times wiht no error at all
HANDLE hDevMode;
HANDLE hDevNames;
if (GetPrinterDevice(_T("Powe
AfxGetApp()->SelectPrinter
CPrintDialog dlgPrint(FALSE,PD_PAGENUMS
ASKER
Andy,
If I go on and on to printing this is my Call Stack when I crash with printing
> KERNEL32.DLL!77eaf870()
KERNEL32.DLL!77eae67e()
Threads
> 2504 CStockbrueggerView::OnPain t 77eaf870 Normal 0
2352 Win32 Thread 77888f03 Normal 0
2120 Win32 Thread 77888b37 Normal 0
If I go on and on to printing this is my Call Stack when I crash with printing
> KERNEL32.DLL!77eaf870()
KERNEL32.DLL!77eae67e()
Threads
> 2504 CStockbrueggerView::OnPain
2352 Win32 Thread 77888f03 Normal 0
2120 Win32 Thread 77888b37 Normal 0
ASKER
Hi Andy, please take a look at my new question...I think I have to clean first my program with errors, Thank you
ASKER
thanks for the code.
with your code I am calling the function also 3 times (PrintToTray).
Okay...thats is fewer coding....but the same as I would call 3 different OnBnClickedButton_Printing
with different dev->dmDefaultSource values.
I thought I can change the OnBnClickedButton_Printing
for(UINT page=pInfo.GetMinPage();pa
{
//begin a new page
dc.StartPage();
pInfo.m_nCurPage=page;
.
.
.
or is this not possible?
Let me know
Thank you.