📄 emf.c
字号:
return bReturn;
}
BOOL
PrintReverseForDriverEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwDrvNumberOfPagesPerSide,
DWORD dwTotalNumberOfPages,
DWORD dwNupBorderFlags,
DWORD dwJobNumberOfCopies,
DWORD dwDrvNumberOfCopies,
BOOL bCollate,
BOOL bDuplex,
BOOL bOdd,
DWORD dwOptimization,
LPDEVMODEW pDevmode,
PPAGE_NUMBER pHead,
PPRINTPROCESSORDATA pData)
/*++
Function Description: PrintReverseForDriverEMF plays the EMF pages in the reverse order
for the driver which does the Nup transformations.
Parameters: hSpoolHandle -- handle the spool file handle
hPrinterDC -- handle to the printer device context
dwDrvNumberOfPagesPerSide -- number of pages the driver will print per side
dwTotalNumberOfPages -- total 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
bDuplex -- flag to indicate duplex printing
bOdd -- flag to indicate odd number of sides to print
dwOptimization -- optimization flags
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
--*/
{
DWORD dwPageIndex,dwPageNumber,dwRemainingCopies;
BOOL bReturn = FALSE;
// select the correct page for duplex printing
if (bDuplex && !bOdd) {
if (pHead) {
pHead = pHead->pNext;
} else {
bReturn = TRUE;
goto CleanUp;
}
}
// play the sides in reverse order
while (pHead) {
//
// If the print processor is paused, wait for it to be resumed
//
if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
WaitForSingleObject(pData->semPaused, INFINITE);
}
// set the page number
dwPageNumber = pHead->dwPageNumber;
if (bCollate) {
if (!PrintOneSideReverseForDriverEMF(hSpoolHandle,
hPrinterDC,
dwDrvNumberOfPagesPerSide,
dwTotalNumberOfPages,
dwNupBorderFlags,
bDuplex,
dwOptimization,
dwPageNumber,
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 (!PrintOneSideReverseForDriverEMF(hSpoolHandle,
hPrinterDC,
dwDrvNumberOfPagesPerSide,
dwTotalNumberOfPages,
dwNupBorderFlags,
bDuplex,
dwOptimization,
dwPageNumber,
pDevmode)) {
goto CleanUp;
}
}
}
pHead = pHead->pNext;
// go to the next page for duplex printing
if (bDuplex && pHead) {
pHead = pHead->pNext;
}
}
bReturn = TRUE;
CleanUp:
return bReturn;
}
BOOL
PrintOneSideReverseEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwNumberOfPagesPerSide,
DWORD dwNupBorderFlags,
BOOL bDuplex,
DWORD dwOptimization,
DWORD dwStartPage1,
DWORD dwEndPage1,
DWORD dwStartPage2,
DWORD dwEndPage2,
LPDEVMODE pDevmode)
/*++
Function Description: PrintOneSideReverseEMF plays the EMF pages for the next physical page.
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
bDuplex -- flag to indicate duplex printing
dwOptimization -- optimization flags
dwStartPage1 -- page number of the first EMF page on 1st side
dwEndPage1 -- page number of the last EMF page on 1st side
dwStartPage2 -- page number of the first EMF page on 2nd side
dwEndPage2 -- page number of the last EMF page on 2nd side
pDevmode -- devmode with resolution settings
Return Values: TRUE if successful
FALSE otherwise
--*/
{
DWORD dwPageNumber, dwPageIndex, dwPageType;
BOOL bReturn = FALSE, bNewDevmode;
LPDEVMODEW pLastDM,pCurrDM;
HANDLE hEMF = NULL;
DWORD dwEndPage, dwStartPage, dwSides;
for (dwSides = bDuplex ? 2 : 1;
dwSides;
--dwSides) {
if (bDuplex && (dwSides == 1)) {
dwStartPage = dwStartPage2;
dwEndPage = dwEndPage2;
} else {
dwStartPage = dwStartPage1;
dwEndPage = dwEndPage1;
}
for (dwPageNumber = dwStartPage, dwPageIndex = 1;
dwPageNumber <= dwEndPage;
++dwPageNumber, ++dwPageIndex) {
if (!(hEMF = GdiGetPageHandle(hSpoolHandle,
dwPageNumber,
&dwPageType))) {
ODS(("GdiGetPageHandle failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
if (dwPageIndex == 1) {
// Process devmodes in the spool file and call StartPage
if (!ResetDCForNewDevmode(hSpoolHandle,
hPrinterDC,
dwPageNumber,
FALSE,
dwOptimization,
&bNewDevmode,
pDevmode) ||
!GdiStartPageEMF(hSpoolHandle)) {
goto CleanUp;
}
}
if (!PlayEMFPage(hSpoolHandle,
hPrinterDC,
hEMF,
dwNumberOfPagesPerSide,
dwPageNumber,
dwPageIndex,
dwNupBorderFlags,
EMF_DEGREE_90)) {
ODS(("PlayEMFPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
}
if ((dwPageIndex == 1) && !GdiStartPageEMF(hSpoolHandle)) {
ODS(("StartPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
if (!GdiEndPageEMF(hSpoolHandle, dwOptimization)) {
ODS(("EndPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
}
bReturn = TRUE;
CleanUp:
return bReturn;
}
BOOL
PrintReverseEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwTotalNumberOfPages,
DWORD dwNumberOfPagesPerSide,
DWORD dwNupBorderFlags,
DWORD dwJobNumberOfCopies,
DWORD dwDrvNumberOfCopies,
BOOL bCollate,
BOOL bDuplex,
BOOL bOdd,
DWORD dwOptimization,
LPDEVMODEW pDevmode,
PPAGE_NUMBER pHead,
PPRINTPROCESSORDATA pData)
/*++
Function Description: PrintReverseEMF plays the EMF pages in the reverse order and also
performs nup transformations.
Parameters: hSpoolHandle -- handle the spool file handle
hPrinterDC -- handle to the printer device context
dwTotalNumberOfPages -- number of pages in the document
dwNumberOfPagesPerSide -- number of pages to be printed per side by the print
processor
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
bDuplex -- flag to indicate duplex printing
bOdd -- flag to indicate odd number of sides to print
dwOptimization -- optimization flags
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
--*/
{
DWORD dwPageNumber,dwPageIndex,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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -