我们在要打印的文件上点击鼠标右键,弹出菜单中有一个打印子菜单,点击打印就可以完成文档的打印工作。但要注意的是,只有可以打印的文件在鼠标右键点击时才会出现打印子菜单,且操作系统上要安装与之匹配的编辑器。例如有一个DOC格式的文件要能打印,必须要安装WORD或WPS之类的软件,否则操作系统无法识别文件格式,自然也就无法打印, 这种打印叫做快速打印。
在程序中快速打印可以用一个函数来完成:
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
"open" | The function opens the file specified by the lpFile parameter. The file can be an executable file or a document file. It can also be a folder. |
"print" | The function prints the file specified by lpFile. The file should be a document file. If the file is an executable file, the function opens the file, as if "open" had been specified. |
"explore" | The function explores the folder specified by lpFile. |
This parameter can be NULL. In that case, the function opens the file specified by lpFile.
如上所述,在不支持打印文件上将执行打开操作,如BMP图像文件将会以与之匹配的查看器打开。
使用如下:
ShellExecute(NULL, "print", "C://aa.doc", NULL, NULL, SW_HIDE);
SW_HIDE表示隐藏打印,在打印时,文件会被打开,随即将会关闭。
用这种方法真是相当简单方便,可是如何设置纸张的类型和打印方向呢,打印份数可以自己用循环控制,我在网上搜了一下,打印属性无非都是DEVMODE结构体进行设置(DEVMODE太长,在此不贴出,可以自己查MSDN),然后用给结构PRINTER_DEFAULTS进行赋值,再将PRINTER_DEFAULTS传给OpenPrinter的第三个参数,就完成了打印属性的设置。但可惜的是往往这种设置都是局部的,只对传递了打印机句柄的打印操作才有效,ShellExecute无法接受打印机句柄。
所以解决的办法就是设置全局打印机属性(6.0编译不能通过)
//设置打印方向如下:
int SetPrinterOrientation(short dmOrientation)
{
HANDLE hPrinter = NULL;
DWORD dwNeeded = 0;
PRINTER_INFO_2 *pi2 = NULL;
DEVMODE *pDevMode = NULL;
PRINTER_DEFAULTS pd;
BOOL bFlag;
LONG lFlag;
LPTSTR pPrinterName = NULL;
DWORD size;
GetDefaultPrinter(NULL, &size);
TCHAR* buffer = new TCHAR[size];
if(GetDefaultPrinter(buffer, &size))
pPrinterName = buffer;
else
{
if(buffer != NULL)
delete buffer;
return 0;
}
ZeroMemory(&pd, sizeof(pd));
pd.DesiredAccess = PRINTER_ALL_ACCESS;
bFlag = OpenPrinter(pPrinterName, &hPrinter, &pd);
if (!bFlag || (hPrinter == NULL))
{
if(buffer != NULL)
delete buffer;
return 0;
}
SetLastError(0);
bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
if ((!bFlag) && (GetLastError() !=
ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
{
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
if (pi2 == NULL)
{
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
bFlag = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
if (pi2->pDevMode == NULL)
{
dwNeeded = DocumentProperties(NULL, hPrinter,
pPrinterName,NULL, NULL, 0);
if (dwNeeded <= 0)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
pDevMode = (DEVMODE *)GlobalAlloc(GPTR, dwNeeded);
if (pDevMode == NULL)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
lFlag = DocumentProperties(NULL, hPrinter,
pPrinterName, pDevMode, NULL,DM_OUT_BUFFER);
if (lFlag != IDOK || pDevMode == NULL)
{
GlobalFree(pDevMode);
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
pi2->pDevMode = pDevMode;
}
if (!(pi2->pDevMode->dmFields & DM_ORIENTATION))
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return 0;
}
pi2->pDevMode->dmFields = DM_ORIENTATION;
int OriginalOrientation = pi2->pDevMode->dmOrientation;
pi2->pDevMode->dmOrientation = dmOrientation;
pi2->pSecurityDescriptor = NULL;
lFlag = DocumentProperties(NULL, hPrinter, pPrinterName,
pi2->pDevMode, pi2->pDevMode,
DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag != IDOK)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return 0;
}
bFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return 0;
}
SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,
(LPARAM)(LPCSTR)pPrinterName, SMTO_NORMAL, 1000, NULL);
if (pi2)
GlobalFree(pi2);
if (hPrinter)
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return OriginalOrientation;
}
//设置纸张类型如下:
BOOL SetPaperType(short dmPaperSize)
{
HANDLE hPrinter = NULL;
DWORD dwNeeded = 0;
PRINTER_INFO_2 *pi2 = NULL;
DEVMODE *pDevMode = NULL;
PRINTER_DEFAULTS pd;
BOOL bFlag;
LONG lFlag;
LPTSTR pPrinterName = NULL;
DWORD size;
GetDefaultPrinter(NULL, &size);
TCHAR* buffer = new TCHAR[size];
if(GetDefaultPrinter(buffer, &size))
{
pPrinterName = buffer;
}
else
{
if(buffer != NULL)
delete buffer;
return FALSE;
}
ZeroMemory(&pd, sizeof(pd));
pd.DesiredAccess = PRINTER_ALL_ACCESS;
bFlag = OpenPrinter(pPrinterName, &hPrinter, &pd);
if (!bFlag || (hPrinter == NULL))
{
if(buffer != NULL)
delete buffer;
return FALSE;
}
SetLastError(0);
bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
if ((!bFlag) && (GetLastError() !=
ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
{
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
if (pi2 == NULL)
{
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
bFlag = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
if (pi2->pDevMode == NULL)
{
dwNeeded = DocumentProperties(NULL, hPrinter,
pPrinterName,NULL, NULL, 0);
if (dwNeeded <= 0)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
pDevMode = (DEVMODE *)GlobalAlloc(GPTR, dwNeeded);
if (pDevMode == NULL)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
lFlag = DocumentProperties(NULL, hPrinter,
pPrinterName, pDevMode, NULL,DM_OUT_BUFFER);
if (lFlag != IDOK || pDevMode == NULL)
{
GlobalFree(pDevMode);
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return FALSE;
}
pi2->pDevMode = pDevMode;
}
pi2->pDevMode->dmFields = DM_PAPERSIZE;
pi2->pDevMode->dmPaperSize = dmPaperSize;
pi2->pSecurityDescriptor = NULL;
lFlag = DocumentProperties(NULL, hPrinter, pPrinterName,
pi2->pDevMode, pi2->pDevMode,
DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag != IDOK)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return FALSE;
}
bFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return FALSE;
}
SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,
(LPARAM)(LPCSTR)pPrinterName, SMTO_NORMAL, 1000, NULL);
if (pi2)
GlobalFree(pi2);
if (hPrinter)
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return TRUE;
}