1. 程式人生 > >VB下逐行列印的實現方法

VB下逐行列印的實現方法

用過Windows的人都知道,幾乎所有軟體,Word也好,Excel也好,AutoCAD也好,在列印的時候,一旦按下【列印】按鈕,印表機就會開始動作,然後整頁紙會被送入印表機,哪怕這張紙上僅有一個字也是如此。這就是所謂的“按頁”列印,。嗯,是的,這在一般情況下似乎也沒有什麼問題。但是,有的場合就不行了,比如票據列印,還有列印一些流水帳之類的東西,總不至於打一份記錄就用一整頁紙這麼誇張吧,所以我們必須找到一個“按行”列印的方法,當印表機打完一行後,並不執行出紙動作,而是停留在下一行的位置待命。因此我編寫了這個類,以方便需要用到“按行”列印的人士使用。

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

簡單講一下原理,我們都知道Windows程式在列印的時候都有一個“列印到檔案”的功能,這個功能可以講列印的內容存為一種字尾為.PRN的檔案,很多工具都能瀏覽這種檔案,比如Adobe的PageMaker。

當我們生成了.PRN檔案(而不是實質列印後),就能對檔案本身進行修改,根據我的實驗,發現該檔案最後三個位元組為“出紙”命令。Windows列印每次都換頁的祕密就在於此,簡單的,我們只需要將這三個位元組刪除,印表機就不會執行“出紙”命令了。

接著,我們將處理後的.PRN(最後三個位元組被刪除)檔案用常規的方法再實質性(也就是啟動印表機)列印一遍,印表機因為收不到“出紙”指令,所以它打完一行之後如果沒有新的內容,它就會卡在原處不動,除非有新的內容需要它再次啟動。

至此,完成“按行”列印的目的。

下面給出一個使用這個類的範例:

Dim LBL As New clsLBLPrn  '建立一個新的clsLBLPrn 類例項

LBL.StartDocs '開始一個新的列印任務

LBL.CurrentX = 30 'X座標設定

 LBL.CurrentY = 70 'Y座標設定

LBL.FontSize = 20 '設定字號

LBL.PrintText "I LOVE WWW.STONEREN.COM " '列印文字

LBL.PrintLine 1, 1, 100,100 '畫一條從座標1,1到100,100的直線

LBL.EndDocs   '開始列印

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

說明:
1. 本程式只使用於針式印表機
2. 本程式所使用的長度單位為“畫素”

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


首先按常規方法新增向工程裡新增一個類,取名為clsLBLPrn,並將以下內容複製進去:

' *************************************************************
' LBL (Line By Line) Print class
' 2004.06.01 Written By Rockage(Yang Hua)
' http://www.rockags.com http://www.stoneren.com
' email: [email protected]
' *************************************************************
' Author grants royalty-free rights to use this code.
' *************************************************************
Option Explicit

Private Type DOCINFO
cbSize As Long
lpszDocName As String
lpszOutput As String
lpszDatatype As String
fwType As Long
End Type

Private Type DOC_INFO_1
pDocName As String
pOutputFile As String
pDatatype As String
End Type

Private Type POINT_TYPE
x As Long
y As Long
End Type

Private Type LOGFONT
lfHeight As Long
lfWidth As Long
lfEscapement As Long
lfOrientation As Long
lfWeight As Long
lfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
lfPitchAndFamily As Byte
lfFaceName As String * 32
End Type

'Drawing API:
Private Declare Function CreateFontIndirect Lib "gdi32.dll" Alias "CreateFontIndirectA" (lplf As LOGFONT) As Long
Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Private Declare Function CreatePen Lib "gdi32.dll" (ByVal fnPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
Private Declare Function MoveToEx Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINT_TYPE) As Long
Private Declare Function LineTo Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long

'Printer API:
Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
Private Declare Function CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpszDriver As String, ByVal lpszDevice As String, ByVal lpszOutput As Long, lpInitData As Any) As Long
Private Declare Function StartPage Lib "gdi32.dll" (ByVal hdc As Long) As Long
Private Declare Function StartDoc Lib "gdi32.dll" Alias "StartDocA" (ByVal hdc As Long, lpdi As DOCINFO) As Long
Private Declare Function EndPage Lib "gdi32.dll" (ByVal hdc As Long) As Long
Private Declare Function EndDoc Lib "gdi32.dll" (ByVal hdc As Long) As Long
Private Declare Function GetProfileString Lib "kernel32" Alias "GetProfileStringA" (ByVal lpAppName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long) As Long
Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrn As Long, pDefault As Any) As Long
Private Declare Function StartDocPrinter Lib "winspool.drv" Alias "StartDocPrinterA" (ByVal hPrn As Long, ByVal Level As Long, pDocInfo As DOC_INFO_1) As Long
Private Declare Function StartPagePrinter Lib "winspool.drv" (ByVal hPrn As Long) As Long
Private Declare Function WritePrinter Lib "winspool.drv" (ByVal hPrn As Long, pBuf As Any, ByVal cdBuf As Long, pcWritten As Long) As Long
Private Declare Function EndPagePrinter Lib "winspool.drv" (ByVal hPrn As Long) As Long
Private Declare Function EndDocPrinter Lib "winspool.drv" (ByVal hPrn As Long) As Long
Private Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrn As Long) As Long

Private lf As LOGFONT, itsCurrentX As Long, itsCurrentY As Long
Private pt As POINT_TYPE
Private ret As Long
Private hPrintDC As Long
Private di As DOCINFO
Private prnName As String, strDOC As Boolean

Public Property Let CurrentY(ByVal vNewValue As Long)
itsCurrentY = vNewValue
End Property

Public Property Let CurrentX(ByVal vNewValue As Long)
itsCurrentX = vNewValue
End Property

Public Property Let FontSize(ByVal vNewValue As Long)
lf.lfHeight = vNewValue
End Property

Public Sub PrintLine(ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long)
MoveToEx hPrintDC, X1, Y1, pt
LineTo hPrintDC, X2, Y2
End Sub

Public Sub PrintText(ByVal strText As String)
Dim hFont As Long, hOldFont As Long

hFont = CreateFontIndirect(lf)
hOldFont = SelectObject(hPrintDC, hFont)
ret = TextOut(hPrintDC, itsCurrentX, itsCurrentY, strText, LenB(StrConv(strText, vbFromUnicode)))
ret = SelectObject(hPrintDC, hOldFont)
ret = DeleteObject(hFont)

End Sub

Public Sub EndDocs()

If strDOC Then

ret = EndPage(hPrintDC) '結束虛擬列印,temp.prn過渡檔案生成完畢
ret = EndDoc(hPrintDC)

'--------------------------------------------
'進入實質列印:

Dim hPrn As Long
Dim Written As Long
Dim I As Long
Dim hFile As Integer
Dim sFile As String
Dim Buffer() As Byte, lstByte As Long
Dim di2 As DOC_INFO_1

hFile = FreeFile
sFile = App.Path & "/" & "temp.prn" '裝載過渡檔案

di2.pDocName = sFile
di2.pOutputFile = vbNullString
di2.pDatatype = "RAW"

Call OpenPrinter(prnName, hPrn, ByVal 0&)
Call StartDocPrinter(hPrn, 1, di2) '開啟一個直傳模式的列印Job
Call StartPagePrinter(hPrn)

hFile = FreeFile


Open sFile For Binary Access Read As hFile

If LOF(hFile) > 0 Then
'
ReDim Buffer(1 To LOF(hFile)) As Byte
lstByte = UBound(Buffer) - 3 'temp.prn檔案的最後三個位元組為翻頁指令,此處將此3位元組過濾

For I = 1 To lstByte
Get #hFile, , Buffer(I)
Next I

Call WritePrinter(hPrn, Buffer(1), lstByte, Written) '資料直接傳送到印表機
End If 'lof=0
Close #hFile

Call EndPagePrinter(hPrn)
DoEvents
Call EndDocPrinter(hPrn) '結束列印
Call ClosePrinter(hPrn)
ret = DeleteDC(hPrintDC)
strDOC = False
Kill sFile '刪除過渡檔案

End If

End Sub

Public Sub StartDocs()


'建立一個與預設印表機相關聯的DC:
hPrintDC = CreateDC("WINSPOOL", prnName, 0, ByVal CLng(0))

di.cbSize = Len(di)
di.lpszDocName = "Heavy Metal Forever" '列印標題,隨意設
di.lpszOutput = App.Path & "/" & "temp.prn" '列印到過渡檔案
di.lpszDatatype = ""
di.fwType = 0

ret = StartDoc(hPrintDC, di) '以傳統模式開始一個列印Job
ret = StartPage(hPrintDC)
strDOC = True

End Sub

Private Sub Class_Initialize()

Dim sRet As String
Dim nRet As Integer
Dim I As Integer
'
'查WIN.INI 中的預設印表機:
sRet = Space(255)
nRet = GetProfileString("Windows", ByVal "device", "", sRet, Len(sRet))
sRet = UCase(Left(sRet, InStr(sRet, ",") - 1))

prnName = sRet '預設印表機

End Sub


Private Sub Class_Terminate()
'Exit Code
End Sub

 

相關推薦

VB列印實現方法

用過Windows的人都知道,幾乎所有軟體,Word也好,Excel也好,AutoCAD也好,在列印的時候,一旦按下【列印】按鈕,印表機就會開始動作,然後整頁紙會被送入印表機,哪怕這張紙上僅有一個字也是如此。這就是所謂的“按頁”列印,。嗯,是的,這在一般情況下似乎也沒有什麼問

iOS的後臺任務實現方法

後臺任務 場景一 地圖後臺定位   場景二 後臺播放音樂 場景三  後臺 更新推送內容  場景四  voip  IP電話   視訊通話 關於Background Fet

Swift的print不換列印方法

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Eclipse-格式化程式碼時不換與自動換實現方法

preferences->Java->Code Style->Code Formatter->Show… ,開啟之後,選擇“Line Wrapping”選項卡,在“Maximun line width”指定大於多少列時換行。 還是在“

