打印

PowerPrint 1.1 DLL(最老牌的dll文件,几年以前本站独家提供的,现在已经被广泛使用) 
http://www.pdriver.com/display.asp?key_id=1084

在win2000/xp/2003server中自定义纸张打印票据  这是通过输出打印机控制命令来控制针式打印机的,通用性不够好。
http://www.pdriver.com/display.asp?key_id=1537
正文:
作者:李刚 email: zzutligang@hotmail.com 
下载2003/12/26月最新版本 www.pdriver.com/pb03/12/printNewCtrl.rar (size :125kb) 已增加功能:
增加了获得打印作业的功能,同时可以对打印作业进行控制,例如:暂停,恢复,取消,重新开始等。
关于无法获得当前打印机是否缺纸的问题,我发现在Windows中也没有直接获得打印机是否缺纸的功能,但如果你将文档送到打印机,在打印机队列管理中的状态中可以看见有缺纸的提示。所以,我建议各位如何想监视是否缺纸,可以通过获得打印机打印作业,然后分析状态中有没有缺纸的状态信息就可以了!
下载:www.pdriver.com/pb03/12/printctrl.rar (size:78kb) pb7版本 (兼容所有pb版本, rar中已经包括有dll文件)


下载:www.pdriver.com/pb03/12/printctrl_vc.rar vc写的dll源代码。关于编译的时候出错请见本文最下方的所示:
内有作者李刚 VC 6 写的 dll 源代码,当然还有 pb7 写的调用 dll 的示例。中间有一些很强的功能。 
“增加自定义纸张” - 这个功能是对 2000/xp 来使用的,是其它很多 DLL 没有的功能。
 
点击增加自定义纸张以后,让我们来看看打印机的属性中增加了什么内容: 
 
 
 
增加的纸张名称,宽度 / 高,左 / 右,上 / 下等值都是在程序中增加的:如下,是 pb 中调用的代码: 
string paperName = " 试验纸张类型 " 
string printerName = "" 
boolean rt 
long w,h,l,r,t,b 
w = 2000 
h = 1500 
l = 10 
r = 10 
t = 20 
b = 20 
if lb_1.TotalItems ( )<=0 then 
messagebox(""," 没有打印机列表,请执行 < 获得打印机列表 > 功能 ") 
return 
end if 
printerName = lb_1.SelectedItem () 
if printerName="" then 
messagebox(""," 请选择一个打印机! ") 
return 
end if 
rt = AddCustomPaper(ref printerName, ref PaperName, w, h, l, r, t, b) 
if rt then 
messagebox(""," 成功 ") 
else 
messagebox(""," 失败 ") 
end if 
在平时的打印中除了可以在程序中选择纸张外,在 windows 系统中也能见到此打印纸张: 
 
 
关于源代码编译的时候会提示出错,请按作者 所示进行如下修改
看来这个问题不仅仅我碰到了,我不知道vc6的winspool.h中为什么没有定义这个函数,但winspool.lib中确实有这个函数。
打开你的winspool.h,将如下代码添加到文件末尾#ifdef __cplusplus这句话的前面,保存重新编译就可以了。
BOOL 
WINAPI 
SetDefaultPrinterA(
       LPCTSTR pszPrinter
       );
BOOL 
WINAPI 
SetDefaultPrinterW(
       LPCTSTR pszPrinter
       );
#ifdef UNICODE
#define SetDefaultPrinter  SetDefaultPrinterW
#else
#define SetDefaultPrinter  SetDefaultPrinterA
#endif // !UNICODE






直接打印不显示设置对话框


HDC PrintDC;
     DOCINFO docin;
    
     docin.cbSize = sizeof(DOCINFO);
     docin.lpszDocName = "TestDoc";
     docin.lpszOutput = NULL;
    
     CPrintDialog PrintDialog(TRUE,PD_ALLPAGES|PD_NOPAGENUMS,NULL);
     // if(!PrintDialog.GetDefaults()) return ; //如果不用打印设置对话框,使这一行有效
    
     if(PrintDialog.DoModal()!=IDOK) return; //显示打印设置对话框(不显示把这一行去掉)
    
     PrintDC = PrintDialog.CreatePrinterDC(); // 返回一个打印DC句柄
    
     //重新定义纸张大小
     DEVMODE* lpDevMode = (DEVMODE*)PrintDialog.GetDevMode();
     lpDevMode->dmPaperSize = DMPAPER_USER; //设定为自定义纸张尺寸
     lpDevMode->dmFields |= DM_PAPERSIZE; //允许重新设置纸张大小
     lpDevMode->dmPaperLength = 300; //设定纸长为 3 厘米
     ResetDC(PrintDC,lpDevMode); //使设置的参数发挥作用
    
     StartDoc(PrintDC,&docin); // 启动打印工作
     StartPage(PrintDC); // 一页开始
     TextOut(PrintDC,0,10,"打印内容",8); //打印内容
     EndPage(PrintDC); // 一页结束
     EndDoc(PrintDC); // 终止打印工作
    
     if(DeleteDC(PrintDC))
     return; // 删除打印机DC
     else
     {
     AfxMessageBox("出错",MB_OK);
     return;
     }





char  szprinter[80];
     char  *szDevice,*szDriver,*szOutput;
     HDC  hdcprint;  // 定义一个设备环境句柄
     //定义一个打印作业
     DOCINFO di = { sizeof (DOCINFO), "printer" ,NULL};
     // 得到设备字符串存入数组szprinter中
     GetProfileString( "windows" , "device" , ",,," ,szprinter,80);
     // 将设备字符串分解
     if (NULL != (szDevice =  strtok (szprinter, "," )) 
         && NULL != (szDriver =  strtok (NULL, "," )) 
         && NULL != (szOutput =  strtok (NULL, "," ))) 
     {
         // 创建一个打印机设备句柄 
         if ((hdcprint = CreateDC(szDriver,szDevice,szOutput,NULL)) != 0) 
        
             CRect rc, rt1, rt2, rt3, rt4, rt5, rt6;
             if (StartDoc(hdcprint,&di) > 0)  //开始执行一个打印作业 
            
                 StartPage(hdcprint);  //打印机走纸,开始打印 
                 SaveDC(hdcprint);  //保存打印机设备句柄 
                 //输出内容
                 TextOut(hdcprint,250,260, "处方号:091-4" ,13); 
                 
                                 ................
                                  RestoreDC(hdcprint,-1);  //恢复打印机设备句柄 
 
                 EndPage(hdcprint);  //打印机停纸,停止打印 
                 EndDoc(hdcprint);  //结束一个打印作业 
                 //MessageBox("打印完毕!","提示",MB_ICONINFORMATION); 
             }
             // 用API函数DeleteDC销毁一个打印机设备句柄 
             DeleteDC(hdcprint); 
        
         else 
        
             MessageBox( "没有默认打印机,或者没有安装打印机!" ); 
             return
         }








利用API打印

介绍: 这一段代码,用以演示《如何在VC++中使用API直接打印》。并且该段代码可以直接嵌入各种工程中,有实际使用的价值。 
  用途: 在Visual C++中,应用程序通常是使用CView中提供的打印功能,在OnPrint()或OnDraw()中向打印机输出。但是对于对话框中的数据,或基于对话框的程序,打印成了一件繁琐的工作。

  该段代码向用户提供了PrintListCtrl()函数,用于打印用户在对话框或FormView中的CListCtrl(控件必须是Report View 形式的)控件中的内容。在打印过程中,根据控件中每列标题的宽度计算打印输出时各列的宽度,并根据数据的行数自动分页。在本代码的基础上稍作修改,就可以适应各种数据的输出。

  用法: 该段代码使用Visual C++ 6.0, 使用Windows API来完成所需功能,使用时将本文本作为头文件使用。打印时直接调用PrintListCtrl(),函数的参数为所要打印的ListCtrl。

*/

//该结构用于存储各列的信息

typedef struct tagColAtt
{
int nColIndex;
CString strColText;
int nPrintX;
int nSubItemIndex;
}COLATT;

BOOL PrintListCtrl(CListCtrl& list)
{
PRINTDLG pd;
pd.lStructSize = sizeof(PRINTDLG);
pd.Flags = PD_RETURNDC;
pd.hDC = NULL;
pd.hwndOwner = NULL;
pd.hInstance = NULL;
pd.nMaxPage = 1;
pd.nMinPage = 1;
pd.nFromPage = 1;
pd.nToPage = 1;
pd.nCopies = 1;
pd.hDevMode = NULL;
pd.hDevNames = NULL;

//显示打印对话框,由用户来设定纸张大小等。
if(!PrintDlg(&pd)) 
   return FALSE; 

ASSERT(pd.hDC!=NULL);

int nHorRes = GetDeviceCaps(pd.hDC, HORZRES); 
int nVerRes = GetDeviceCaps(pd.hDC, VERTRES);
int nXMargin = 2;
int nYMargin = 2;
TEXTMETRIC tm;
GetTextMetrics(pd.hDC, &tm);
int nCharHeight = tm.tmHeight;
int nCharWidth = tm.tmAveCharWidth;


CHeaderCtrl* pHeader = list.GetHeaderCtrl();
//获得行,列的个数
int nColCount = pHeader->GetItemCount();
int nLineCount = list.GetItemCount();

int ColOrderArray[100];
COLATT ca[100];
list.GetColumnOrderArray(ColOrderArray, nColCount);
int nColX =nXMargin*nCharWidth;

//检索各列的信息,确定列标题的内容长度。
for(int i=0 ; i<nColCount; i++)
{
   ca[i].nColIndex = ColOrderArray[i];
   LVCOLUMN lvc;
   char text[100];
   lvc.mask = LVCF_TEXT|LVCF_SUBITEM;
   lvc.pszText =(LPWSTR)text;
   lvc.cchTextMax = 100;
   list.GetColumn(ca[i].nColIndex, &lvc);
   ca[i].strColText = lvc.pszText;
   ca[i].nSubItemIndex = lvc.iSubItem;
   ca[i].nPrintX = nColX;

   nColX += nCharWidth * wcslen(ca[i].strColText);

   if(nColX > nHorRes) 
   {
    DeleteDC(pd.hDC);
    AfxMessageBox(_T("字段太多,无法在一行内打印,请试用较大的纸,或横向打印。"));
    return FALSE;
   }
}

DOCINFO di;
di.cbSize = sizeof(DOCINFO);
di.lpszDocName =_T("ListCtrl Data Printing"); 
di.lpszOutput = (LPTSTR) NULL; 
di.lpszDatatype = (LPTSTR) NULL; 
di.fwType = 0; 
StartDoc(pd.hDC, &di);
StartPage(pd.hDC);

//调整各列的宽度,以使各列在后面的打印输出时更均匀的打印在纸上。
int space = (nHorRes-nXMargin*nCharWidth-nColX)/nColCount;
for(int i=1; i<nColCount; i++)
{
   ca[i].nPrintX += i*space;
}

//输出列标题
for(int i=0; i<nColCount; i++)
   TextOut(pd.hDC,ca[i].nPrintX, nYMargin,ca[i].strColText, wcslen(ca[i].strColText));

int nMaxLinePerPage = nVerRes/nCharHeight -3;
int nCurPage =1;
//输出各列的数据
for(int i=0; i<nLineCount; i++)
{
   for(int j =0; j<nColCount; j++)
   {
    if(i+1-(nCurPage-1)*nMaxLinePerPage > nMaxLinePerPage)
    {
     //新的一页
     EndPage(pd.hDC);
     StartPage(pd.hDC);
     nCurPage ++;
    }
    CString subitem = list.GetItemText(i, j);
    TextOut(pd.hDC, ca[j].nPrintX, nYMargin+(i+1-(nCurPage-1)*nMaxLinePerPage)*nCharHeight, subitem, wcslen(subitem));
   }
}
EndPage(pd.hDC);
EndDoc(pd.hDC);
//打印结束
DeleteDC(pd.hDC);
return TRUE;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值