打印机编程

打印机编程 - 初级入门篇 具体步骤: 获得打印机DC(设备环境句柄).开始打印(StartDoc).开始一页(StartPage).对DC进行绘图操作,就像往窗口上画图一样。结束一页(EndPage).结束打印(EndDoc)或转到第3步再开始新的一页.删除打印创建的资源,如:释放DC(ReleaseDC)、删除字体、画笔、画刷之类的对象(DeleteObject) 第一步: 获得打印机DC(设备环境句柄 阅读详情
1.1--打印机编程 
1.1 .1 打印机介绍


1.打印术语
   cpi(characters Per Inch) 每英寸内所含的字符数,用来表示字符的大小、
   间距。
   cpl(Characters Per Line) 每行中所含的字符个数,用来在横向表示字符
   的宽度和间距。
   cps(Character Per Second):每秒所能打印的字符个数,用来表示打印机的打
   印速度。当然它和打印的字符大小与笔划有关。一般以10cpi的西文字符为基准
   来计算打印速度.
   dpi(Dot Per Inch)每英寸所打印的点数(或线数),用来表示打印机打印分辨.这是
   衡量打印机打印精度的主要参数之一.该值越大表明打印机的打印精度越高.
   lpi(Lines Per Inch): 每英寸所含的行数,用来表示在垂直方向字符的大小
   间距.
   ppm(Papers Per Minute):每分钟打印的页数,这是衡量打印机打印速度的
   重要参数,是指连续打印时的平均速度.
   
   在大多数的Internet及多媒体应用软件中,为使画面下载速度增快,大都是采
   用72dpi或75dpi的低解析度影像,如果仅从屏幕上观看,画质还可以,但是当
   使用解析度较高的打印机打印出来时,就会发生如锯齿状或是模糊不清的问题.
   这主要的原因在于原始影像本身的像素不能呈现高解析度的输出品质.
   因此,无论使用的打印机品质或解析度多高,打印品质仍不理想.使用HP SmartFocus
   智慧聚焦技术的打印机驱动程序,将低品质的影像自动地做解析度提升的处理.
   这样一来,就可以打印出较清晰的影像.
   
   sRGB:(standard Red Green Blue)是一种彩色语言协定.它提供了一个标准方法来定义
   色彩.让计算机的周边设备与应用软件对于色彩有一个共通的语言.sRGB是由HP和微软
   共同推出的开放业界标准.


2.打印机技术指标
  (1) 打印质量
  衡量图像清晰程度最重要的指标就是分辨率(dpi每平方英寸多少个点).
  300dpi是人眼分辨打印文本与图像的边缘是否有锯齿的临界点.再考虑
  到其他的一些因素,只有360dpi以上的打印效果才能基本令人满意.要将
  基色组成的色点转换成印刷上由四色墨水喷出的各种色彩效果,就需要
  由色彩转换的驱动程序来实现.目前各打印机厂商均有自已的图像调整技术.
  
  (2)打印速度
  打印机的打印速度是每分钟打印多少页纸(PPM),打印机速度与打印的色彩和
  打印分辨有关.
  
  (3)色彩数目
  更多的彩色墨盒数就意味着更丰富的色彩.有红、黄、蓝三色单墨盒。还有
  黑、淡蓝和淡红的六色打印机。
  
  1.1.2 分辨率
  分辨率是一个表示平面图像精细程序的概念,通常它是以横向和纵向点的数量来衡量的,
  表示成:水平点数*垂直点数的形式.在一个固定的平面内,分辨率越高,图像越细致.
  分辨率有多种.在显示器上有表示显示精度的显示分辨率,在打印机上有表示打印精度的
  打印机分辨率.
  
  1、显示分辨率
  显示分辨率是显示器在显示图像时的分辨率。显示分辨率的数值是指整个显示器所有
  可视面积上水平像素和垂直像素的数量.例如:800*600的分辨率是指在整个屏幕上水平
  显示800个像素,垂直显示600个像素.显示分辨率的水平像素和垂直像素的总数总是成一
  定的比例:一般为4:3,5:4,8:5
  
  2、打印机分辨率
  打印机分辨率直接关系到打印机输出图像或文字的质量好坏。打印机分辨率用dpi(dot per inch)
  来表示。喷墨打印机和激光打印机的分辨率通常是相同的.例如:打印机分辨率为600dpi,
  是指打印机在一平方英寸的区域内垂直打印600个点,水平打印600个点.总共可打印360000个点.






1.2--打印机编程基础(未完) 
1.2编程基础
  下面将了解打印编程中至关重要的两个概念"设备环境"和"映射模式"
  1.2.1设备环境
  设备环境本身是GDI(Graphics Device interface)对象.每个C++设备对象有一个相关的设备环境.它由
  一个32位HDC类型句柄来标识.GDI是Windows核心DLL中的一组接口函数.这些函数处于硬件的驱动程序
  之上.当应用程序调用这些函数的时候,它们再调用驱动程序提供的接口函数.
  
  1.CDC类
  使用MFC编程,所用的设备环境不是CDC就是从CDC派生的。CDC类中有两个与底层
  GDI对象有关的句柄m_hDC和m_hAttribDC.与m_hDC相关的GDI对象处理绘图函数的所有
  输出流;与m_hAttribDC句柄有关的GDI对象处理所有与绘图属性有关的操作。如颜色属性
  和绘图模式。
  
  每个窗口、控件都拥有一个覆盖窗口或控件的设备环境。我们可以使用任何一个控件的设备环境,
  从而绘制控件或者改善倥件的外观。
  
  获得设备环境对象指针需要调用GetDC函数。在构造一个CDC对象,并且对它处理完之后,务必使用
  ReleaseDC()函数将CDC对象释放。
  
  GetDC()函数和ReleaseDC()函数是CWnd类的成员函数,任何CWnd类及其派生类都可以通过调用它获得
  和释放设备环境对象。
  
  2. CClientDC和CWindowDC
  窗口客户区不包括边框、标题栏和菜单栏,创建CClientDC对象将获得客户区的设备
  环境。构造CClientDC对象,只需要向它传递一个指向窗口的指针,GetDC()函数会被
  自动调用。当ClientDC对象被销毁时,它会自动调用ReleaseDC()函数。
  
  CClientDC派生于CDC,在构造时调用了Windows函数GetDC,在析构时调用了ReleaseDC.
  和CClientDC对象相关的设备上下文是窗口的客户区.
  
  CClientDC 构造一个连接到CWnd上的CClientDC对象.
  CClientDC(CWnd *pWnd);
  throw (CResourceException);
  参数:
  pWnd:设备上下文将要存取的客户区所在的窗口.
  
  CWindowDC能够在整个应用程序窗口上绘图,包括标题栏和窗口边框。一般情况下CWindowDC
  对象很少用,但是当读者不欢喜Windows标准窗口标题栏的样式和按钮,就可以应用它了。
  
  CWindowDC类是从CDC继承的,它在构造的时候调用Windows函数GetWindowDC,在销毁的时候调用ReleaseDC.
  这意味着CWindowDC对象可以访问CWnd的全部屏幕区域(包括客户区和非客户区).
  
  
  AfxGetMainWnd()函数用于获得框架(包括标题栏、菜单栏、状态栏、边框)窗口的指针。
  AfxGetMainWnd()获得主框架窗口指针。
  
  
  
  3、CPaintDC
  CPaintDC类是一个特殊的设备环境封装类。它用来处理来自Windows的WM_PAINT消息。
  当窗口上覆盖的其他窗口移走,或者窗口最小化后又最大化时,窗口就会收一个系统
  发来的WM_PAINT消息,这时应用程序就会重画可见的区域。这个被重画的区域,我们称
  它为无效区域。WM_PAINT消息发出后,Windows会帮助用户判断哪些区域需要重画,哪些
  区域保持不变,从而加快窗口的显示速度。
  
  CPaintDC类有一个成员变量m_ps,m_ps有一个RECT类型的成员变量rcPaint.这个矩形变量
  保存了需要重画的矩形区域,即无效区域。m_ps是一个PAINTSTRUCT结构类型的变量。
  
  PAINTSTRUCT结构的定义如下所示:
  typedef struct tagPAINTSTRUCT
  {
     HDC hDC;
     BOOL fErase;
     RECT rcPaint;
     BOOL fRestore;
     BOOL fIncUpdate;
     byte rgbReserved[32];
  }PAINTSTRUCT;
  
  hdc是底层的GDI设备环境对象的句柄.Ferase标志判断背景是否被清除,如果这个标志
  被设置为TRUE,在重画之前将清除背景.rcPaint 保存了窗口无效区域(即需要重画的
  区域).最后三个变量被声明为保留变量.一般不改动.
  
  4、内存设备环境
  内存设备环境是一个没有设备与它联系的环境。我们一般利用与某个标准设备环境兼容
  的内存设备环境把一个位图复制到屏幕上去。为此可以先创建一个与某个标准设备环境兼容
  的内存设备环境,然后把所要显示的位图复制到内存设备环境中,最后再从内存设备环境复
  制到真正的设备环境,从而把位图显示出来。
  还可以创建内存设备环境对象,使用该对象在内存中绘图来代替在屏幕上绘图,绘制完成后,
  再调用BitBlt()函数把它复制到屏幕上去。这种方法绘图可以克服屏幕闪烁现象。
  
  CGdiObject::GetObject 把描述了将Windows GDI对象附加给CGdiObject对象的数据填充到缓冲区。
  int GetObject(int nCount,LPVOID lpObject)const;
  返回值:获取的字节数。如果发生错误,则返回0
  参数:
  nCount 指定要拷贝到lpObject缓冲区的字节数
  lpObject 指向用户应用缓冲区的指针以接收信息。
  说明:
  用定义指定对象的数据填充缓冲区。函数获得一个类型由图像对象决定
  的数据结构,列表如下所示:
  LoadBitmap  从应用的可执行文件中加载一个命名的位图资源来初始化位图对象。
  
  CDC::BitBlt 从指定设备上下文拷贝位图
  BOOL BitBlt(int x,int y,int nWidth,int nHeight,CDC *pSrcDC,int xSrc,int ySrc,DWORD dwRop);
  返回值:函数成功,返回非零值,否则为0
  
  参数:x 指定目标矩形左上角的逻辑x坐标
        y 指定目标矩形左上角的逻辑y坐标
        nWidth 指定目标矩形矩形和源位图的宽度(逻辑单位)
        nHeight 指定目标矩形和源位图的高度(逻辑单位)
        pSrcDC  指向CDC对象的指针,标识待拷贝位图的设备上下文。
        xSrc    指定源位图左上角的逻辑x坐标
        ySrc    指定源位图左上角的逻辑y坐标
        dwRop   指定要执行的光栅操作。
  CDC::CreateCompatibleDC 创建内存设备上下文,与另一个设备上下文匹配。可以
  用它在内存中准备图像。
  virtual BOOL CreateCompatibleDC(CDC *pDC);
  返回值:如果成功,则返回非零值,否则为0
  参数:
  pDC 设备上下文指针。如果pDC为NULL,函数将产生与系统兼容的内存设备上下文。
  说明:
  产生与pDC指定设备兼容的设备上下文内存,设备上下文内存包含显示表面的信息,
  它用于在向实际的兼容设备表面发送图像之前在内存中作好准备。
  
  void CPrintProjView::OnDrawBitmap()
  {
    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_BITMAP1);
    BITMAP bmpInfo;
    CDC *pDC = GetDC();
    CDC memDC;
    memDC.CreateCompatibleDC();
    CBitmap *pBitmap = memDC.SelectObject(&bitmap);
    bitmap.GetObejct(sizeof(bmpInfo),&bmpInfo);
    pDC->BitBlt(0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,&memDC,0,0,SRCCOPY);
     memDC.DeleteDC();
     ReleaseDC(pDC);
  }
  上面这段程序,先获得视图的设备环境,然后声明了一个内存设备环境memDC.
  memDC调用了CreateCompatibleDC()函数,作用是设置内存设备环境的大小等各种属性,
  从而使内存设备环境与屏幕窗口兼容。Bitmap是位图对象,它调用成员函数LoadBitmap
  载入位图;bmpInfo是BITMAP结构类型的变量,它保存了位图的长、宽等信息。
  
  BitBlt()函数把内存设备环境复制到屏幕设备环境。BitBlt()是一个图像复制函数。
  当向函数传递需要复制区域的宽、高度、开始偏移和复制模式这些参数时,它会将需要复制的
  矩形区域从内存设备环境复制到屏幕上。
  
  注意:
  程序中使用的位图类型是GDI位图。有两种类型的Windows位图:GDI位图和DIB位图。
  GDI位图对象是由MFC库的CBitmap类表示的。GDI位图对象有一个与之相关的Windows
  数据结构,它在Windows GDI模块内进行维护,它是与设备相关的。对于GDI位图来说,
  显示器的“位图”实际上就是显示器表面的映像,打印机设备的“位图”是打印机本身。
  因此,不能将位图选入显示设备环境或打印设备环境,这就是为什么必须使用
  CDC::CreateCompatibleDC函数创建一个特殊的内存设备环境。
  
  5、打印机设备上下文
  CDC::CreateDC 为指定设备创建设备上下文
  virtual BOOL CreateDC(LPCTSTR lpszDriverName,
                        LPCTSTR lpszDeviceName,
                        LPCTSTR lpszOutput,
                        const void *lpInitData)
  返回值:如果成功,则返回非零值,否则为0
  参数:
  lpszDriverName:指向空终止字符串的指针,字符串为设备驱动程序的文件名(不带扩展名,
  例如:"EPSON")也可以为该参数传递CString对象。
  
  lpszDeviceName:指向空终止字符串的指针,字符串为支持特定设备的文件名(例如:
  "EPSON FX-80")
  lpszOutput:指向空终止字符串的指针。字符串为指定了物理输出媒介的文件和设备名
  (文件或输出端口).也可以为该参数传递CString对象。
  
  lpInitData:指向DEVMODE结构的指针,该结构包含有指定设备驱动程序的初始数据,Windows
  的DocumentProperties函数从该结构中获得指定设备的信息。如果设备驱动程序使用用户
  在控制面板的缺省值,lpInitData参数一定要设置为NULL.
  
  说明:
  为指定的设备创建设备上下文。
  如果使用DEVMODE结构,就需要PRINT.H头文件。
  
  或者参数作如下说明:
  lpszDriverName是打印机所用的设备驱动程序。
  lpszDeviceName是进行打印的打印设备名称。设备驱动程序可以支持多种打印设备。
  lpszOutput:指定设备的串口名。
  lpInitData:是设备专用的初始化数据。
  使用打印机设备环境之后,必须调用DeleteDC()成员函数销毁它。但是,如果在堆栈
  中创建CDC类,程序返回时,设备环境自动删除。


  至此Windows提供的五个公共设备环境已经全部介绍完了。




1.2.2 映射模式 
 /////////////////////////////////////////////////
 1.2.2 映射模式样
 vc++中采用的坐标映射方式使得用户图形坐标和输出设备的像素完全一致,当屏幕的像素大
 小为800*600时,每逻辑英寸包含的屏幕像素数为96,而打印机则需要多出
 好几倍的点数才能到达同样的逻辑尺寸。例如:HP打印机每逻辑英寸包含的打印机点数为600,
 也就是说打印机的清晰度比屏幕要高很多。这样的后果就是在屏幕上显示出来的满屏幕的图像
 在打印出来的纸上却只有一点点,怎么解决这个问题呢?一种简单的方法就是转换坐标映射方式,
 使得打印时采用的坐标比例比显示时采用的坐标比例相应地大若干倍.
 
 映射模式的意思是在屏幕或者打印机上绘图的时候,可以使用英寸或者毫米作为单位,这样更加直观.
 
 这其中要注意设备单位和逻辑单位的区别:逻辑单位是传递给绘图函数的x和y值,它们可以表示英寸和
 毫米,而设备单位是x和y在屏幕上的像素数,或是打印机上的点阵数。单击鼠标以设备单位返回。如果
 想知道鼠标单击位图的什么位置,需要将设备单位转化为逻辑单位。表1-5所示是可用的映射模式。
 
 映射模式        逻辑单位
 MM_TEXT         一个像素
 MM_LOMETRIC     0.1毫米
 MM_HIMETRIC     0.01毫米
 MM_LOENGLISH    0.01英寸
 MM_HIENGLISH    0.001英寸
 MM_TWIPS        1/1440英寸
 MM_ISOTROPIC    用户定义的值,但是x和y方向相等
 MM_ANISOTROPIC  用户定义的值,但是x和yy方向任意
 
 映射模式通过设备环境类的一个成员函数SetMapMode()来设置.只要把上述标志当作参数
 传入函数即可.设置映射模式后,传给任何绘图函数的坐标值都通过GDI内部的映射机制转
 换成设备坐标.如果把映射模式设置为MM_LOENGLISH,然后向绘图函数传递一个100的逻辑
 单位值,映射模式知道用户实际想要的是100*0.1mm,也就是1cm。
 
 映射模式MM_ISOTROPIC和MM_ANISOTROPIC允许改变比例因子和原点,使用这些模式改变窗
 口大小时,绘制的内容也会改变大小。
 
 使用MM_ISOTROPIC方式,x和y始终保持1:1的比例。如果在屏幕上画了一个圆,无论比例因
 子如何改变,始终还是圆,而在MM_ANISOTROPIC方式中,x和y比例因子可分别改变,圆会被
 压成椭圆。
 
 有一点需要注意:当使用MM_TEXT映射模式时候,y轴的正方向是沿屏幕垂直向下的,x轴是沿屏幕
 向右的.然而,其他的映射模式的y轴正方向是沿屏幕向上的,x轴正方向也是向右的.这一点特别容易
 搞混了.
 
 我们定义两个矩形,设置从逻辑环境到设备环境的转换。第一个矩形以逻辑单位表示绘制区域的大小,
 windows术语称之为窗口,第二个矩形以设备单位(即像素)表示第一个矩形大小代表的设备范围大小,
 在Windows术语中称之为视口,两种关系如图:
 1、设置视口到视图的客户区,并可忘记它。SetViewportOrg(0,0);SetViewPortExt(100,50);
 2、把窗口的初始位置设置在想在逻辑环境中看到的地方:SetWindowOrg(100,100);
 3、要缩小图形,只要缩小窗口的范围。要放大图形,只要增大窗口范围。要滚动图形,只要改变
 窗口的初始位置。
 
 SetWindowOrg()用来改变窗口坐标(逻辑坐标)的原点,SetViewPortOrg()用来改变视口坐标(设备坐标)
 的原点。
 void CPrintProjView::OnDraw(CDC *pDC)
 {
    pDC->SetMapMode(MM_TEXT);
    pDC->SetViewPortOrg(50,50);
    pDC->SetWindowPortOrg(200,200);
    CPen myPen(PS_SOLD,1,RGB(0,255,0));
    Cpen *pOldPen = pDC->SelectObject(&myPen);
    pDC->TextOut(200,200,_T("窗口映射模式"));
    pDC->Rectangle(200,200,400,400);
    pDC->SelectObject(pOldPen);
    myPen.DeleteObject();
 }
 这段代码,把视口原点设置为设置坐标(50,50),把窗口原点设置为逻辑坐标(200,200),
 然后通过窗口原点(200,200)绘制一个长宽各为200的方框.逻辑点(200,200)映射到设备
 点(50,50),即把窗口原点映射到视口原点.
 
 SetWindowExt()用来设定逻辑环境的大小,SetViewPortOrg()用来设定设备环境的大小.映射
 模式MM_ISOTROPIC和MM_ANISOTROPIC允许调用SetWindowExt()和SetViewPortExt()函数来设置
 设备坐标和逻辑坐标之间的比例.
 
 可以用下面的公式实现逻辑单位到设备单位的转换:
 x比例因子 = x视口长度/x窗口长度
 y比例因子 = y视口长度/y窗口长度
 设备x = 逻辑x * x比例因子 + x原点偏移量
 设备y = 逻辑y * y比例因子 + y原点偏移量
 设备环境本身提供了两个函数实现逻辑坐标和设备坐标之间的互换.DPtoLP()函数,可以
 接受一个指向CPoint类或者CRect类对象的指针作为参数,然后把它所指向的对象从设备
 坐标转换为逻辑坐标,LPtoDP的作用正好相反.
 
 下面这段程序根据GetClientRect()函数返回窗口客户矩形,函数SetWindowExt和SetViewportExt
 一起设置比例,结果窗口大小恰好是800*800,SetViewPortOrg函数把原点放置在窗口中心.这样椭
 圆恰好充满整个屏幕.
 
 void CPrintProjView::OnDraw(CDC *pDC)
 {
   CRect rcClient;
   GetClientRect(&rcClient);
   pDC->SetMapMode(MM_ANISOTROPIC);
   pDC->SetWindowExt(800,800);
   pDC->SetViewportExt(rcClient.right/2,rcClient.bottom/2);
   CPen myPen(PS_SOLID,1,RGB(255,0,0));
   CPen *pOldPen = pDC->SelectObject(&myPen);
   pDC->Ellipse(-400,-400,400,400);
   pDC->SelectObject(pOldPen);
   myPen.DeleteObject();
 }
 注意:SetWindowExt()和SetViewPortExt()函数只有在MM_ANISOTROPIC和MM_ISOTROPIC模式下才有效,
 在其他模式下,对它们的调用将被忽略。无论彩用哪种映射模式,GetClientRect()和GetWindowRect()
 函数返回的都是设备坐标(即像素)。




1.2.3 MFC的打印功能分析
 
 1.框架中的打印
 MFC的框架内置了功能强大的打印和打印预览功能。首先,分析MFC应用程序框架打印的内在机制,
 这样将能更有效地使用打印机。
 
 在视图类及其派生类中,通过重载OnDraw(CDC*pDC)函数,利用它提供的pDC(设备上下文)指针,可以在
 屏幕上显示各种图形和数据。CView类的打印是通过OnPrint(CDC *pDC,CPrintInfo*pInfo)这个函数实现
 的,OnPrint()函数对打印的实现就是简单的调用OnDraw(CDC*pDC)这个函数,把打印机的设备上下文
 指针pDC传递给OnDraw(CDC *pDC)函数。可见CView类对输出到屏幕和输出到打印机的处理都是一样的,
 只是换了一个设备上下文而已(输出到屏幕时是通过OnPaint()函数实现的)。
 
 如果重载OnPrint()函数,可以选择根本不调用OnDraw来支持打印逻辑。OnPrint有两个参数,一个是指向
 打印机设备环境的指针,一个是打印信息对象CPrintInfo的指针,该信息包括纸张大小、当前页码和最大
 页码。对每个需要打印的页,应用程序框架都要调用一次OnPrint(),在OnPrintInfo结构中记录着当前页码。
 
 视图类及其派生类在进行显示和打印之前都会调用virtual void OnParepareDC(CDC *pDC,CPrintInfo* pInfo = null)
 这个虚成员函数来准备设备上下文,可以重载这个虚成员函数,进行坐标转换。下面是MFC框架打印的基本流程:
 
    OnPreparePrint---->设置起始和终止页  
       |
    OnBeginPrinting---->创建GDI对象
       |
    OnPrepareDC(每页)---->设置映射模式,并选择检测打印任务的结尾
       |
    OnPrint(每页)----->打印输出
       |
    是否打印完毕
       |
       y
    OnEndPrinting--->删除GDI对象
 
 CDC::GetDeviceCaps 获得指定设备的信息。
 int GetDeviceCaps(int nIndex)const;
 返回值:如果成功,则返回需要的能力值。
 LOGPIXELSX:沿显示宽度方向,每一逻辑单位的像素数。
 LOGPIXELSY:沿显示高度方向,每一逻辑单位的像素数。
 
 
 
 void CPrintProjView::OnDraw(CDC *pDC)
 {
   pDC->TextOut(400,200,_T("Hello word"));
 }
 
 BOOL CPrintProjView::OnPreparePrinting(CPrintInfo*pInfo)
 {
    pInfo->SetMaxPage(2);
    return DoPreparePrinting(pInfo);
 }
 
 void CPrintProjView::OnPrepareDC(CDC *pDC,CPrintInfo *pInfo)
 {
    CView::OnPrepareDC(pDC,pInfo);
    pDC->SetMapMode(MM_ANISOTROPIC); //转换坐标映射方式
    CSize size = CSize(800,560);
    pDC->SetWindowExt(size);//确定窗口的大小
    //得到实际设备每逻辑英寸的像素数量
    int xLogPixelPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
    int yLogPixelPerInch = pDC->GetDeviceCaps(LOGPIXELSY);
    
    //得到设备坐标和逻辑坐标的比例
    long xExt = (long)size.cx * xLogPixelPerInch / 96;
    long yExt = (long)size.cy * yLogPixelPerInch / 96;
    pDC->SetViewportExt((int)xExt,(int)yExt); //设置视口大小
 }
 
 在上面的程序中,首先将坐标映射方式改变为MM_ANISOSTROPIC方式,即各向异性的意思,
 在这种坐标方式下,x轴和y轴的逻辑单位可以进行任意的缩放。改变坐标映射方式后,就要
 确定窗口大小和视口大小,注意窗口大小就是我们在屏幕上所见的尺寸,,而视口大小是实际
 设备,如打印机等,和显示设备每逻辑英寸的像素数量比较所得的比例尺.
 
 通过函数得到显示器和打印机每逻辑英寸的像素数量,然后对视口大小进行相应的缩放,就可以
 使屏幕上的显示和打印机的输出是一致了.
 
 编译、运行程序,使用打印预览功能,会看到在两个视图和预览两个页面中"Hello word"的位置是
 一样的。
 
 下次在看的时候,将这一部分再串一下。注意下面几点。
 1、只有在MM_ANISOTROPIC和MM_ISOTROPIC映射模式下,SetWindowExt和SetViewportExt才起作用。
    MM_ANISOTROPIC和MM_ISOTROPIC的区别是:
    MM_ANISOTROPIC是不锁定纵横比,也就是x和y各向异性,x和y轴的逻辑单位可以任意缩放。
    MM_ISOTROPIC:是锁定纵横比,x和y轴的比值是1:1
    
 2、SetWindowExt()设置窗口的x和y轴范围,也就是窗口的大小
    SetViewportExt()设置视口的x和y轴范围,也就是视口的大小
 
 3、窗口大小是指:我们在屏幕上所见的尺寸
    视口大小是指:实际设备,如打印机等.
    
2、框架之外的打印
   框架实现了对打印的一些底层支持,直接的打印机制是通过函数StartDoc和EndDoc()来实现的。应用程序
   要使用打印机时,它首先使用CreateDC或PrintDlg来获取指向打印机设备环境的一个句柄,这就使得打印机
   设备驱动程序库模块被加载到内存(如果还没有加载到内存的话),并进行初始化。然后,程序调用StartDoc
   函数,通知一个新文档开始了。StartDoc函数是由GDI模块来处理的。GDI模块调用打印机设备驱动程序中的
   control函数告诉打印机准备打印。
   
   打印一个文档的过程以StartDoc调用开始,以EndDoc调用结束。调用StartPage来开始一页,调用EndPage来
   结束该页。
   
   下面这段代码在对话框中实现了对打印的支持。
   /*
   GetPrinterDC 获取设备环境的句柄。
   HDC GetPrinterDC()const;
   返回值:
   如果成功则返回一个打印机设备环境的句柄;否则返回null.
   说明:
   如果CPrintDialog构造函数的参数bPrintSetupOnly是FALSE(表明显示的是Print对话框,则GetPrinterDC返回一个
   打印机设备环境句柄。当你使用完这个设备环境时,你必须调用Windows DeleteDC函数来删除它。)
   */
   /*
   {
     long cbSize,
     CString lpszDocName,
     CString lpszOutput
   } DOCINFO;
   对文档进行定义的一个结构。
   cbSize:结构的大小
   lpszDocName:文档的名字
   lpszOutput:输出文档的名字
   */
   /*
   StartDoc:开始新的打印作业
   CDC::StartDoc
   int StartDoc(LPDOCINFO lpDocInfo);
   返回值:如果出错,例如存储空间不足或指定端口无效,则返回-1否则返回正值。
   参数:
   lpDocInfo: DOCINFO结构的指针。该结构包含了文档文件和输出文件的名字。
   
   说明:
   通知设备的驱动程序开始一个新的打印作业,其后所有的StartPage和EndPage调用处于假
   脱机状态,直到EndDoc调用出现。这确保了长于一页的文档不被其它作业中断。   
   */
   /*
   EndDoc  结束由StartDoc成员函数启动的打印作业。
   CDC::EndDoc
   int EndDoc();
   返回值:
   如果成功,则返回值大于零或等于零,出错则返回值小于零。下面列出了一般的错误
   类型:
   SP_ERROR:一般错误。
   SP_OUTOFDISK:假脱机所需的磁盘空间不足,没有其它可用的磁盘空间。
   SP_OUTOFMEMORY:假脱机所需的内存不足。
   SP_USERABORT: 用户在打印管理中中止作业。
   
   说明:
   中止由StartDoc成员函数调用的打印作业。在成功完成打印作业后应立即调用。
   如果应用遇到打印错误或取消的打印操作,决不可用EndDoc或AbortDoc去中止
   操作,GDI在返回错误值之前自动中止操作。   
   */
   /*
   StartPage:通知设备的驱动程序开始新页。
   CDC::StartPage
   int StartPage
   说明:
   调用该成员函数使用打印机驱动程序做好准备接收数据。在StartPage和EndPage之间,
   ResetDC成员函数不起作用。
   */
   /*
   EndPage:通知打印机驱动程序打印页结束。
   CDC::EndPage
   int EndPage()
   返回值:如果成功,则返回大于或等于零的值,如果失败则返回如下错误类型:
   SP_ERROR:一般错误
   SP_APPABORT: 作业终止
   SP_USERABORT:用户在打印管理中中止作业。
   SP_OUTOFDISK:假脱机所需的磁盘空间不足。
   SP_OUTOFMEMORY:假脱机所需的内存不足。
   
   说明:
   通知设备已经写完一页。该成员函数通常用在打印机驱动程序开始新的一页。
   */
   /*
   AbortDoc:终止当前打印任务,擦除自上次调用StartDoc成员函数以业写入设备的任何内容。
   CDC::AbortDoc
   int AbortDoc();
   返回值:如果成功,则返回大于或等于零的值,如果出现错误,则为负值。与EndPage和
   EndDoc返回的错误类型值一样。
   说明:
   终止当前打印任务,并擦除自上次StartDoc以后写入设备的任何任务。
   */
   
   /*
   CPrintInfo没有基类。
   CPrintInfo存储有关一次打印或打印预览的信息。每次选择Print或PrintPreview命令,框架
   就会创建一个CPrintInfo对象。并在命令完成时删除此对象。
   
   CPrintInfo包含打印时的一般信息,例如:要打印页的范围,打印机的状态,当前正在打印的页
   这些信息存放在CPintInfo的对象中;此对象还包括在CPrint对话框中输入的值。
   
   在打印期间,一个CPrintInfo对象在框架和视图类之间传递,并且用于两者之间交换信息。例如:
   框架通过对CPrintInfo类的m_nCurPgae成员赋值,来通知视图类要打印文档的哪一页,视图类检索
   此值,并执行指定页的实际打印。
   
   另一个例子就是文档的长度到打印的时候也不知道多少页。视图类每打印一页都要检测是否到了文档的
   末尾。当到达文档的末尾时,视图类将CPrintInfo的m_bContinuePrinting成员设置为FALSE,通知框架
   停止打印循环。
   */
   /*
   Attach:把Windows设备上下文句柄附加在CDC对象上。
   CDC::Attach
   BOOL Attach(HDC hDC);
   返回值:如果成功,返回非零值,否则为0
   参数:
   hDC:Windows设备上下文。
   说明:
   使用这个函数把hDC附加到CDC对象上。
   */
   /*
   Detach:从CDC对象中分离出Windows设备上下文。
   CDC::Detach
   HDC Detach()
   返回值:Windows设备上下文句柄。
   说明:
   调用该函数将m_hDC从CDC对象中分离出来。并将m_hDC与m_bAttribDC设备为NULL。
   */
   void CPrintProj::Print()
   {
    CDC dc;
    CPrintDialog printDlg(FALSE);
       //利用CPrintDialog生成打印机设备环境
    if(printDlg.DoModual() == IDCANCEL) //让用户选择打印纸张等
       return;
    dc.Attach(printDlg.GetPrinterDC());//让Handle连接到dc上.
    dc.m_bPrinting = TRUE;


    CString strTitle;
    strTitle.LoadString(AFX_IDS_APP_TITLE);


    DOCINFO di; //DOCINFO中有相关的打印信息
    ::ZeroMemory(&di,sizeof(DOCINFO));
    di.cbSize = sizeof(DOCINFO);
    di.lpszDocName = strTitle; //设置标题


    BOOL bPrintingOK = dc.StartDoc(&di); //开始打印


    CPrintInfo Info;
    Info.m_rectDraw.SetRect(0,0,dc.GetDeviceCaps(HORZRES),dc.GetDeviceCaps(VERTRES)); //设置范围.


       OnBeginPrinting(&dc,&Info); //调用你自定义的打印功能.
    fo(UINT page = Info.GetMinPage();page < Info.GetMaxPage() && bPrintOK;page++)
    {
     Info.m_nCurPage = page;
     OnPrint(&dc,&Info); //调用你的"Print page"函数
     bPrintOK = dc.EndPage() > 0; //结束页
    }
    OnEndPrinting(&dc,&Info);//结束打印.


    if(bPrintingOK)
     dc.EndDoc();
    else
     dc.AbortDoc();
    dc.Detach();
   }
   
   说明:其实在Windows环境中是设备无关的.只要有了DC,就可以使用各种GDI函数,而不需要理会是在屏幕或是在
   打印机上绘图.




第2章      打印机基本控制技术


  打印编程之所以比较复杂,在于其需要处理的信息比较复杂.假如编程打印一张报表,我们不但要处理文本信息、
  完成表格绘制、版面编排等,而且可能还要进行相关图像处理。因此编写一个功能强大的打印程序,必须熟练
  掌握打印相关的控制技术。
2。1 控制打印机
 2。1。1选择当前打印机
  一个系统可以连接多个打印机,甚至可以有其他程序(传真软件)将自已伪装成打印机.不论连接的打印机有多少,
  始终有一个"当前打印机"或者"默认打印机".


  获取默认打印机设备环境的标准方法有:EnumPrinters()函数.该函数填充一个包含每个所连接打印机信息的数组
  结构.根据需要,还可以选择几种结构作为该函数的参数. 如结构PRINTER_INFO_x,x是一个数字,在Windows95,98上
  函数使用PRINTER_INFO_5结构,在Windows2000/xp上,函数使用PRINTER_INFO_4结构.


  获取当前打印机的另一种方法是使用打印对话框CPrintDialog.该类的GetDeviceName()函数用以获得当前选择的打印
  机的名称,GetDriverName()函数用以获得当前选择的打印机驱动程序.


  /*
  EnumPrinters
  Declare function EnumPrinters lib (ByVal flags As long,ByVar name As String,
  Byval Level As long,pPrinterEnum As Byte,ByVal cdBuf As long,pcbNeeded As Long,pcReturned As long ) As Long


  说明:枚举系统中安装的打印机.


  返回值:
  long,非零表示成功,零表示失败.可以通过GetLastError获取错误值.


  参数:
  flags: long,一个或多个下述标志.
   PRINTER_ENUM_LOCAL:检举本地打印机(包括Window95中的网络打印机)
   PRINTER_ENUM_NAME:枚举由name参数指定的打印机.如果name为NULL,则枚举出可用的打印机.
   PRINTER_ENUM_SHARE:枚举出共享打印机(必须同其他常数组合使用)
   PRINTER_ENUM_CONNECTIONS:枚举网络列表中的打印机.(仅适用于NT)
   PRINTER_ENUM_NETWORK:枚举通过网络连接的打印机.级别(level)必须为1,仅适用于NT
  name:String,vbNullString表示枚举同本机连接的打印机.否则由标志和级别决定.
  Level:Long,1,2,4或5(4仅适用于NT,5仅适用于Win95和NT4.0)指定欲枚举的结构的类型.
  如果是1,则name参数由标志设置决定.如果是2或5,那么name就代表要枚举的打印服务器的名字.
  或者为vcbNullString.如果是4,那么只有PRINTER_ENUM_LOCAL和PRINTER_ENUM_CONNECTIONS才有效.名字必须是vbNullString.


  pPrinterEnum:Byte,包含PRINTER_ENUM_x结构的缓冲区,其中x代表级别.
  cbBuf:Long,pPrinterEnum缓冲区中的字符数量.
  pcbNeeded:Long,指向一个Long型变量的指针,该变量用于保存请求的缓冲区长度.或者实际读入的字节数量.
  pcReturned:Long,载入缓冲区的结构数量(用于那些能返回多个结构的函数).


  说明:
  第4级和第5级将它们的结构建立在系统注册表的基础上.而且要比第2级快得多.


  使用EnumPrinter时,要包含以下头文件:#include <winspool.h>
  */
  注意:使用Printing and Print Spooler 函数必须包含"winspool.h"头文件。
  注意:使用Windows NT/2000/xp的读者使用EnumPrinters()函数时请使用PRINTER_INFO_4结构。


  void CPrintProj::OnEnumPrinters()
  {
   DWORD dwSize,dwPtiner;
   ::EnumPrinters(PRINTER_ENUM_LOCAL,NULL,5,NULL,0,&dwSize,&dwPrinter);
   BYTE *pBuffer = new BYTE[dwSize];
   ::EnumPrinters(PRINTER_ENUM_LOCAL,NULL,5,pBuffer,dwSize,&dwSize,&dwPrinter);


   if(dwPrinter != 0)
   {
    PRINTER_INFO_5 *pPrnInfo = (PRINTER_INFO_5*)pBuffer;
    for(UINT i = 0; i < dwPrinter; i++)
    {
     CString strprnInfo = pPrnInfo->pPrinterName;
     AfxMessageBox(strprnInfo);
     pPrnInfo++;
    }
   }
   delete[] pBuffer;
  }




2。1。2监测当前打印机状态
  Windows标准的打印机监测程序。通过该程序,我们可以了解当前打印机的状态,包括打印机任务队列,
  各项任务状态、所有者、进度和开始时间,并且可以及时暂停、清除打印任务。


  监控打印机就有必要对Windows后台打印机制有所了解。后台程序可以减轻应用程序的打印负担。Windows在启动时就加载后台
  打印程序。因此,当应用程序开始打印时,它已经是活动的了。当程序打印一个文件时,GDI模块创建打印的数据文件。后台
  打印程序的任务是将这些文件发往打印机。GDI模块发出一个消息来通知它开始一个新的打印作业。然后打印机开始读文件,
  并将文件传送到打印机。为了传送打印文件,后台程序为打印机所连接的并口和串口提供各种通信函数。在后台程序向打
  印机发送文件操作结束的命令后,它就删除包含输出数据的临时文件。


               后台打印程序的组合。
  ----------------------------------------
  打印请求后台程序     | 将数据流传递给打印机
  本地打印提供者       | 为本地打印机创建后台文件
  网络打印提供者       | 为网络打印机创建后台文件。
  打印处理程序         | 将后台的设备无关数据转换为特定打印机的格式
  端口监视程序         | 控制连接打印机的端口
  语言监视程序         | 控制双向通信的打印机,配置并检测打印机的状态


  使用后台打印程序,真正的文件打印操作是后台打印程序的任务,而不是应用程序的任务。
  我们可以暂停打印作业、改变作业的优先级或者取消打印作业。这种管理方式使得应用程序
  可能比下面的这种情况“打印”得更快。即作业以实时方式打印,且必须等到打印完一页后
  才能处理下一页。


  但是如果我们拥有更好的打印机软硬件或者在网络打印机等某些特殊的情况下,可以去掉Windows后台打印程序。
  去掉Windows后以中打印程序可以加快打印速度。因为打印输出不必保存在硬盘上,而可以直接输出到打印机,并被
  外部硬件或软件后台程序所接受。


  实现类似Windows打印监测试程序的功能,需要调用Win32假脱机(SPOOL)枚举API函数。"[使用Win32假脱机枚举函数需要调用
  两次所需的函数。这些API函数通常要填充一组结构。但是,这些结构通常包含指向字符串和其他类型数据的指针。
  这些外来的数据必须存储在返回的内存中,使得字符串和其他数据存储在结构中。所以简单的在堆栈中声明一组结构变量
  不足以为API函数返回的信息设置足够的内存。]"


  因此,正确的函数调用是:首先调用API函数确定需要的内存空间,在随后的调用中传入一个指针,该指针指向了一块动态
  分配的大小合适内存空间。需要进行该类处理的枚举函数包括:
  EnumForms(),EnumJobs(),EnumMonitors(),EnumPorts(),EnumPrinterDrivers(),EnumPrinters()和EnumPrinterProcessors()


  下面这段程序,使用EnumJobs()API函数,枚举出所选打印机当前的打印任务。关于其他打印监控函数的使用大家可以参考
  微软平台SDK中关于打印函数和打印假脱机枚举函数的文档。


  注意:独占设备是指在一个程序(作业、用户)的整个运行其间独占的设备,直到该程序(作业、用户)完成。系统的独占设备是
  有限的(譬如一台计算机只能连接一台打印机),往往不能满足多进程的要求,会引起大量进程由于等待某些独占设备而阻塞,
  成为系统的“瓶颈”。另一方面,申请到独占设备的进程在其整个运行期间虽然占有设备,利用率却常常很低,设备还是经常
  处于空闲状态。为了解决这种矛盾,最常用的方法就是用共享设备来模拟独占设备,从而提高系统地效率和设备利用率.这种
  技术称为虚拟设备技术.实现这一技术的软、硬件系统被称为假脱机(Simultaneous Peripaheral Operation On Line SPOOL)
  系统。打印机是典型的独占设备。引入SPOOL技术后,用户的打印请求传递给SPOOL系统,而不是真正的把打印机分配给用户。
  SPOOL系统的输出进程是先磁盘上申请一个空闲区域,把需要打印的数据传输到里面,再把用户的打印请求挂到打印机队列上。
  如果打印机空闲,就会从打印机队列中取出一个打印请求,再从磁盘上的指定区域取出数据,执行打印操作。由于磁盘是共享
  的,SPOOL系统可以随时响应打印请求并把数据缓存起来,这样独占设备改造成了共享设备,从而提高了设备的利用率和系统
  利用率。


   /*
   OpenPrinter
   Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA"(ByVal pPrinterName As String,phPrinter As Long,
   pDefault As PRINTER_DEFAULTS)As Long


   说明:
   打开指定的打印机,并获取打印机的句柄。
   返回值:
   Long,非零表示成功,零表示失败。会设置GetLastError
   参数表:
   pPrinterName  String,要打开的打印机的名字
   phPrinter     Long,用于装载打印机的句柄。
   pDefault      PRINTER_DEFAULT,这个结构保存要载入的打印机信息。
   */
   /*
   Declare Function EnumJobs Lib "winspool.drv"Alias "EnumJobsA"(ByVal hPrinter As Long,
   ByVal First Job As Long,ByVal NoJobs As Long,ByVal Level As Long,pJob As Byte,ByVal cdBuf As Long
   ,pcbNeeded As Long,pcReturned As Long)As Long


   说明:
   枚举打印队列中的作业
   返回值:
   Long,非零表示成功,零表示失败。 可以通过GetLastError获取错误信息。
   hPrinter:  Long,一个已打开的打印机对象的句柄(用OpenPrinter获得)
   FirstJob:  Long,作业列表中要枚举的第一个作业的索引(注意编号从0开始)
   NoJobs     Long,要枚举的作业数量。
   Level      Long,1或2
   pJob       Byte,包含JOB_INFO_1或JOB_INFO_2结构的缓冲区
   cbBuf      Long,pJob缓冲区中的字符数量。
   pcbNeeded  Long,指向一个LONG型变量的指针,该变量用于保存请求的缓冲区长度
              或者实际读入的字节数量。
   pcReturned Long,载入缓冲区的结构数量(用于那些能返回多个结构的函数)。
   */
   /*
   GetLastError
   Declare Function GetLastError lib "kernel32"Alias "GetLastError"As Long
   说明:
   针对之前调用的api函数,用这个函数取得扩展错误信息
   返回值:Long,由api函数决定.请参考api32.txt文件,其中列出了一系列错误常数;都以ERROR_前
   缀起头.常用的错误代码见下表:
   ERROR_INVALID_HANDLE:无效的句柄作为一个参数传递。
   ERROR_CALL_NOT_IMPLEMENTED  在win95下调用专为win nt设计的win32 api函数
   ERROR_INVALID_PARAMETER   函数中有个参数不正确。
   */
   /*
   EnumJobs
   Declare Function EnumJobs Lib "winspool.drv" alias "EnumJobsA"(ByVal hPrinter As Long,ByVal FirstJob As Long,ByVal NoJobs As Long,By Level As Long
   pJob As Byte,ByVal cdBuf As Long,pcbNeeded As Long,pcReturned As Long) As Long


   说明:
   枚举打印队列中的作业
   返回值:
   Long,非零表示成功,零表示失败。可以通过GetLastError获取错误信息
   参数表:
   hPrinter         Long,一个已打开的打印机对象的句柄(用OpenPrinter获得)
   FirstJob         Long,作业列表中要枚举的第一个作业的索引(注意编号从0开始)
   NoJobs           Long,要枚举的作业数量。
   Level            Long,1或2
   pJob             Byte,包含JOB_INFO_1或JOB_INFO_2结构的缓冲区。
   cbBuf            Long,pJob缓冲区中的字符数量。
   pcbNeeded        Long,指向一个Long型变量的指针,该变量用于保存请求的缓冲区长度,或者实际读入的字节数。
   pcbReturned      Long,载入缓冲区的结构数量。
   */


   BOOL CPrintListDlg::PrintJobList(LPCTSTR szPrintName)
   {
    HANDLE   hPrinter;
    DWORD    dwNeeded,dwReturned,i;
    JOB_INFO_1  *pJobInfo;


    if(!OpenPrinter(szPrinterName,&hPrinter,NULL))
     return FALSE;
    if(EnumJobs(hPrinter,0,0xFFFFFFFF,NULL,1,NULL,0,&dwNeeded,&dwReturned))
    {
     if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
     {
      ClosePrinter(hPrinter);
      return FALSE;
     }
    }
    if((pJobInfo = (JOB_INFO_1*)malloc(dwNeeded)) == NULL)
    {
     ClosePrinter(hPrinter);
     return FALSE;
    }
    if(!EnumJobs(hPrinter,0,0xFFFFFFFF,1,(LPBYTE)pJobInfo,dwNeeded,&dwNeeded,&dwReturned))
    {
     ClosePrinter(hPrinter);
     free(pJobInfo);
     return FALSE;
    }
    ClosePrinter(hPrinter);
    
    for(UINT i = 0; i < dwReturned; i++)
    {
     m_listBox2.AddString(pJobInfo[i].pDocument);
    }
    free(pJobInfo);
    return TRUE;
   }
   void CPrintListDlg::OnSelchangePrinters()
   {
    int nIndex = m_listBox.GetCurSel();
    CString strPrinterName;
    if(nIndex != CB_ERR)
    {
     m_listBox.GetText(nIndex,strPrinterName);
     if(strPrinterName.IsEmpty())
     {
      PrintJobList((LPCTSTRstrPrinterName));
     }
    }
   }
   /*
   这个例子启发我们,应用打印枚举API函数可以对打印机进行有效的监控。
   */

条码打印机编程             openport("TSC TTP-245");//Call openport(“TSC CLEVER TTP-243”)  TSC TTP/TDP-243(E),            //openport(“TSC CLEVER TTP-243”)      setup(this.textBox3.Text, this.textBox4.Text, "2", "10 阅读详情

相关推荐

面向接口编程经典案例之打印机

开发打印机 墨盒:彩色、黑白。纸张类型:A4、B5 墨盒和l纸张都不是打印机厂商提供的。打印机厂商要兼容市场上的墨盒、纸张 用向接口编扁程的方式开发 制定墨盒、纸张的约定或标 打印机厂商使用墨盒、纸张的标住开发打印机。其他厂商按照墨盒、纸张的标准生产墨盒、纸张 接口1: public interface InkBox { //墨盒接口 public String color(); } 实现类: public class BlackBox im.

hxb1111的博客 993

第十三章 使用打印机

限用在打印机上的函数(StartDoc、EndDoc、StartPage和EndPage)负责将打印机的输出组织打印到纸页上。而一个程序呼叫普通的GDI函数在一张纸上显示文字和图形和在屏幕上显示的方式一样。打印入门在Windows下使用打印机时,实际上启动了一个包含GDI32动态链接库模块、打印驱动程序动态连结模块(带.DRV扩展名) 、Windows后台打印程序,以及有用到的其它相关模块

千月星跡 2518

常见的打印机类型及其编程实现

通过相应的编程接口和指令,我们可以实现对这些打印机的控制和操作。在实际开发中,可以根据具体需求选择适合的编程语言和相关库或框架,以实现与打印机的交互和打印功能。这里提到的打印机类型只是其中的几种常见类型,市场上还有其他类型的打印机,如热敏打印机、热转印打印机等。根据不同类型的打印机,编程接口和指令会有所不同,需要根据具体的打印机型号和文档进行开发和调试。需要注意的是,在实际编程中,通常会使用打印机的驱动程序或者通过操作系统提供的打印接口进行打印操作。以下将介绍几种常见的打印机类型,并提供相应的编程示例。

PixelLoom的博客 528

windows获取系统DPI

dc.GetDeviceCaps(LOGPIXELSX); //每英寸水平逻辑像素数 dc.GetDeviceCaps(LOGPIXELSY); //每英寸垂直逻辑像素数 dc.GetDeviceCaps(HORZRES); //水平像素总数 dc.GetDeviceCaps(VERTRES); //垂直像素总数 dc.GetDeviceCaps(DESKTOPHORZRES); //可视桌面的水平像素总数 dc.GetDeviceCaps(DESKTOPVERTRES); //可视桌面的水平像素总数 dc

就是那个党伟 4017

Konica Minolta bizhub 打印机的编程指南

通过这些编程接口和功能,开发人员可以根据自己的需求定制和优化打印机的行为,实现更加灵活和高效的打印操作。作为一种广泛使用的打印设备,Konica Minolta bizhub 打印机提供了丰富的编程接口和功能,使开发人员能够通过编程来控制和自定义打印机的行为。通常情况下,可以使用网络连接通过基于网络的协议与打印机进行通信,例如基于HTTP的打印机控制协议(PAP)或基于网络的打印机控制语言(PCL)。请注意,上述示例代码中的 IP 地址和端口需要替换为实际 bizhub 打印机的 IP 地址和端口。

YabClass的博客 642

HP1007打印机的选择和编程

总结起来,对于HP1007打印机的硒鼓选择,建议选择与之兼容的认证硒鼓,以确保打印机的正常工作和打印质量。在编程方面,您可以使用适合的编程语言和相应的打印机模块与HP1007进行通信,并实现打印任务。以上是使用Python编程的示例代码,您可以根据自己的需求和喜好选择合适的编程语言和相应的打印机模块进行开发。对于HP1007打印机的硒鼓选择和编程,我们将为您提供详细的解答和相应的源代码。对于HP1007打印机而言,我们需要选择与之兼容的硒鼓,以确保打印机正常工作并获得最佳打印效果。方法断开与打印机的连接。

CyberLynxX的博客 359

13.1 打印基础

摘录于《Windows程序(第5版,珍藏版).CHarles.Petzold 著》P471         在 Windows 中使用打印机时,你实际上启动了一系列模块之间复杂的交互过程,包括 GDI32 库模块、打印机设备驱动程序库模块(带 .DRV 后缀的文件)、Windows 后台打印机处理程序(print spooler)和其他有关模块。在开始为打印机编程之前,让我们先来看一下这

wilim 1303

如何在PIXMA打印机中添加墨水并进行编程

本文将介绍如何在PIXMA打印机上添加墨水,并提供一些与打印机编程相关的示例代码。请确保使用正确类型的墨水,并按照说明书中的指示操作。通过编程,您可以进一步控制和自定义PIXMA打印机的功能,以满足特定的需求。首先,我们需要确认所使用的PIXMA打印机所需的墨水类型。将墨水瓶插入墨水槽,并轻轻按下墨水瓶,使墨水流入槽中。然后,找到打印机上的墨水盖。这只是一个简单的示例,您可以根据自己的需求进行更多的编程操作,例如设置打印机的打印模式、打印多个文件等。当墨水槽已经装满墨水时,小心地关闭墨水盖。

LogicGuruX的博客 1093

VFP下打印机的设置编程

VFP下打印机的设置编程2008-09-29 13:03VFP本身提供了部分相关打印机的数据返回函数以及部分设置项,但在打印机的直接控制方面没有提供相应的策略,这里从分析打印机的Devmode和PRINTER_INFO_2的结构来详细说明一下VFP打印机的相关操作编程。首先看下打印机的基本数据结构Devmode:Private Type DEVMODE    dmDevic

tianxia_xiangyu的专栏 6686

如何在编程中查看打印机型号

在编程中,有时候需要获取连接到计算机的打印机的型号信息。通过使用适当的编程语言和操作系统相关的API,我们可以轻松地实现这一目标。无论你选择使用哪种编程语言,通过上述示例代码,你都可以轻松地获取连接到计算机的打印机的型号信息。根据你的需求,你可以进一步扩展代码,以获取更多关于打印机的详细信息。如果你喜欢使用Java编程语言,同样可以通过使用相关的API获取打印机型号。在Windows操作系统中,我们可以使用Python编程语言来获取打印机的型号信息。类来获取默认打印机的名称,从而获取打印机的型号信息。

CyberFlare的博客 214

多种编程语言下POS58打印机编程指南

本文还有配套的精品资源,点击获取 简介:POS58打印机广泛用于零售、餐饮行业,用于打印收据和小票。本编程资源提供了VB、PB、VFP和C语言下的打印例程和文档,帮助开发者在这些语言环境中实现POS58的功能。介绍了使用Windows API、.NET类、VFP命令和C语言系统调用来实现打印,并深入讲解了ESC/POS指令集的使用,以及打印机初始化、错误处理、纸张检测和打印...

weixin_42527665的博客 1338

斑马打印机ZPL语言编程实战

ZPL是斑马条码打印机工业型号用的编程语言。利用这些编程语言,编辑好一个打印的指令集,发送给条码打印机,条码打印机就会把ZPL所绘制的标签打印出来。

btmood的博客 2万+

Zebra打印机ZPL编程及中文应用手册

ZPL(Zebra Programming Language)是一种专门为Zebra打印机设计的编程语言,用于控制打印机的打印任务。这种语言广泛应用于工业打印领域,如物流、医疗、零售等行业,用于打印标签、条形码、二维码和图形等。学习ZPL指令可以帮助开发者在这些行业中实现定制化的打印解决方案。

weixin_32661831的博客 4777

VC打印机编程之两篇有用的文章获取打印机与打印作业的状态和设置打印机模式并预览打印

VC打印机编程之两篇有用的文章

thanklife的专栏 1万+

C#打印机编程实战:源代码解析与应用

C#作为一种现代编程语言,提供了强大的打印功能,它通过灵活的API支持各种打印任务,使得开发者能够轻松实现从基本的文本输出到复杂的图形打印。本章将对C#打印功能进行概述,为读者展示如何在应用程序中实现打印输出。System.Drawing.Printing命名空间是.NET Framework中用于处理打印任务的一套类库。它为开发者提供了丰富的API来管理打印任务和控制打印过程。通过这个命名空间,我们可以在应用程序中实现复杂的打印逻辑,包括但不限于页面布局、打印预览、打印任务的启动和取消等。

weixin_33298352的博客 842

AD4030-24BBCZ详细资料 Analog Devices 模数转换器 - ADC 24-Bit, 2 MSPS, SAR ADC

AD4030-24BBCZ详细资料  Analog Devices 模数转换器 - ADC 24-Bit, 2 MSPS, SAR ADC

Chen_YYan的博客 794

面向接口编程:打印机

实现打印机功能

Stardust_fantasy的博客 686

智能音箱麦克风阵列实战:Python实现宽带GSC波束形成(附完整代码)

本文从工程实战角度,详细介绍了如何在智能音箱中利用Python实现宽带GSC波束形成算法。文章深入解析了广义旁瓣消除器(GSC)的核心架构,包括固定波束形成、阻塞矩阵与自适应滤波路径,并提供了完整的仿真代码、关键参数(如LMS步长)调优方法,以及面向嵌入式部署的计算优化与移植考量,旨在帮助开发者构建在真实噪声环境下高效工作的语音增强系统。

opencv7vision的博客 342
上一篇: 打印
下一篇: Windows窗口
htt9931
博客等级 码龄24年 43粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值