Win10 60程式碼實現多執行緒PDF轉Word 執行錯誤摘要

當我們在win10中按要求裝好包,執行“60行程式碼實現多執行緒PDF轉Word”專案時,總會出現一些編碼問題,現整理如下。 問題一: 解決方案,在主程式中新增程式碼片: import l

Eclipse 格式化程式碼時不換與自動換實現方法

1、preferences->Java->Code Style->Code Formatter->Show... ,開啟之後,選擇“Line Wrapping”選項卡,在“Maximun line width”指定大於多少列時換行。  2、還是在“Line Wrapping”選項卡中

VB對序列介面第9位的操作以及API實現方法

RS232-485序列介面是一種非常成熟的通訊介面,曾幾何時,我們用的滑鼠是串列埠的,Modem是串列埠的,還有早期的一些數碼相機都是串列埠的,時過境遷,家用電腦現在已是USB時代,串列埠這種東西逐漸淡出了我們的視線。 但是,在工業控制上,序列介面依然有著不可替代的優勢,首先

Linux《UNIX環境高級編程》undefined reference to `err_quit 編譯出錯的處理方法

reg init def bre linux tput linux下 pan termios 錯誤信息: : undefined reference to `err_quit‘: undefined reference to `err_sys‘ 解決方法: 因為err

提高VMware虛擬機服務系統運性能方法

space 對話 列表 usb water 稱多 add reg oss 提高VMware虛擬機下服務系統運行性能方法 因測試環境物理資源有限,往往公司會提供一臺配置相對不錯的物理服務器讓我們在該服務器裏面安裝多個虛擬主機,如果物理服務器是linux之類的操作系統可以使

Windows系統某些程序時缺少“Msflxgrd.ocx”的解決方法

系統 wow reg svr3 TP sys 下載 http 窗口 出現這樣的錯誤就是系統缺少相應的庫文件,我們安裝即可。 下載Msflxgrd.ocx,這裏提供一個下載網址:https://www.ocxme.com/files/msflxgrd_ocx 64位系統

python使用讀取,出現空,清楚空方法

參考 文件 txt utf rip blog open href .html 腳本如下: #!/usr/bin/python -*- coding: utf-8 -*- for line in open("awip.conf"): print(line.strip

關於WPF用戶登錄後再啟動主窗體的實現方法

但是 color event mar 登陸 one 測試 public close /// <summary>App.xaml 的交互邏輯</summary> public partial class App : Application

PCB Genesis 無需啟動Xmanager圖形窗口運腳本 實現方法

class 方法 script pre 內存 信息 場景 取出 答案 從事PCB工程行業的都知道,啟動Genesis需2個exe程序(Xmanager.exe與get.exe)需一起啟動才可以打開我們熟悉的軟件, 而Xmanager是圖形窗口是給用戶UI交互使用的,如果僅僅

python讀取大檔案的方法 python計算檔案的數和讀取某一行內容的實現方法

 python計算檔案的行數和讀取某一行內容的實現方法 :最簡單的辦法是把檔案讀入一個大的列表中,然後統計列表的長度.如果檔案的路徑是以引數的形式filepath傳遞的,那麼只用一行程式碼就可以完成我們的需求了:   1、http://blog.csdn.net/shudaq

linux匯入、匯出mysql資料庫命令的實現方法

首先建空資料庫 mysql>create database abc; 匯入資料庫 mysql>use abc; 設定資料庫編碼 mysql>set names utf8; 匯入資料(注意sql檔案的路徑) mysql>source /home/abc/abc.sql;

實現兩個檔案內容進行對比的shell指令碼

寫一個實現兩個檔案內容逐行進行對比的shell指令碼,將兩個檔案相同的內容輸出到一個檔案中。 程式碼實現如下: #!/bin/bash #output is the same line in file1 andfile2 for line1 in $(cat $1) do

Android 不同格式字型的實現方法

從師兄那裡看到了android 介面不同格式字型的實現方法,記錄下來以便以後檢視。 首先在Android Studio中建立assets資料夾,在assets資料夾下建立fonts資料夾,然後將字型檔案.ttf檔案拷貝至fonts資料夾下。 在android studio中建立a

windows 借助7zip實現命令解壓縮

電腦下載 調用 處理 文件 left 解壓 壓縮 dll 命令行 windows 下借助7zip實現命令行解壓縮 64位電腦下載 https://www.7-zip.org/a/7z1805-x64.exe 安裝 安裝目錄下所有文件如下: 在命令行下只需要用到 7z

微信小程式拉載入和上拉重新整理兩種實現方法

方法一:onPullDownRefresh和onReachBottom方法實現小程式下拉載入和上拉重新整理 首先要在json檔案裡設定window屬性             屬性  

微信小程式上拉重新整理和拉載入2種方法實現

微信小程式上拉重新整理和下拉載入2種方法實現,onPullDownRefresh,scroll-view使用 一、XXX.json開啟下拉重新整理 {    "enablePullDownRefresh": true }   二、XXX.js onP