📄 emf.c
字号:
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 pLastDM, pCurrDM;
BOOL bReturn = FALSE ,bNewDevmode;
// 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)) {
goto CleanUp;
}
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) {
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(hPrinterDC, pDevmode, dwRemainingCopies);
dwRemainingCopies = 0;
} else {
SetDrvCopies(hPrinterDC, pDevmode, dwDrvNumberOfCopies);
dwRemainingCopies -= dwDrvNumberOfCopies;
}
if (!PrintOneSideBookletEMF(hSpoolHandle,
hPrinterDC,
dwNumberOfPagesPerSide,
dwNupBorderFlags,
dwTotalNumberOfPages,
dwTotalPrintPages,
dwIndex * 2 + 1,
bReverseOrderPrinting,
dwOptimization,
dwDuplexMode,
pDevmode)) {
goto CleanUp;
}
}
}
}
bReturn = TRUE;
CleanUp:
return bReturn;
}
BOOL
PrintEMFSingleCopy(
HANDLE hSpoolHandle,
HDC hPrinterDC,
BOOL bReverseOrderPrinting,
DWORD dwDrvNumberOfPagesPerSide,
DWORD dwNumberOfPagesPerSide,
DWORD dwTotalNumberOfPages,
DWORD dwNupBorderFlags,
DWORD dwJobNumberOfCopies,
DWORD dwDrvNumberOfCopies,
BOOL bCollate,
BOOL bOdd,
BOOL bBookletPrint,
DWORD dwOptimization,
DWORD dwDuplexMode,
LPDEVMODEW pDevmode,
PPAGE_NUMBER pHead,
PPRINTPROCESSORDATA pData)
/*++
Function Description: PrintEMFSingleCopy plays one copy of the job on hPrinterDC.
Parameters: hSpoolHandle -- handle the spool file handle
hPrinterDC -- handle to the printer device context
bReverseOrderPrinting -- flag for reverse order printing
dwDrvNumberOfPagesPerSide -- number of pages the driver will print per side
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
bCollate -- flag for collating the copies
bOdd -- flag to indicate odd number of sides to print
bBookletPrint -- flag for booklet printing
dwOptimization -- optimization flags
dwDuplexMode -- duplex printing mode (none|horz|vert)
pDevmode -- pointer to devmode for changing the copy count
pHead -- pointer to a linked list containing the starting
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
--*/
{
BOOL bDuplex = (dwDuplexMode != EMF_DUP_NONE);
if (bBookletPrint) {
// Booklet Printing
return PrintBookletEMF(hSpoolHandle,
hPrinterDC,
dwNumberOfPagesPerSide,
dwTotalNumberOfPages,
dwNupBorderFlags,
dwJobNumberOfCopies,
dwDrvNumberOfCopies,
bReverseOrderPrinting,
bCollate,
dwOptimization,
dwDuplexMode,
pDevmode,
pData);
}
if (bReverseOrderPrinting) {
if (dwDrvNumberOfPagesPerSide != 1 || dwNumberOfPagesPerSide == 1) {
return PrintReverseForDriverEMF(hSpoolHandle,
hPrinterDC,
dwDrvNumberOfPagesPerSide,
dwTotalNumberOfPages,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -