VB中打印机选择.docx
《VB中打印机选择.docx》由会员分享,可在线阅读,更多相关《VB中打印机选择.docx(18页珍藏版)》请在冰豆网上搜索。
VB中打印机选择
(1)
假设你的COMMONDIALOG控件叫CMDiag
用如下代码可以使你选择的打印机成为默认打印机"Printer"
OnErrorResumeNext
CMDiag.PrinterDefault=True
CMDiag.CancelError=True
CMDiag.ShowPrinter
IfErr.Number<>0ThenExitSub
(2)
VB里面,原本改变预设打印机的方法是:
(假设安装有两种打印机(驱动程式))
SetPrinter=Printers(O)'将预设打印机设定成第一种打印机
SetPrinter=Printers
(1)'将预设打印机设定成第二种打印机
但实际上以上叙述有时候不会成功(原因不详),为了能够成功地改变预设打印机,
以下是呼叫WindowsAPI的方法:
(此一解决方案适用於Windows95,98)
1.API的宣告:
ConstHWND_BROADCAST=&HFFFF&
ConstWM_WININICHANGE=&H1A
PrivateDeclareFunctionGetProLib"kernel32"Alias_
"GetPro"(ByVailpAppNameAsString,ByVailpKeyNameAs_
String,ByVallpDefaultAsString,ByVallpReturnedStringAsString,_ByValnSizeAsLong)AsLong
PrivateDeclareFunctionWriteProLib"kernel32"Alias_
"WritePro"(ByVallpszSectionAsString,ByVallpszKeyName_
AsString,ByVallpszStringAsString)AsLong
Long,
PrivateDeclareFunctionSendMessageLib"user32"Alias"SendMessageA"(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAslParamAsAny)AsLong
2.程式范例:
PrinterName="您想设定的打印机名称"
DimSAsString,lengthAsLong,hKeyAsLong
S=String(80,Chr(O))
length=GetPro("devices",PrinterName,"",S,Len(S))
S=Left(S,length)
&S)
CallWritePro("windows","device",PrinterName&
至於改变NT预设打印机的方法,则是改变登录资料库(Registry)打印机的设定,
在登录资料库中纪录
预设打印机的Value是:
HKEY_CURRENT_USER
\Software\Microsoft\WindowsNT\CurrentVersion\Windowssubkey的Devicevalue
(3)VB中获取指定打印机的各种纸张类型及大小
放入一个MSFIexGrid,名称为fgdl,列数为4
'Option
Explicit
Private
Const
DC_MAXEXTENT=
5
Private
Const
DC_MINEXTENT=
4
Private
Const
DC_PAPERNAMES
16
Private
Const
DC_PAPERS=2
Private
Const
DC_PAPERSIZE=
3
Private
Declare
FunctionDeviceCapabilities
Lib
"winspool.drv"
Alias
"De
viceCapabilitiesA"
(ByVallpDeviceNameAs
String,
ByVal
lpPort
As
Strin
g,ByVal
ilndex
AsLong,lpOutputAs
Any,lpDevMode
AsAny)
As
Long
PrivateTypePOINTS
xAsLong
yAsLong
EndType
PrivateSubForm_Load()
DimiAsLong
Withfgdl
.Clear
.FormatString="A纸张编号|A纸张名称|A纸张长度|A纸张宽度”
Fori=0To.Cols-1
.ColWidth(i)=1700
Nexti
.AllowUserResizing=flexResizeColumns
.Left=0
.Width=Me.ScaleWidth
EndWith
GetPaperInfo
EndSub
PrivateSubGetPaperInfo()
DimiAsLong,retAsLong
DimLengthAsInteger,WidthAsInteger
DimPaperNo()AsInteger,PaperName()AsString,PaperSize()AsPOINTS'支持最大打印纸:
ret=DeviceCapabilities(
打
印
机
名
称,"LPT1",DC_MAXEXTENT,ByVal
0&,
ByVal
0&)
Length=ret\65536
Width=ret-Length
*65536
'lblMaxLength.Caption=
Length
'IbIMaxWidth.Caption=
Width
'支持最小打印纸:
ret=DeviceCapabilities(
打
印
机
名
称,"LPT1",DC_MINEXTENT,ByVal
0&,
ByVal
0&)
Length=ret\65536
Width=ret-Length
*65536
'支持纸张种类数
ret=DeviceCapabilities(
打
印
机
名
称,"LPT1",DC_PAPERS,ByVal
0&,ByVal
0&)
'纸张编号
ReDimPaperNo(1Toret)As1
Integer
CallDeviceCapabilities(
打
印
机
名
称,"LPT1",DC_PAPERS,PaperNo
(1),ByVal
0&)
'纸张名称
DimarrPageName()AsByte
DimallNamesAsString
DimlStartAsLong,lEndAs
Long
ReDimPaperName(1Toret)As
String
ReDimarrPageName(1Toret*
64)AsByte
CallDeviceCapabilities(
打
印
机
名
称,"LPT1",DC_PAPERNAMESarrPageName
(1),
ByVal0&)
allNames=StrConv(arrPageName,
vbUnicode)
'loopthroughthestringand
searchfor
the
namesof
thepapers
i=1
Do
IEnd=InStr(IStart+1,allNames,Chr$(O),vbBinaryCompare)
If(lEnd>0)And(lEnd-lStart-1>0)Then
PaperName(i)=Mid$(allNames,lStart+1,lEnd-lStart
-1)
i=i+1
EndIf
lStart=lEnd
LoopUntillEnd=0
'纸张尺寸
ReDimPaperSize(1Toret)AsPOINTS
CallDeviceCapabilities(Form2.Combo1.Text,"LPT1",DC_PAPERSIZE,PaperSize(
1),ByVal0&)
'显示在表格中
Fori=1Toret
fgdl.AddltemPaperNo(i)&vbTab&PaperName(i)&vbTab&Paper
Size(i).y&vbTab&PaperSize(i).x
Nexti
'移除第一个空行
fgd1.Row=1
fgd1.RemoveItem1
EndSub
PrivateSubForm_Resize()
Withfgd1
.Left=0
.Width=Me.ScaleWidth.Height=Me.ScaleHeight
.Top=0
EndWith
EndSub
(5)编写VB打印控制程序的几点心得
摘要本文在总结作者实际开发经验的基础上,详细介绍了VB实现高分辨率打印方法
的几点心得。
阐述了参数化绘图程序缩短打印程序开发时间的方法以及打印机缩放属性与窗体属性匹配使用的技巧,并总结了解决坐标定位、图形与其实际打印
位置出现误差等问题的经验。
关键词PrintForm高分辨率打印参数化绘图缩放属性
SomeExperiencesonVBPrintControl
BaiYang,WangPeng
ComputerScienceDepartment
UniversityofInformationandEngineering
Zhengzhou,China
Abstract:
Onthebasisofourworkingexperiences,wehavegivenadetail
descriptionaboutVBprintmethodofhighresolution.Wefocusonhowtoshorten
developingperiodwithparameterizedplotprogram,thematchbetweenthezoom
attributeandtheattributeofdisplaywindowetc.,whichbasedonprintprogram
ofPrinterObject.Inadditiontothis,wehaveintroducedsomeexperiencesondealingwithpositionerrorthatcausedbythemismatchbetweenfontandgraphonscreenandthatonprinter.
Keywords:
PrintForm,HighResolutionPrint,parameterizedplot,zoom
attribute
1.简介
VisualBasic(VB)给用户提供了可视化编程环境,因其简单易学、功能强大而得到
了广泛的应用。
VB提供了两种实现打印的方法。
一般在对打印质量要求不高的场合,或者是编程项目的早期开发过程中,可以直接使用VB窗体的Printform方法实现打印。
用这种
方法实现打印具有编程简单、易用并且功能强大的优点,它只需要通过一行代码,几乎能打印所有内容。
实现的方法就是:
首先将要打印的内容在屏幕上显示出来,然后开发人员只要
为窗体对象激活PrintForm,窗体则自动将要打印的内容发送到Printer对
象上,其语法格式如下:
[窗体.]PrintForm。
如果窗体中包括图形,那么打印前应先置窗
体的AutoRedraw属性为真。
这种方法虽然简单,但是它却存在着内存消耗大、打印粗糙、速度慢等缺陷,尤其对于带有滚动条的图像,这种方法只能打印当前可视的区域。
在实际应
用中经常会遇到对打印质量要求很高的场合,例如打印音乐五线谱,对打印的美观、清晰度
以及音符符头的位置都有很严格的要求,这种应用场合若采用VB提供的另一种基于Printer
对象的打印方法则可以获得高分辨率的打印,得到很高的打印质量。
在实际应用中,也可以
根据实际应用情况将上述两种方法结合起来使用,即:
前期工作使用PrintForm简单的打
印方法将窗体的布局定下来,后期再使用基于Printer对象的打印方法实现最终的打印工
作。
2.高分辨率打印程序开发心得
⑴Printer对象
VB的打印可以使用Printer对象。
Printer对象是一个独立于打印机设备的封装,它可以代表不同的打印机,初始时,Printer对象为系统缺省的打印机,也可以使用下列语句:
SetPrinter=Printers
(2)(其中2代表Printers集中的第二个打印机)对打印机进行指
Printer对象具备例如:
ColorMode、Copies、Duplex、Printquality等控制打印机
特征的属性,提供了NewpageEndDocKillDoc等控制打印过程的方法,以及大多数由窗体和图片框控件提供的图形属性和方法如:
Currentx、Currenty、Textwidth、Textheight、
Print、Pset、Line、PaintPicture和Circle等方法,它还拥有Font的所有属性。
实现高分辨率的打印就是通过控制Printer对象的上述属性和方法完成的。
⑵直接利用Windows公用标准对话框CommonDialogK件【打印】
VB为用户提供了Windows公用标准对话框CommonDialog控件:
【打开】、【文件另存为】、【颜色】、【字体】、【打印】。
CommonDialog控件在VisualBasic和MicrosoftWindows动态连接库Commdlg.dll例程之间提供了接口。
利用公用标准对话框【打印】开发VB的打印程序,将大大缩短程序的开发周期。
应用程序中要使用公用对话框,必须首先在工具箱中添加公用对话框控件。
该动作通过激活【部件】对话框,选中MicrosoftCommon
DialogControl6.0,单击【确定】即可。
然后再将公用控件添加到窗体上并设置相应属性,该控件具有的属性有Color、Font、Print、Help等。
VB提供mnu()过程供用户添加开发的打印程序代码。
⑶Printer对象控制打印的基本过程
利用Printer对象开发的打印程序主要靠其提供的NewPage(打印新的
一页,CurrentX、CurrentY置为新页的左上角,可完成多页功能。
)、EndDoc(将打印任务加入打印机队列)、KillDoc(取消打印任务)控制打印过程的。
一
般情况下,打印程序完成多页打印时会多次执行NewPage,结束时执行一次
EndDoc将打印任务加入打印机队列。
如果你在NewPage后,立即使用EndDoc,
VB则不会打印额外的空白页。
如果希望显示空白页,则可在新的一页上只使用
Printer.Print打印空字符即可。
为了通过Printer对象实现文本和图形的打印,获得最好的打印质量,还需要对VB控制打印机的多种属性有更深入的理解,例如打印机的坐标体系向屏幕坐
标体系的转换、打印机字体尺寸的确定等。
下面给出了打印程序的主框架:
PrivateSubmnuClick()
OnErrorResumeNext
IfActiveFormIsNothingThenExitSub
WithdlgCommonDialog'打印机公用对话框
.DialogTitle="打印"
.CancelError=True
.Flags=1
Printer.FontSize=dlgCommonDialog.FontSize
'将打印机公用对话框设置的字体大小传递
给打印机
.ShowPrinter‘在屏幕上显示【打印】公用对话框
IfErr<>MSComDlg.cdlCancelThen
Printer.FontTransparent=False'初始化打印的字体为
不透明
SetPrinterScaleMyform
的属性
PrintAnywherePrinter
参数化例程
'匹配打印机的缩放属性与窗体
'可放置用户编写的打印对象
'实现字符和图形的显示
Printer.NewPage
'打印机坐标初始化
PrintAnywherePrinter
‘打印另一页的内容
Printer.NewPage
'打印机坐标初始化
Printer.EndDoc
'将该任务加入打印机任务队
列
不打印空白页
Printer.KillDoc
'取消当前的打印任务
EndIf
EndWith
EndSub
⑷参数化绘图程序
用VB开发应用程序时,如果使用参数化绘图例程进行屏幕显示程序的开发,则在开发打印程序时,就不需再另行开发代码,从而避免了大量的重复劳动,有效地缩短了程序的开发周期。
参数化绘图例程就是:
在开发例程时,为每一个例行程序提供一个OBJECTS型的参数,调用程序通过向例程的OBJECTS型参数分别传递窗体、Printer对象,就可分别完成屏幕显示与打印机输出。
见如下示
例:
SubPrintAnywhere(DestAsObject)
Dest.Print“HELLO”
DestIsPrinterThen
Printer.EndDoc
EndIf
EndSub
要完成屏幕上的输出,调用PrintAnywhereMyform即可,而调用PrintAnywherePrinter则完成在打印机上输出。
⑸属性匹配与窗体缩放
因为控制打印机实际绘图区域大小的属性Height和Width,由目前正在使用
的纸张决定,而且可打印的区域与纸张边缘有一定距离。
因而为了获得正确的打
印输出结果,不能简单地将Printer对象直接传递给绘图例行程序,还必须要解决打印机的缩放属性与显示窗体属性相匹配的问题。
即:
保证使窗体中的打印内
容以正确的大小显示,并居于可打印区域的中间。
实际上实现的是打印机的坐标体系向屏幕坐标体系的转换。
具体过程是:
使用打印机的ScaleX和ScaleY方法,获取以twip为单位的打印机尺寸,再利用窗体的ScaleX和ScaleY方法将这些尺寸转换为窗体中的坐标系统,从而实现以窗体的坐标系统提供打印机可打印区域大小的目的。
然后,用这些尺寸作为打印机中新的ScaleWidth和ScaleHeight,即可实现属性匹配。
但是,我们在打印时,经常会遇到这样的场合一一在不改变窗体形状的情况下,需要扩大或缩小窗体的大小。
要完成这样的工作,不仅需要完成属性匹配,还要确定对象被缩放的系数。
程序如下:
PrivateSubSetPrinterScale(objAsObject)
DimpwidAsSingle,phgtAsSingle,xmidAsSingle,ymidAsSingle
DimowidAsSingle,ohgtAsSingle
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
EndIf'计算缩放因子
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
EndSub
⑹坐标定位
窗体、图片框控件以及Printer对象提供的TextWidth和TextHeight方法在文本定位的应用方面很有用。
TextWidth、TextHeight分别以对象当前的刻度单位返回字符串的宽度和高度。
但是必须注意很多字体中其字符宽度并不全部相同,所以不能简单地将单个字符的宽度乘以字符数来获得字符串的宽度。
对那些
没有TextWidth和TextHeight的控件可通过设置父窗体的Font属性,使其与该控件的属性相匹配,再利用父窗体的TextWidth和TextHei