📄 emf.cpp
字号:
page numbers for each of the sides
pData -- needed for status and the handle of the event: pause, resume etc.
Return Values: TRUE if successful
FALSE otherwise
--*/
{
DWORD dwRemainingCopies;
DWORD dwStartPage1,dwStartPage2,dwEndPage1,dwEndPage2;
BOOL bReturn = FALSE;
if (!pHead) {
bReturn = TRUE;
goto CleanUp;
}
// set the start and end page numbers for duplex and regular printing
if (bDuplex) {
if (bOdd) {
dwStartPage1 = pHead->dwPageNumber;
dwEndPage1 = dwTotalNumberOfPages;
dwStartPage2 = dwTotalNumberOfPages+1;
dwEndPage2 = 0;
} else {
dwStartPage2 = pHead->dwPageNumber;
dwEndPage2 = dwTotalNumberOfPages;
if (pHead = pHead->pNext) {
dwStartPage1 = pHead->dwPageNumber;
dwEndPage1 = dwStartPage2 - 1;
}
}
} else {
dwStartPage1 = pHead->dwPageNumber;
dwEndPage1 = dwTotalNumberOfPages;
dwStartPage2 = 0;
dwEndPage2 = 0;
}
while (pHead) {
//
// If the print processor is paused, wait for it to be resumed
//
if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
WaitForSingleObject(pData->semPaused, INFINITE);
}
if (bCollate) {
if (!PrintOneSideReverseEMF(hSpoolHandle,
hPrinterDC,
dwNumberOfPagesPerSide,
dwNupBorderFlags,
bDuplex,
dwOptimization,
dwStartPage1,
dwEndPage1,
dwStartPage2,
dwEndPage2,
pDevmode)) {
goto CleanUp;
}
} else {
dwRemainingCopies = dwJobNumberOfCopies;
while (dwRemainingCopies) {
if (dwRemainingCopies <= dwDrvNumberOfCopies) {
SetDrvCopies(hPrinterDC, pDevmode, dwRemainingCopies);
dwRemainingCopies = 0;
} else {
SetDrvCopies(hPrinterDC, pDevmode, dwDrvNumberOfCopies);
dwRemainingCopies -= dwDrvNumberOfCopies;
}
if (!PrintOneSideReverseEMF(hSpoolHandle,
hPrinterDC,
dwNumberOfPagesPerSide,
dwNupBorderFlags,
bDuplex,
dwOptimization,
dwStartPage1,
dwEndPage1,
dwStartPage2,
dwEndPage2,
pDevmode)) {
goto CleanUp;
}
}
}
if (bDuplex) {
if (pHead->pNext && pHead->pNext->pNext) {
dwEndPage2 = pHead->dwPageNumber - 1;
pHead = pHead->pNext;
dwStartPage2 = pHead->dwPageNumber;
dwEndPage1 = dwStartPage2 - 1;
pHead = pHead->pNext;
dwStartPage1 = pHead->dwPageNumber;
} else {
break;
}
} else {
pHead = pHead->pNext;
if (pHead) {
dwEndPage1 = dwStartPage1 - 1;
dwStartPage1 = pHead->dwPageNumber;
}
}
}
bReturn = TRUE;
CleanUp:
return bReturn;
}
BOOL
PrintOneSideBookletEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwNumberOfPagesPerSide,
DWORD dwNupBorderFlags,
DWORD dwTotalNumberOfPages,
DWORD dwTotalPrintPages,
DWORD dwStartPage,
BOOL bReverseOrderPrinting,
DWORD dwOptimization,
DWORD dwDuplexMode,
LPDEVMODE pDevmode)
/*++
Function Description: PrintOneSideBookletEMF prints one page of the booklet job.
Parameters: hSpoolHandle -- handle the spool file handle
hPrinterDC -- handle to the printer device context
dwNumberOfPagesPerSide -- number of pages to be printed per side by the print
processor
dwNupBorderFlags -- border printing options for nup
dwTotalNumberOfPages -- number of pages in the document
dwTotalPrintPages -- number of pages to printed (multiple of 4)
dwStartPage -- number of the starting page for the side
bReverseOrderPrinting -- flag for reverse order printing
dwOptimization -- optimization flags
dwDuplexMode -- duplex printing mode (none|horz|vert)
pDevmode -- devmode with resolution settings
Return Values: TRUE if successful
FALSE otherwise
--*/
{
DWORD dwPageArray[4];
DWORD dwPagesPrinted = 0, dwPageIndex, dwAngle, dwPageType, dwLastPage;
HANDLE hEMF = NULL;
LPDEVMODEW pCurrDM;
BOOL bReturn = FALSE ,bNewDevmode;
INT dmOrientation;
// set the order of the pages
if (bReverseOrderPrinting) {
dwPageArray[0] = dwStartPage + 1;
dwPageArray[1] = dwTotalPrintPages - dwStartPage;
if (dwDuplexMode == EMF_DUP_VERT) {
dwPageArray[2] = dwStartPage;
dwPageArray[3] = dwPageArray[1] + 1;
} else { // EMF_DUP_HORZ
dwPageArray[3] = dwStartPage;
dwPageArray[2] = dwPageArray[1] + 1;
}
} else {
dwPageArray[1] = dwStartPage;
dwPageArray[0] = dwTotalPrintPages - dwStartPage + 1;
if (dwDuplexMode == EMF_DUP_VERT) {
dwPageArray[2] = dwPageArray[0] - 1;
dwPageArray[3] = dwPageArray[1] + 1;
} else { // EMF_DUP_HORZ
dwPageArray[2] = dwPageArray[1] + 1;
dwPageArray[3] = dwPageArray[0] - 1;
}
}
// Set page number for ResetDC
dwLastPage = (dwTotalNumberOfPages < dwPageArray[0]) ? dwTotalNumberOfPages
: dwPageArray[0];
// Process devmodes in the spool file
if (!ResetDCForNewDevmode(hSpoolHandle,
hPrinterDC,
dwLastPage,
FALSE,
dwOptimization,
&bNewDevmode,
pDevmode,
&pCurrDM)) {
goto CleanUp;
}
if (pCurrDM)
dmOrientation = pCurrDM->dmOrientation;
else
dmOrientation = pDevmode->dmOrientation;
while (dwPagesPrinted < 4) {
for (dwPageIndex = 1;
dwPageIndex <= dwNumberOfPagesPerSide;
++dwPageIndex, ++dwPagesPrinted) {
if (dwPageArray[dwPagesPrinted] <= dwTotalNumberOfPages) {
if (!(hEMF = GdiGetPageHandle(hSpoolHandle,
dwPageArray[dwPagesPrinted],
&dwPageType))) {
ODS(("GdiGetPageHandle failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
}
if (dwPageIndex == 1) {
if (!GdiStartPageEMF(hSpoolHandle)) {
ODS(("StartPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
}
if (dwPageArray[dwPagesPrinted] <= dwTotalNumberOfPages) {
// in case of orientation switch we need to keep track of what
// we started with and what it is now
dwAngle = 0;
if (GdiGetDevmodeForPagePvt(hSpoolHandle,
dwPageArray[dwPagesPrinted],
&pCurrDM,
NULL))
{
if (pCurrDM && pCurrDM->dmOrientation != dmOrientation)
dwAngle |= EMF_DEGREE_SWAP;
}
if ((dwDuplexMode == EMF_DUP_VERT) &&
(dwPagesPrinted > 1)) {
dwAngle |= EMF_DEGREE_270;
} else { // EMF_DUP_HORZ or 1st side
dwAngle |= EMF_DEGREE_90;
}
if (!PlayEMFPage(hSpoolHandle,
hPrinterDC,
hEMF,
dwNumberOfPagesPerSide,
dwPageArray[dwPagesPrinted],
dwPageIndex,
dwNupBorderFlags,
dwAngle)) {
ODS(("PlayEMFPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
}
if (dwPageIndex == dwNumberOfPagesPerSide) {
if (!GdiEndPageEMF(hSpoolHandle, dwOptimization)) {
ODS(("EndPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
}
}
}
bReturn = TRUE;
CleanUp:
return bReturn;
}
BOOL
PrintBookletEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwNumberOfPagesPerSide,
DWORD dwTotalNumberOfPages,
DWORD dwNupBorderFlags,
DWORD dwJobNumberOfCopies,
DWORD dwDrvNumberOfCopies,
BOOL bReverseOrderPrinting,
BOOL bCollate,
DWORD dwOptimization,
DWORD dwDuplexMode,
LPDEVMODEW pDevmode,
PPRINTPROCESSORDATA pData)
/*++
Function Description: PrintBookletEMF prints the job in 2-up in booklet form.
Parameters: hSpoolHandle -- handle the spool file handle
hPrinterDC -- handle to the printer device context
dwNumberOfPagesPerSide -- number of pages to be printed per side by the print
processor
dwTotalNumberOfPages -- number of pages in the document
dwNupBorderFlags -- border printing options for nup
dwJobNumberOfCopies -- number of copies of the job to be printed
dwDrvNumberOfCopies -- number of copies that the driver can print
bReverseOrderPrinting -- flag for reverse order printing
bCollate -- flag for collating the copies
dwOptimization -- optimization flags
dwDuplexMode -- duplex printing mode (none|horz|vert)
pDevmode -- pointer to devmode for changing the copy count
pData -- needed for status and the handle of the event: pause, resume etc.
Return Values: TRUE if successful
FALSE otherwise
--*/
{
BOOL bReturn = FALSE;
DWORD dwTotalPrintPages, dwNumberOfPhyPages, dwRemainingCopies, dwIndex;
// Get closest multiple of 4 greater than dwTotalNumberOfPages
dwTotalPrintPages = dwTotalNumberOfPages - (dwTotalNumberOfPages % 4);
if (dwTotalPrintPages != dwTotalNumberOfPages) {
dwTotalPrintPages += 4;
}
dwNumberOfPhyPages = (DWORD) dwTotalPrintPages / 4;
for (dwIndex = 0; dwIndex < dwNumberOfPhyPages; ++dwIndex) {
//
// If the print processor is paused, wait for it to be resumed
//
if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
WaitForSingleObject(pData->semPaused, INFINITE);
}
if (bCollate) {
if (!PrintOneSideBookletEMF(hSpoolHandle,
hPrinterDC,
dwNumberOfPagesPerSide,
dwNupBorderFlags,
dwTotalNumberOfPages,
dwTotalPrintPages,
dwIndex * 2 + 1,
bReverseOrderPrinting,
dwOptimization,
dwDuplexMode,
pDevmode)) {
goto CleanUp;
}
} else {
dwRemainingCopies = dwJobNumberOfCopies;
while (dwRemainingCopies) {
if (dwRemainingCopies <= dwDrvNumberOfCopies) {
SetDrvCopies(hPrint
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -