📄 gsprint.cpp
字号:
}
// Get the information needed for the DEVNAMES structure
GetProfileString("Devices", device, "", driverbuf, sizeof(driverbuf));
if (strlen(driverbuf) == 0)
return FALSE; // printer doesn't exist
driver = strtok(driverbuf, ",");
output = strtok(NULL, ",");
// Build the DEVNAMES structure
length = sizeof(DEVNAMES) +
strlen(device) + 1 +
strlen(driver) + 1 +
strlen(output) + 2;
if (length < 1024)
length = 1024;
hglobal = GlobalAlloc(GMEM_MOVEABLE, length);
if (hglobal == NULL)
return FALSE;
lpdevnames = (LPDEVNAMES)GlobalLock(hglobal);
memset(lpdevnames, 0, length);
offset = sizeof(DEVNAMES);
lpdevnames->wDriverOffset = offset;
strcpy((char *)lpdevnames + offset, driver);
offset += strlen(driver) + 1;
lpdevnames->wDeviceOffset = offset;
strcpy((char *)lpdevnames + offset, device);
offset += strlen(device) + 1;
lpdevnames->wOutputOffset = offset;
strcpy((char *)lpdevnames + offset, output);
GlobalUnlock(hglobal);
lpdevnames = NULL;
*hdevnames = hglobal;
// here we should try to merge requests for page size,
// duplex, orientation etc. by obtaining and modifying
// DEVMODE.
LPDEVMODE podevmode, pidevmode;
HANDLE hprinter;
if (!OpenPrinter(device, &hprinter, NULL))
return FALSE;
length = DocumentProperties(NULL, hprinter, device, NULL, NULL, 0);
hglobal = GlobalAlloc(GMEM_MOVEABLE, length);
if (hglobal == NULL) {
ClosePrinter(hprinter);
return FALSE;
}
podevmode = (LPDEVMODE)GlobalLock(hglobal);
memset(podevmode, 0, length);
if ((pidevmode = (LPDEVMODE)malloc(length)) == (LPDEVMODE) NULL) {
GlobalUnlock(hglobal);
GlobalFree(hglobal);
ClosePrinter(hprinter);
return FALSE;
}
DocumentProperties(NULL, hprinter, device, podevmode, NULL, DM_OUT_BUFFER);
memcpy(pidevmode, podevmode, length);
pidevmode->dmFields = 0;
if (opt->duplex) {
pidevmode->dmFields |= DM_DUPLEX;
pidevmode->dmDuplex = DMDUP_VERTICAL;
}
if (opt->copies) {
pidevmode->dmFields |= DM_COPIES;
pidevmode->dmCopies = opt->copies;
}
if (opt->orientation == PORTRAIT) {
pidevmode->dmFields |= DM_ORIENTATION;
pidevmode->dmOrientation = DMORIENT_PORTRAIT;
} else if (opt->orientation == LANDSCAPE) {
pidevmode->dmFields |= DM_ORIENTATION;
pidevmode->dmOrientation = DMORIENT_LANDSCAPE;
}
// merge the entries
DocumentProperties(NULL, hprinter, device, podevmode, pidevmode,
DM_IN_BUFFER | DM_OUT_BUFFER);
ClosePrinter(hprinter);
free(pidevmode);
GlobalUnlock(hglobal);
*hdevmode = hglobal;
return TRUE;
}
void print_devmode(HANDLE hDevMode)
{
DWORD dw;
if ((hDevMode == NULL) || (hDevMode == INVALID_HANDLE_VALUE))
return;
LPDEVMODE dm = (LPDEVMODE)GlobalLock(hDevMode);
fprintf(stdout, "DevMode:\n");
fprintf(stdout, " dmDeviceName=\042%s\042\n", dm->dmDeviceName);
fprintf(stdout, " dmFields=0x%x\n", dm->dmFields);
dw = dm->dmFields;
if (dw & DM_ORIENTATION)
fprintf(stdout, " DM_ORIENTATION\n");
if (dw & DM_PAPERSIZE)
fprintf(stdout, " DM_PAPERSIZE\n");
if (dw & DM_PAPERLENGTH)
fprintf(stdout, " DM_PAPERLENGTH\n");
if (dw & DM_PAPERWIDTH)
fprintf(stdout, " DM_PAPERWIDTH\n");
if (dw & DM_SCALE)
fprintf(stdout, " DM_SCALE\n");
if (dw & DM_COPIES)
fprintf(stdout, " DM_COPIES\n");
if (dw & DM_DEFAULTSOURCE)
fprintf(stdout, " DM_DEFAULTSOURCE\n");
if (dw & DM_PRINTQUALITY)
fprintf(stdout, " DM_PRINTQUALITY\n");
if (dw & DM_COLOR)
fprintf(stdout, " DM_COLOR\n");
if (dw & DM_DUPLEX)
fprintf(stdout, " DM_DUPLEX\n");
if (dw & DM_YRESOLUTION)
fprintf(stdout, " DM_YRESOLUTION\n");
if (dw & DM_TTOPTION)
fprintf(stdout, " DM_TTOPTION\n");
if (dw & DM_COLLATE)
fprintf(stdout, " DM_COLLATE\n");
if (dw & DM_FORMNAME)
fprintf(stdout, " DM_FORMNAME\n");
fprintf(stdout, " dmOrientation=%d\n", dm->dmOrientation);
fprintf(stdout, " dmPaperSize=%d\n", dm->dmPaperSize);
fprintf(stdout, " dmPaperLength=%d\n", dm->dmPaperLength);
fprintf(stdout, " dmPaperWidth=%d\n", dm->dmPaperWidth);
fprintf(stdout, " dmScale=%d\n", dm->dmScale);
fprintf(stdout, " dmCopies=%d\n", dm->dmCopies);
fprintf(stdout, " dmDefaultSource=%d\n", dm->dmDefaultSource);
fprintf(stdout, " dmPrintQuality=%d\n", dm->dmPrintQuality);
fprintf(stdout, " dmColor=%d\n", dm->dmColor);
fprintf(stdout, " dmDuplex=%d\n", dm->dmDuplex);
fprintf(stdout, " dmYResolution=%d\n", dm->dmYResolution);
fprintf(stdout, " dmTTOption=%d\n", dm->dmTTOption);
fprintf(stdout, " dmCollate=%d\n", dm->dmCollate);
fprintf(stdout, " dmFormName=\042%s\042\n", dm->dmFormName);
fprintf(stdout, " dmLogPixels=%d\n", dm->dmLogPixels);
fprintf(stdout, " dmBitsPerPel=%d\n", dm->dmBitsPerPel);
fprintf(stdout, " dmPelsWidth=%d\n", dm->dmPelsWidth);
fprintf(stdout, " dmPelsHeight=%d\n", dm->dmPelsHeight);
fprintf(stdout, " dmDisplayFlags=%d\n", dm->dmDisplayFlags);
fprintf(stdout, " dmDisplayFrequency=%d\n", dm->dmDisplayFrequency);
GlobalUnlock(hDevMode);
}
void print_devnames(HANDLE hDevNames)
{
if ((hDevNames == NULL) || (hDevNames == INVALID_HANDLE_VALUE))
return;
LPDEVNAMES lpdevnames = (LPDEVNAMES)GlobalLock(hDevNames);
fprintf(stdout, "DevNames:\n");
fprintf(stdout, " Device=\042%s\042\n",
((char *)lpdevnames) + lpdevnames->wDeviceOffset);
fprintf(stdout, " Driver=\042%s\042\n",
((char *)lpdevnames) + lpdevnames->wDriverOffset);
fprintf(stdout, " Output=\042%s\042\n",
((char *)lpdevnames) + lpdevnames->wOutputOffset);
GlobalUnlock(hDevNames);
}
HDC query_printer(GSPRINT_OPTION *opt)
{
PRINTDLG pd;
memset(&pd, 0, sizeof(pd));
pd.lStructSize = sizeof(pd);
pd.hwndOwner = HWND_DESKTOP;
pd.Flags = PD_RETURNDC;
if (!get_devmode(opt, &pd.hDevMode, &pd.hDevNames))
return (HDC)NULL;
pd.Flags |= PD_NOSELECTION;
pd.nMinPage = 1;
pd.nMaxPage = (unsigned int)-1;
if (opt->from != 0) {
pd.nFromPage = opt->from;
pd.nToPage = 999;
pd.Flags |= PD_PAGENUMS;
}
if (opt->to != 0) {
if (pd.nFromPage == 0)
pd.nFromPage = 1;
pd.nToPage = opt->to;
pd.Flags |= PD_PAGENUMS;
}
if (!PrintDlg(&pd))
return (HDC)NULL;
if (pd.Flags & PD_PAGENUMS) {
opt->from = pd.nFromPage;
opt->to = pd.nToPage;
}
if (opt->debug)
print_devnames(pd.hDevNames);
if (opt->debug)
print_devmode(pd.hDevMode);
GlobalFree(pd.hDevMode);
GlobalFree(pd.hDevNames);
pd.hDevMode = NULL;
pd.hDevNames = NULL;
return pd.hDC;
}
HDC open_printer(GSPRINT_OPTION *opt)
{
char *device;
char *driver;
char *output;
HANDLE hDevMode;
HANDLE hDevNames;
HDC hdc;
if (!get_devmode(opt, &hDevMode, &hDevNames))
return (HDC)NULL;
LPDEVNAMES lpdevnames = (LPDEVNAMES)GlobalLock(hDevNames);
device = ((char *)lpdevnames) + lpdevnames->wDeviceOffset;
driver = ((char *)lpdevnames) + lpdevnames->wDriverOffset;
output = ((char *)lpdevnames) + lpdevnames->wOutputOffset;
LPDEVMODE lpdevmode = (LPDEVMODE)GlobalLock(hDevMode);
hdc = CreateDC(driver, device, NULL, lpdevmode);
GlobalUnlock(hDevMode);
GlobalUnlock(hDevNames);
if (opt->debug)
print_devnames(hDevNames);
if (opt->debug)
print_devmode(hDevMode);
GlobalFree(hDevMode);
GlobalFree(hDevNames);
return hdc;
}
#ifdef NOTUSED
void CheckProcess( void *dummy )
{
DWORD exit_status;
while (GetExitCodeProcess(piProcInfo.hProcess, &exit_status)
&& (exit_status == STILL_ACTIVE)) {
Sleep(1000);
if (global_debug)
fprintf(stderr, ".");
}
if (global_debug)
fprintf(stderr, "CheckProcess exiting\n");
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
// We still have a handle to the write end of the pipe
// Reading the read end of the pipe won't return EOF
// until both the child copy of the write handle and
// our copy of the write handle are closed.
CloseHandle(hPipeWr);
}
#endif
int main(int argc, char *argv[])
{
GSPRINT_OPTION opt;
print_id();
#ifdef BETA
if (beta())
return 1;
#endif
memset(&opt, 0, sizeof(opt));
opt.args_end = 0;
opt.args[0] = '\0';
opt.args[1] = '\0';
find_gs(opt.gs, sizeof(opt.gs)-1, 600, FALSE);
// try reading the default config file
char buf[1024];
if (!GetModuleFileName(NULL, buf, sizeof(buf)-1))
return 1;
char *s = strrchr(buf, '\\');
if (s) {
s++;
strcpy(s, "gsprint.cfg");
}
FILE *f = fopen(buf, "r");
if (f != (FILE *)NULL) {
if (!read_config(&opt, f)) {
fclose(f);
return 1;
}
fclose(f);
}
if (!collect_args(&opt, argc, argv))
return 1;
if (!process_args(&opt))
return 1;
if (strlen(opt.gs) == 0) {
fprintf(stdout, "You must use -ghostscript\n");
return 1;
}
if (opt.debug) {
fprintf(stdout, "Options:\n");
fprintf(stdout, " Colour=%d\n", opt.colour);
fprintf(stdout, " Orientation=%d\n", opt.orientation);
fprintf(stdout, " Duplex=%d\n", opt.duplex);
fprintf(stdout, " Copies=%d\n", opt.copies);
fprintf(stdout, " From=%d\n", opt.from);
fprintf(stdout, " To=%d\n", opt.to);
fprintf(stdout, " Even/Odd=%d\n", opt.even_odd);
fprintf(stdout, " Twoup=%d\n", opt.twoup);
fprintf(stdout, " Query=%d\n", opt.query);
fprintf(stdout, " Printer=%d\n", opt.printer);
fprintf(stdout, " Printer Name=\042%s\042\n", opt.printer_name);
fprintf(stdout, " Ghostscript=\042%s\042\n", opt.gs);
fprintf(stdout, " Ghostscript Options=\042%s\042\n", opt.options);
fprintf(stdout, " Document: \042%s\042\n", opt.document_name);
}
// Get a printer handle
HDC hdc = NULL;
if (opt.query) {
hdc = query_printer(&opt);
}
else {
hdc = open_printer(&opt);
}
if (hdc == (HDC)NULL) {
fprintf(stderr, "Couldn't open Windows GDI printer driver\n");
if (!opt.query)
fprintf(stderr, "Printer name: \042%s\042\n", opt.printer_name);
return 1;
}
// create the pipe for capturing printer output
/* Set the bInheritHandle flag so pipe handles are inherited. */
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
HANDLE hPipeTemp;
if (!CreatePipe(&hPipeTemp, &hPipeWr, &saAttr, 0)) {
fprintf(stderr, "failed to open printer pipe\n");
return 1;
}
/* make the read handle non-inherited */
if (!DuplicateHandle(GetCurrentProcess(), hPipeTemp,
GetCurrentProcess(), &hPipeRd, 0,
FALSE, /* not inherited */
DUPLICATE_SAME_ACCESS)) {
return 1;
}
CloseHandle(hPipeTemp);
// open printer, get size and resolution
CPrintDIB printdib;
LPBYTE p;
LPBYTE pLine = NULL;
int length;
DWORD dwRead;
DOCINFO di;
memset(&di, 0, sizeof(DOCINFO));
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = strlen(opt.document_name) ? opt.document_name : "gsprint";
di.lpszOutput = NULL;
if (StartDoc(hdc, &di) == SP_ERROR) {
DWORD err = GetLastError();
fprintf(stderr, "StartDoc failed, error code %ld\n", err);
write_error(err);
DeleteDC(hdc);
return 1;
}
int width = GetDeviceCaps(hdc, PHYSICALWIDTH);
int height = GetDeviceCaps(hdc, PHYSICALHEIGHT);
int xdpi = GetDeviceCaps(hdc, LOGPIXELSX);
int ydpi = GetDeviceCaps(hdc, LOGPIXELSY);
int xoff = GetDeviceCaps(hdc, PHYSICALOFFSETX);
int yoff = GetDeviceCaps(hdc, PHYSICALOFFSETY);
int hres = GetDeviceCaps(hdc, HORZRES);
int vres = GetDeviceCaps(hdc, VERTRES);
if (opt.debug) {
fprintf(stdout, "PHYSICALWIDTH=%d\n", width);
fprintf(stdout, "PHYSICALHEIGHT=%d\n", height);
fprintf(stdout, "PHYSICALOFFSETX=%d\n", xoff);
fprintf(stdout, "PHYSICALOFFSETY=%d\n", yoff);
fprintf(stdout, "HORZRES=%d\n", hres);
fprintf(stdout, "VERTRES=%d\n", vres);
fprintf(stdout, "LOGPIXELSX=%d\n", xdpi);
fprintf(stdout, "LOGPIXELSY=%d\n", ydpi);
}
// copy all the command line arguments to a buffer
char command[4096];
int i;
strcpy(command, opt.gs);
switch (opt.colour) {
case MONO:
strcat(command, " -sDEVICE=bmpmono");
break;
case GREY:
strcat(command, " -sDEVICE=bmpgray");
break;
case COLOUR:
strcat(command, " -sDEVICE=bmp16m");
break;
}
strcat(command, " -dNOPAUSE");
sprintf(command + strlen(command), " -g%dx%d -r%dx%d",
width, height, xdpi, ydpi);
sprintf(command + strlen(command), " -sOutputFile=%%handle%%%08x", hPipeWr);
{ /* Set the margins so that PDFFitPAge and EPSFitPage work better.
* This may cause problems here. It would be better to place it
* just before the filename, not before other the ghostscript
* options.
*/
char margin[256];
sprintf(margin,
" -c \042<< /.HWMargins [%lg %lg %lg %lg] >> setpagedevice\042 -f",
(double)xoff / xdpi * 72.0, /* left */
(double)yoff / ydpi * 72.0, /* top */
(double)(width - xoff - hres) / xdpi * 72.0, /* right */
(double)(height - yoff - vres) / ydpi * 72.0); /* bottom */
strcat(command, margin);
}
strcat(command, opt.options);
if (opt.twoup) // add an extra showpage to eject last odd page
strcat(command, " -c showpage -f");
strcat(command, " -c quit");
if (opt.twoup) {
// page counts need to be halved for twoup
if (opt.from)
opt.from = opt.from / 2;
if (opt.to)
opt.to = (opt.to+1) / 2;
}
if (opt.debug) {
fprintf(stdout, " Command: \042%s\042\n", command);
}
// start the program
if (!exec_prog(command)) {
fprintf(stderr, "Failed to exec program\n %s\n",command);
CloseHandle(hPipeWr);
CloseHandle(hPipeRd);
return 1;
}
global_debug = opt.debug;
#ifdef NOTUSED
_beginthread(CheckProcess, 32768, NULL);
#endif
GFile *pFile = gfile_open_handle((int)hPipeRd);
// now that program is running, we can close our copy of
// the pipe write handle
CloseHandle(hPipeWr);
hPipeWr = INVALID_HANDLE_VALUE;
int page = 0;
BOOL print_it;
printdib.debug = opt.debug_gdi;
while (printdib.ReadHeader(pFile)) {
page++;
print_it = TRUE;
if ((opt.even_odd == EVEN_PAGES) && ((page & 1) == 1))
print_it = FALSE;
else if ((opt.even_odd == ODD_PAGES) && ((page & 1) == 0))
print_it = FALSE;
if ((opt.from > 0) && (page < opt.from))
print_it = FALSE;
if ((opt.to > 0) && (page > opt.to))
print_it = FALSE;
fprintf(stdout, "Page %d, %s\n", page,
print_it ? "PRINT" : "ignore");
if (print_it)
StartPage(hdc);
length = printdib.m_bytewidth;
pLine = new BYTE[length];
for (i=0; i < printdib.m_PageBmp.bmp2.biHeight; i++) {
// read a scan line
length = printdib.m_bytewidth;
p = pLine;
while (length && (dwRead = gfile_read(pFile, p, length)) != 0) {
length -= dwRead;
p += dwRead;
}
if (print_it)
printdib.AddPrintLine(hdc, i, pLine);
}
if (print_it) {
printdib.FlushPrintBitmap(hdc);
EndPage(hdc);
}
delete pLine;
}
EndDoc(hdc);
DeleteDC(hdc);
gfile_close(pFile);
Sleep(2000);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -