重庆分公司,新征程启航

为企业提供网站建设、域名注册、服务器等服务

vb.net打印机状态 c#获取打印机状态

VB 返回打印机状态

VB 通过MSComm控件取得打印机的状态:正常、缺纸、卡纸等:

创新新互联,凭借10余年的成都网站建设、成都网站制作经验,本着真心·诚心服务的企业理念服务于成都中小企业设计网站有上千案例。做网站建设,选成都创新互联公司

此方法使用VB中的串口通信控件MSComm给打印机发送指令,然后打印机自动返回其状态值,根据不同的返回值就可以判断打印机是正常、缺纸、卡纸等状态。其中的指令适用于Star SP500系列。注意在使用此方法时不要安装打印机的驱动,或者在驱动中设置的串口端口与此程序中的要不能相同,否则程序会提示参数设置错误,其实就是端口已经被占用的原因。以下是程序代码:

Option Explicit

Dim Status As String

Dim StatusString As String

Dim TimeUp As Boolean

Private Sub Command1_Click()Sub Command1_Click()Sub Command1_Click()Sub Command1_Click()

On Error Resume Next

Dim i As Long

Status = "" '状态返回值

StatusString = ""

MSComm1.CommPort = 1 'COM端口号:如果是COM1则为1,以此类推;

MSComm1.Settings = "38400,N,8,1" '参数设置:波特率,奇偶校验,数据位,停止位;

MSComm1.InputLen = 0

MSComm1.PortOpen = True '打开端口

'给Star打印机发送“ENQ”指令或“ESC ACK SOH”指令,打印机自动返回状态值

MSComm1.Output = Chr$(5) + Chr$(HA) + Chr$(0)

'MSComm1.Output = Chr$(H1B) + Chr$(H6) + Chr$(H1)

' Poll for 8 byte status

Do While Len(Status) 8

DoEvents

Status = MSComm1.Input

Loop

For i = 1 To 9

StatusString = StatusString Right("00" " " Hex(Asc(Mid$(Status, i, 1))), 2)

'StatusString = StatusString Hex(Asc(Mid$(Status, i, 1))) " "

Next i

Text1.Text = StatusString

MSComm1.PortOpen = False

End Sub

Private Sub Form_Unload()Sub Form_Unload()Sub Form_Unload()Sub Form_Unload(Cancel As Integer)

Close

End Sub

Private Sub Wait()Sub Wait()Sub Wait()Sub Wait(Interval As Long)

Timer1.Interval = Interval

Timer1.Enabled = True

TimeUp = False

Do

DoEvents

Loop While Not TimeUp

End Sub

Private Sub Timer1_Timer()Sub Timer1_Timer()Sub Timer1_Timer()Sub Timer1_Timer()

Timer1.Interval = 0

Timer1.Enabled = False

TimeUp = True

End Sub

----------------------------------------------------------------------

2号代码:

Option Explicit

Declare Function MapPhysToLin Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysSize As Long, ByRef PhysMemHandle) As Long

Declare Function UnmapPhysicalMemory Lib "WinIo.dll" (ByVal PhysMemHandle, ByVal LinAddr) As Boolean

Declare Function GetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByRef PhysVal As Long) As Boolean

Declare Function SetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysVal As Long) As Boolean

Declare Function GetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByRef PortVal As Long, ByVal bSize As Byte) As Boolean

Declare Function SetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByVal PortVal As Long, ByVal bSize As Byte) As Boolean

Declare Function InitializeWinIo Lib "WinIo.dll" () As Boolean

Declare Function ShutdownWinIo Lib "WinIo.dll" () As Boolean

Declare Function InstallWinIoDriver Lib "WinIo.dll" (ByVal DriverPath As String, ByVal Mode As Integer) As Boolean

Declare Function RemoveWinIoDriver Lib "WinIo.dll" () As Boolean

Public IOStat As Boolean

'************************************************************

'* 函数名称:GetPrnStat *

'* 功能:根据打印机的内存地址,检测打印机的目前工作状态 *

'* 参数:lptport: 要检测的打印机的端口号,如LPT1: *

'* 返回值:打印机的工作状态值。 *

'* 0:正常 1:缺纸 2:无联系 3:异常(其他错误) *

'* 调用:本模块中的API函数InitializeWinIo和GetPortVal *

'* 备注:检测的内存地址,是在打印端口所在的基地址上加1; *

'* 作者:谷霖 *

'* LPT1口的基地址为H378;LPT2口的基地址为H278 *

'************************************************************

Public Function GetPrnStat(ByVal LptPort As String) As Long

Dim PrnAddr As Long

On Error Resume Next

If IOStat = False Then IOStat = InitializeWinIo()

If IOStat Then

If UCase(LptPort) = "LPT1:" Then

PrnAddr = H379

ElseIf UCase(LptPort) = "LPT2:" Then

PrnAddr = H279

End If

GetPortVal PrnAddr, GetPrnStat, 1

Else

GetPrnStat = HFF

End If

GetPrnStat = GetPrnStat And HF8

Select Case GetPrnStat

Case H68, H58, H70

GetPrnStat = 1 '缺纸

Case H78

GetPrnStat = 2 '无联系

Case HD8

GetPrnStat = 0 '正常

Case Else

GetPrnStat = 3 '异常

End Select

End Function

'*************************************************************************

'* 函数功能:检查打印机的状态主函数 *

'* 输入参数:PrintName 要检测的打印机名称 *

'* 输出参数:checkprinterr *

'* 检查结果(0:正常 1:打印机缺纸 2:打印机无联系 3:打印机异常 *

'* 4:没有安装打印机 5:打印机名称错误) *

'*************************************************************************

Public Function CheckPrintErr(ByVal PrintName As String) As Long

'CheckPrintErr参数说明

'0:没有错误

'1:打印机无联系

'2:打印机缺纸

'3:没有安装打印机

Dim printjieguo As Long

Dim i As Long, k As Long

On Error GoTo ErrCheckPrint

If Printers.Count = 0 Then

CheckPrintErr = 4 '没有安装打印机

Exit Function

End If

'检测发票打印机是否可以联系

For i = 0 To Printers.Count - 1

If (Printers(i).DeviceName = PrintName) Then

k = k + 1

Exit For

End If

Next

If k = 0 Then '打印机名称错误

CheckPrintErr = 5

Exit Function

End If

Set Printer = Printers(i)

CheckPrintErr = GetPrnStat(Printer.Port)

Exit Function

ErrCheckPrint:

CheckPrintErr = 3

Exit Function

End Function

----------------------------------------------------------------------

3号答案:

编写VB打印控制程序的几点心得

Visual Basic(VB)给用户提供了可视化编程环境,因其简单易学、功能强大而得到了广泛的应用。VB提供了两种实现打印的方法。一般在对打印质量要求不高的场合,或者是编程项目的早期开发过程中,可以直接使用VB窗体的Printform方法实现打印。用这种方法实现打印具有编程简单、易用并且功能强大的优点,它只需要通过一行代码,几乎能打印所有内容。实现的方法就是:首先将要打印的内容在屏幕上显示出来,然后开发人员只要为窗体对象激活 PrintForm ,窗体则自动将要打印的内容发送到Printer对象上,其语法格式如下:[窗体.]PrintForm 。如果窗体中包括图形,那么打印前应先置窗体的AutoRedraw属性为真。这种方法虽然简单,但是它却存在着内存消耗大、打印粗糙、速度慢等缺陷,尤其对于带有滚动条的图像,这种方法只能打印当前可视的区域 。在实际应用中经常会遇到对打印质量要求很高的场合,例如打印音乐五线谱,对打印的美观、清晰度以及音符符头的位置都有很严格的要求,这种应用场合若采用VB提供的另一种基于Printer对象的打印方法则可以获得高分辨率的打印,得到很高的打印质量。在实际应用中,也可以根据实际应用情况将上述两种方法结合起来使用,即:前期工作使用PrintForm 简单的打印方法将窗体的布局定下来,后期再使用基于Printer对象的打印方法实现最终的打印工作。

2.高分辨率打印程序开发心得

⑴ Printer对象

VB的打印可以使用Printer对象。Printer对象是一个独立于打印机设备的封装,它可以代表不同的打印机,初始时,Printer对象为系统缺省的打印机,也可以使用下列语句:Set Printer=Printers(2) (其中2代表Printers集中的第二个打印机)对打印机进行指定。

Printer对象具备例如:ColorMode、Copies、Duplex、Printquality等控制打印机特征的属性, 提供了Newpage、EndDoc、KillDoc等控制打印过程的方法,以及大多数由窗体和图片框控件提供的图形属性和方法如:Currentx、Currenty、Textwidth、Textheight、Print、Pset、Line、PaintPicture和Circle等方法,它还拥有Font的所有属性。实现高分辨率的打印就是通过控制Printer对象的上述属性和方法完成的。

⑵ 直接利用Windows公用标准对话框CommonDialog控件【打印】VB为用户提供了Windows公用标准对话框CommonDialog控件:【打开】、【文件另存为】、【颜色】、【字体】、【打印】。CommonDialog控件在Visual Basic 和Microsoft Windows动态连接库Commdlg.dll例程之间提供了接口。利用公用标准对话框【打印】开发VB的打印程序,将大大缩短程序的开发周期。应用程序中要使用公用对话框,必须首先在工具箱中添加公用对话框控件。该动作通过激活【部件】对话框,选中Microsoft Common Dialog Control6.0, 单击【确定】即可。然后再将公用控件添加到窗体上并设置相应属性,该控件具有的属性有Color、Font、Print、Help等。

VB提供mnuFilePrint_Click()过程供用户添加开发的打印程序代码。

⑶ Printer对象控制打印的基本过程

利用Printer对象开发的打印程序主要靠其提供的——NewPage (打印新的一页,CurrentX、CurrentY置为新页的左上角,可完成多页功能。)、EndDoc (将打印任务加入打印机队列)、KillDoc (取消打印任务)控制打印过程的。一般情况下,打印程序完成多页打印时会多次执行NewPage,结束时执行一次EndDoc将打印任务加入打印机队列。如果你在NewPage后,立即使用EndDoc,VB则不会打印额外的空白页。如果希望显示空白页,则可在新的一页上只使用Printer.Print “ “打印空字符即可。

为了通过Printer对象实现文本和图形的打印,获得最好的打印质量,还需要对VB控制打印机的多种属性有更深入的理解,例如打印机的坐标体系向屏幕坐标体系的转换、打印机字体尺寸的确定等。下面给出了打印程序的主框架:

Private Sub mnuFilePrint_Click()

On Error Resume Next

If ActiveForm Is Nothing Then Exit Sub

With dlgCommonDialog ‘打印机公用对话框

.DialogTitle = "打印"

.CancelError = True

.Flags = 1

Printer.FontSize = dlgCommonDialog.FontSize

‘将打印机公用对话框设置的字体大小传递给打印机

.ShowPrinter ‘ 在屏幕上显示【打印】公用对话框

If Err MSComDlg.cdlCancel Then

Printer.FontTransparent = False ‘初始化打印的字体为不透明

SetPrinterScale Myform ‘匹配打印机的缩放属性与窗体的属性

PrintAnywhere Printer ‘可放置用户编写的打印对象参数化例程

‘实现字符和图形的显示

Printer.NewPage ‘打印机坐标初始化

PrintAnywhere Printer ‘打印另一页的内容

Printer.NewPage ‘打印机坐标初始化

Printer.EndDoc ‘将该任务加入打印机任务队列

‘ 不打印空白页

Printer.KillDoc ‘取消当前的打印任务

End If

End With

End Sub

⑷ 参数化绘图程序

用VB开发应用程序时,如果使用参数化绘图例程进行屏幕显示程序的开发,则在开发打印程序时,就不需再另行开发代码,从而避免了大量的重复劳动,有效地缩短了程序的开发周期。参数化绘图例程就是:在开发例程时,为每一个例行程序提供一个OBJECT类型的参数,调用程序通过向例程的OBJECT类型参数分别传递窗体、Printer对象,就可分别完成屏幕显示与打印机输出。 见如下示例:

Sub PrintAnywhere(Dest As Object)

Dest.Print “HELLO!”

Dest Is Printer Then

Printer.EndDoc

End If

End Sub

要完成屏幕上的输出,调用 PrintAnywhere Myform 即可,而调用 PrintAnywhere Printer则完成在打印机上输出。

⑸ 属性匹配与窗体缩放

因为控制打印机实际绘图区域大小的属性Height和Width,由目前正在使用的纸张决定,而且可打印的区域与纸张边缘有一定距离。因而为了获得正确的打印输出结果,不能简单地将Printer对象直接传递给绘图例行程序,还必须要解决打印机的缩放属性与显示窗体属性相匹配的问题。即:保证使窗体中的打印内容以正确的大小显示,并居于可打印区域的中间。实际上实现的是打印机的坐标体系向屏幕坐标体系的转换。具体过程是:使用打印机的ScaleX和ScaleY方法,获取以twip为单位的打印机尺寸,再利用窗体的ScaleX和ScaleY方法将这些尺寸转换为窗体中的坐标系统,从而实现以窗体的坐标系统提供打印机可打印区域大小的目的。然后,用这些尺寸作为打印机中新的ScaleWidth和ScaleHeight,即可实现属性匹配。

但是,我们在打印时,经常会遇到这样的场合——在不改变窗体形状的情况下,需要扩大或缩小窗体的大小。要完成这样的工作,不仅需要完成属性匹配,还要确定对象被缩放的系数。程序如下:

Private Sub SetPrinterScale(obj As Object)

Dim pwid As Single, phgt As Single, xmid As Single, ymid As Single

Dim owid As Single, ohgt As Single

owid = obj.ScaleX(obj.ScaleWidth, obj.ScaleMode, vbTwips)

ohgt = obj.ScaleY(obj.ScaleHeight, obj.ScaleMode, vbTwips)

‘获取窗体以Twips表示的尺寸

pwid = Printer.ScaleX(Printer.ScaleWidth, Printer.ScaleMode, vbTwips)

phgt = Printer.ScaleY(Printer.ScaleHeight, Printer.ScaleMode, vbTwips)

‘获取打印机以Twips表示的尺寸

If (ohgt / owid phgt / pwid) Then

s = phgt / ohgt

Else

s = pwid / owid

End If ‘计算缩放因子

pwid = obj.ScaleX(pwid, vbTwips, obj.ScaleMode) / s

phgt = obj.ScaleY(phgt, vbTwips, obj.ScaleMode) / s

‘将打印机的尺寸转换成obj的坐标系统 / 缩放因子

x_mid = obj.ScaleLeft + obj.ScaleWidth / 2

y_mid = obj.ScaleTop + obj.ScaleHeight / 2‘设置打印区域的中心点坐标

Printer.Scale (x_mid - pwid / 2, y_mid - phgt / 2)-(x_mid + pwid / 2, y_mid + phgt / 2)

‘ 设置打印机中新的ScaleWidth和ScaleHeight

End Sub

⑹ 坐标定位

窗体、图片框控件以及Printer对象提供的TextWidth和 TextHeight方法在文本定位的应用方面很有用。TextWidth、 TextHeight分别以对象当前的刻度单位返回字符串的宽度和高度。但是必须注意很多字体中其字符宽度并不全部相同,所以不能简单地将单个字符的宽度乘以字符数来获得字符串的宽度。对那些没有TextWidth和TextHeight的控件可通过设置父窗体的Font属性,使其与该控件的属性相匹配,再利用父窗体的TextWidth和TextHeight获得它的字符串的宽度和高度。

但是,我们在完成屏幕显示程序调试后,在进行打印输出时却出现了屏幕显示与打印结果的不一致性的现象,表现在所打印的字体之间坐标关系与屏幕显示不一样,例如:屏幕显示上的两个字符不重叠,而打印出的字符却出现相互重叠的现象。经调试发现,问题出现在字体尺寸的确定上。 程序中,屏幕上显示的字符坐标是通过对象的TextWidth和TextHeight方法计算得来的,它直接受到字体尺寸大小的影响。VB向用户提供的字体是在用户需要的打印机点的范围内,如果你需要的字体大小为73点, 则打印出的实际字体大小为72.75。然而窗体、图片框控件的Fontsize只能是整数,例如它不能将字体的大小定为72.75,实际上这就造成了屏幕上显示字体与实际打印字体大小之间产生了误差。 我们采用如下方法来解决该问题,就是在计算字体大小时,根据计算出来的字体尺寸,确定它存在的范围,然后再将它定位到VB提供的几种固定大小的字体上,而不是随意指定。当然,也可以有其它的解决办法。例如:字体大小选取偶数等。 由于篇幅所限,这里不再作介绍。

VB.NET或C#如何调用某个打印机(例如"Microsoft XPS Document Writer")的“打印首选项”?

实现打印功能的核心是PrintDocument类这个类属于System.Drawing.Printing名字空间这个类封装了当前的打印设置页面设置以及所

有的与打印有关的事件和方法

这个类包括以下几个属性 事件 和方法

1、PrinterSettings 属性

存放打印机的设置信息这个属性不需要程序员设置因为它是由打印对话框获取的

2、PrintCountroller 属性

控制打印过程

3、DefaultPageSettings 属性

存放页面设置信息 打印纸大小方向等也不需要程序员设置因为它是由页面设置对话框获取的

4、DocumentName 属性

指定文档名称,出现在打印机状态窗口中

1。 BeginPrint事件

在打印之前发出

2. PrintPage事件

每打印一页是发出,事件接受一个PrintPageEventArgs参数该参数封装了打印相关的信息

PrintPageEventArgs参数有很多重要的属性

1 Cancel 取消打印

2 Graphics 页面的绘图对象

3 HasMorePages 是否还有要打印的页面

Print 方法 该方法没有参数 调用它将按照当前设置开始打印

若实现打印功能首先构造PrintDocument对象添加打印事件

PrintDocument printDocument;

private void InitializeComponent()

{

...

printDocument=new PrintDocument();

printDocument.PrintPage += new PrintPageEventHandler (this.printDocument_PrintPage);

...

}

实现打印事件功能

打印和绘图类似都是调用Graphics 类的方法进行画图 不同的是一个在显示器上一个在打印纸上并且打印要进行一些复杂的计算

如换行 分页等。

private void printDocument_PrintPage(object sender,PrintPageEventArgs e)

{

StringReader lineReader = new StringReader(textBox.Text);

Graphics g = e.Graphics; //获得绘图对象

float linesPerPage = 0; //页面的行号

float yPosition = 0; //绘制字符串的纵向位置

int count = 0; //行计数器

float leftMargin = e.MarginBounds.Left; //左边距

float topMargin = e.MarginBounds.Top; //上边距

string line = null; 行字符串

Font printFont = this.textBox.Font; //当前的打印字体

SolidBrush myBrush = new SolidBrush(Color.Black);//刷子

linesPerPage = e.MarginBounds.Height / printFont.GetHeight(g);//每页可打印的行数

//逐行的循环打印一页

while(count linesPerPage ((line=lineReader.ReadLine()) != null))

{

yPosition = topMargin + (count * printFont.GetHeight(g));

g.DrawString(line, printFont, myBrush, leftMargin, yPosition, new StringFormat());

count++;

}

如果本页打印完成而line不为空说明还有没完成的页面这将触发下一次的打印事件在下一次的打印中lineReader会

自动读取上次没有打印完的内容因为lineReader是这个打印方法外的类的成员它可以记录当前读取的位置

if(line != null)

e.HasMorePages = true;

else

e.HasMorePages = false;

}

打印设置,构造打印对话框 将对话框中设置的Document属性赋给printDocument这样会将用户的设置自动保存到printDocument

的PrinterSettings属性中

protected void FileMenuItem_PrintSet_Click(object sender,EventArgs e)

{

PrintDialog printDialog = new PrintDialog();

printDialog.Document = printDocument;

printDialog.ShowDialog();

}

页面设置和打印预览与打印设置原理相同都是构造对话框将用户在对话框中的设置保存到相应的类的属性中

protected void FileMenuItem_PageSet_Click(object sender,EventArgs e)

{

PageSetupDialog pageSetupDialog = new PageSetupDialog();

pageSetupDialog.Document = printDocument;

pageSetupDialog.ShowDialog();

}

打印预览

protected void FileMenuItem_PrintView_Click(object sender,EventArgs e)

{

PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog();

printPreviewDialog.Document = printDocument;

try

{

printPreviewDialog.ShowDialog();

}

catch(Exception excep)

{

MessageBox.Show(excep.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

打印就可以直接调用printDocument的Print()方法因为用户可能在打印之前还要再更改打印设置所以

在这里再次显示打印设置对话框

protected void FileMenuItem_Print_Click(object sender,EventArgs e)

{

PrintDialog printDialog = new PrintDialog();

printDialog.Document = printDocument;

lineReader = new StringReader(textBox.Text);

if (printDialog.ShowDialog() == DialogResult.OK)

{

try

{

printDocument.Print();

}

catch(Exception excep)

{

MessageBox.Show(excep.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);

printDocument.PrintController.OnEndPrint(printDocument,new PrintEventArgs());

}

}

}

总结打印的过程是

1 在应用程序窗体初始化时构造PrintDocument对象 添加 printDocument 的 PrintPage 方法

2 实现PrintPage方法 4 在用户的单击事件中调用 printDocument 的 Print方法实现打印功能

在这中间可能要用到 PrintDialog PrintPreviewDialog PageSetupDialog 设置和查看打印效

VB.NET打印编程问题,打印机为激光打印机。

打印做得不多,以前做套打时发现,每台打印机定位都不一样,于是每台机子都加了个偏移设置

我的做法在白纸上打上一标尺,和一个上下边距为2CM的交叉点,然后用标尺量这2CM的偏移,设置完后,在这台打印机打印时,就给纸张加个偏移量,打印就正常了。可能你的原因和我一样。

另外也想问你一下,你这个条码是用什么打的。早先,我用立象的条码打印机打不干胶,很简单,激光打没用过,可能下次我也要用条码打印,我也用VB.net。求教.


新闻名称:vb.net打印机状态 c#获取打印机状态
网页地址:http://cqcxhl.com/article/hpjjei.html

其他资讯

在线咨询
服务热线
服务热线:028-86922220
TOP