home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1995 May
/
cica_0595_4.zip
/
cica_0595_4
/
UTIL
/
VBBOOK
/
VBBOOK.DOC
< prev
next >
Wrap
Text File
|
1991-09-06
|
27KB
|
714 lines
VB BOOK - Utility to print ASCII text files to LaserJet Series II, IIp or III
in booklet format.
Based on the program, PC BOOK, by Jay Munro, Copyright 1990 PC Magazine -
Ziff Davis - Jay Munro. Original Copyright still applicable (as far as I'm
concerned).
Originally written by Jay Munro and converted to Visual Basic by Dennis Scott
on 1 September 1991.
Documentation adapted from original PCBOOK.DOC file:
----------------------------------------------------
Purpose:
VB BOOK prints README and similar ASCII files in booklet format on an HP
LaserJet II, IIp, or III printer. Uses two-sided printing in landscape mode,
with Line Printer font so that four standard pages of 80 characters per line,
66 lines per page are printed on each sheet without formatting changes.
Remarks:
The filename can designate any ASCII text file in which each line is
terminated with a Carriage Return/Line Feed combination. Page Feed characters
can be added to force breaks in addition to those implicit in the 60-line
(68-line if a header is used) page length.
The original switches in PC Book have been replaced with Windows Checkboxes.
Any or all of the Checkboxes can be used to create a one-line header that
prints the filename, page number, and date, on all but blank pages. The Wrap
Checkbox causes lines exceeding 80 characters to wrap; by default such lines
are wrapped.
Output can now be directed to LPT1, LPT2, COM1, COM2, or File. Noted that
you must set the proper parameters for your port before printing to a COM
port. If File is selected, you will be prompted to enter an output filename.
VB BOOK sequences the page printing so that all side-one pages are printed in
one pass. The sheets are then put back in the LaserJet paper tray and all
side-two pages are printed. The finished booklet can then be created with a
single fold. When using the normal (top) LaserJet output bin the pass-one
sheets should be reinserted in the paper tray without any relative change
in orientation. If rear output from the printer is used, the sheets must be
turned over as a group before reinsertion.
Requirements:
VB Book requires Windows 3. The Visual Basic Run Time file, VBRUN100.DLL,
must be in the path (recommend putting it in your Windows directory).
Modifications will require Microsoft Visual Basic Version 1.0. Both the
executable and the source files for VB Book are provided.
Comments to QuickBASIC programmers:
The conversion of PC Book from QuickBASIC to Visual Basic (VB) was undertaken
as an exercise in converting original QuickBASIC (QB) source code into VB code.
It was surprisingly easy!
The hardest part was deciding HOW the screens (forms in VB) should look.
Actually designing the forms is very easy. Once the forms were designed, I
just used "load text" to get the original QB code into the main form. VB does
almost everything automatically. For example, all SUBs are automatically
created and the old code placed in them.
Some things will need to be changed, of course. Any input from the user
(QBs Input, Line Input, and Inkey commands) needs to converted to "InputBox$"
functions. Similarly, the "print" statements (with corresponding Locate's)
were converted to "MsgBox" functions or a form created to place them onto.
The QB code that performed initialization was placed in the main form's
Form_Load procedure. All Declare's were removed. Most of the above changes
were accomplished by pressing F5 (run) and letting VB tell me what it didn't
like. I just used the ol' cut & paste to put things in the right place.
I then defined what should happen when each of the controls on the forms were
activated (usually clicked) and wrote the code into those areas. Putting the
drive, directory, and file selection boxes on the screen and activating them
is phenomenally easy!
The overall concepts of VB are a little difficult to comprehend at first but
then it clicks and it all becomes quite simple. I would highly recommend that
you take the tutorial before doing anything. If you don't, you will not
comprehend what's going on and will probably get disgusted and quit.
This conversion took about a day to do because of having to learn VB. If I
had to do it again I could probably complete it in an hour or less. Please
note that the code has not been "cleaned up" - some debugging code may still
be there.
Recommended additions:
Want some practice with VB? Why not add: A screen preview of output while
printing (or before printing or instead of printing) and status display of
percent completed.
If anyone adds this capability or changes the code in some other way, please
be kind enough to send me a copy.
Please send comments or suggestions to:
Dennis Scott
CompuDirect
9102 Ocean Gate
San Antonio, TX 78242
(512)623-6856
Disclaimer:
The standard disclaimer applies: Use this program at you own risk. Myself,
and the original Copyright holder, will not be held responsible for anything!
The Source Code:
----------------
The following is a complete listing of the VB source code, included here for
those to see that do not yet own VB. For those that do own VB, the forms and
code are also included in the archive. Just place all files in their own
directory then open the VBBOOK project. Note that almost all of the following
code was originally PC Book code - very little had to be added for VB.
The Global form (VBBOOK.BAS):
-----------------------------
Type Flags 'Misc flag variables
CurDate As Integer
DoHeader As Integer
FileTitle As Integer
LineLen As Integer
LineWrap As Integer
PgNumber As Integer
End Type
'The VBBOOK.FRM form: (used for the first little box that goes away in 5 sec's.)
'--------------------
'(No code in this form. Just displays a message for 5 secs)
'The VBBOUT.FRM form:
'--------------------
'(No code in this form. It's a blank, full-page form used to cover up the
'desktop. There should be a better way to do this!)
'The Main module, VBBINP.FRM: (This is where all the selections are done.)
'----------------------------
'Declarations section:
'Note that Dim Shared is not really needed but VB done it during the automatic
'conversion from QuickBasic code so I left it that way.
Dim Shared ESC$, FF$, LF$, filename$, OUTFILE$, NL$
Dim Shared page%, num$, tune%
Dim Shared PC As Flags
Dim lastchange As Integer
Const fileboxclick = 0, dirsboxclick = 1 'Used by file selection routine
Const true = -1, false = 0
'Now the Subs start:
Static Sub BuildArray (ptrarray&(), pgcount%)
MaxLines% = 66 'Maximum number of lines
Offset& = 1 'Start of file (seek point)
Open filename$ For Binary Access Read As #1 Len = 1 'Open file to check
TotalSize& = LOF(1) 'Get LEN of file so we don't read too far
FileLeft& = TotalSize& 'Setup a counter to show whats left
'FRE is not supported by VB. Just set it to 64K
MemAvail& = 65536 'FRE(FileName$) - 2048 'Check available string memory
If MemAvail& < 2048 Then Error 14 'Force out of memory error
SixteenK% = 16384
If TotalSize& > SixteenK% Then 'Set a buffer size
If MemAvail& > SixteenK% Then 'If the file is larger than 16K
BufAvail& = SixteenK% 'Set it to 16k
Else
BufAvail& = MemAvail&
End If
Else
If TotalSize& < MemAvail& Then 'Otherwise set it to file size
BufAvail& = TotalSize&
End If
BuffSize% = BufAvail&
End If
pgcount% = 1 'Initialize page count
ptrarray&(pgcount%) = 1 'First pointer is always 1
LnCount% = 0 'Initialize line count
GetPage: 'Read the file
If FileLeft& < BufAvail& Then 'Check amount left to read
Buffer$ = Space$(FileLeft&) 'If less than our buffer, use lessor
Else
Buffer$ = Space$(BufAvail&) 'Otherwise use full buffer size
End If
Get #1, Offset&, Buffer$ 'Read in a buffers worth
stptr% = 1 'Pointer into buffer$
LastLine% = 0 'remember last position
PageCheck:
TempLn% = InStr(stptr%, Buffer$, LF$) 'Position of next linefeed
temppg% = InStr(stptr%, Buffer$, FF$) 'Position of next pagefeeds
If temppg% Then 'If there was a page feed
If temppg% < TempLn% Or TempLn% = 0 Then ' was it before our linefeed?
pgcount% = pgcount% + 1 ' yes then bump page count
ptrarray&(pgcount%) = Offset& + temppg% ' set next array element
stptr% = temppg% + 1 ' set instr pointer
LnCount% = 0 ' reset linecount
If stptr% < Len(Buffer$) Then GoTo PageCheck 'and loop back for more
End If
End If
If TempLn% Then 'Linefeed
If PC.LineWrap Then 'If Line Wrap, check length
If TempLn% - stptr% > PC.LineLen Then 'Greater than 80?
Do 'check for line wrap
LnCount% = LnCount% + 1 'increment line
If LnCount% = MaxLines% Then
GoTo PageBreak '> 66 lines
End If
stptr% = stptr% + PC.LineLen
Loop While TempLn% - stptr% > PC.LineLen
End If
End If
LnCount% = LnCount% + 1 'Increment page count
PageBreak:
If LnCount% = MaxLines% Then
pgcount% = pgcount% + 1
If pgcount% > 512 Then
msg$ = "Too may pages - printing only 512."
MsgBox msg$, 0, "Notice"
GoTo EndBuild
End If
ptrarray&(pgcount%) = Offset& + TempLn% 'point to next in point in file
LnCount% = 0
End If
stptr% = TempLn% + 1 'point ahead 1 byte for next scan
If stptr% <= Len(Buffer$) Then
GoTo PageCheck 'keep checking
End If
End If
Offset& = Offset& + Len(Buffer$) 'Pointer into file (tally)
stptr% = 1 'Reset Buffer pointer
FileLeft& = TotalSize& - Offset& 'Calculate how much is left
If Offset& < TotalSize& Then GoTo GetPage 'If more text in file, keep going
EndBuild:
ptrarray&(pgcount% + 1) = TotalSize& 'Set last pointer to end of file
Close #1 'Close input file
End Sub 'End of BuildArray Sub
Sub Label1_load ()
'This section is not used at this time
Print String$(80, 61)
Print "PCBook - PC Magazine Booklet Printing Utility"
Print "Copyright 1990 PC Magazine Ziff Davis Jay Munro"
Print
Print "Converted to Visual Basic by Dennis Scott"
Print String$(80, 61)
End Sub
Static Sub DoMacro (num$)
Print #2, ESC$; "&f"; num$; "y2X"; 'execute the macro
End Sub
Static Sub EndMacro (num$)
Print #2, ESC$; "&f"; num$; "y1X"; 'Send end of macro command
Print #2, ESC$; "&f"; num$; "y9X"; 'Make it temporary (10 to be permanent)
End Sub
Static Sub Header (page%)
hdr$ = Space$(PC.LineLen) 'Create a string to print
If PC.FileTitle Then 'Print the filename
Mid$(hdr$, 40 - Len(filename$) \ 2) = UCase$(filename$)
End If
If PC.PgNumber Then 'Print the current page
PTemp$ = "Page" + Str$(page%)
If page% Mod 2 Then
Mid$(hdr$, PC.LineLen - Len(PTemp$)) = PTemp$ 'odd page, right side
Else
Mid$(hdr$, 1) = PTemp$ 'even page, left side
End If
End If
If PC.CurDate Then 'Print the current date
If page% Mod 2 Then
Mid$(hdr$, 1) = Date$ 'even page, left side
Else
Mid$(hdr$, PC.LineLen - Len(Date$)) = Date$ 'odd page, right side
End If
End If
Print #2, hdr$ 'Print the Header
Print #2, ' and skip a line for readability
End Sub
Static Sub LJLocate (X%, Y%) 'Laser Jet cursor locate
Temp$ = ESC$ + "&a" + LTrim$(Str$(Y%)) + "r" + LTrim$(Str$(X%)) + "C"
Print #2, Temp$;
End Sub
Static Sub printlogo () 'Banner logo (About VB Box!)
msg$ = " VB Book" + NL$
msg$ = msg$ + " Converted to Visual Basic" + NL$
msg$ = msg$ + " by Dennis Scott." + NL$
msg$ = msg$ + NL$
msg$ = msg$ + "Send Comments/Suggestions to:" + NL$
msg$ = msg$ + " CompuDirect" + NL$
msg$ = msg$ + " 9102 Ocean Gate" + NL$
msg$ = msg$ + " San Antonio, TX" + NL$
msg$ = msg$ + " (512)623-6856" + NL$
MsgBox msg$, 0, "About VB Book"
End Sub
Sub PrintSetup () 'Send codes to prepare printer
Print #2, ESC$; "E"; 'Reset laserjet (simple isn't it!)
Print #2, ESC$; "&l1o5.45C"; 'Select lineprinter font"
Print #2, ESC$; "(s0p16.66H"; ' and pitch
Print #2, ESC$; "&l0L"; 'Turn off page feed at 66 lines
If PC.LineWrap Then 'Wrap lines > 80 chars
Print #2, ESC$; "&s0C";
End If
Print #2, ESC$; "&l2E"; 'Top margin 2 lines
Call StartMacro("1") 'Left side macro
Print #2, ESC$; "9"; 'Reset left - right margins
Print #2, ESC$; "&a0l80M"; 'set left margin 0, right 80
Call EndMacro("1")
Call StartMacro("2") 'Right side macro
Print #2, ESC$; "9"; 'Reset left - right margins
Print #2, ESC$; "&a95l175M"; 'set left margin 95, right 175
Call EndMacro("2")
End Sub
Static Sub StartMacro (num$)
Print #2, ESC$; "&f"; num$; "Y"; 'Macro will have an id of Num$
Print #2, ESC$; "&f0X"; 'Start the macro now
End Sub
Sub Form_Click ()
'If user clicks anywhere on the form, call the about box
Call printlogo
End Sub
'This is the main code - everything is actually called from here and this
'is where most of the VB changes are located
Sub go_click ()
'VB Code for Drive, Directory, and File selections
If index >= 3 Then End
If lastchange = dirsboxclick Then
dir1.path = dir1.list(dir1.listindex)
Else
If file1.filename <> "" Then
ChDrive drive1.drive
ChDir file1.path
filename$ = file1.filename
Else
msg$ = "Sorry! You must first select a file."
abort% = MsgBox(msg$, 49, "No application chosen.")
If abort% = 2 Then 'cancel button
End
End If
End If
End If
lastchange = fileboxclick
ReDim ptrarray&(513) 'total number of pages (512)
On Error GoTo ErrorDept 'Error trapping
'Ensure that we have a file name (user may have clicked DoIt without
'entering a filename)
GetName:
If Len(filename$) = 0 Then
If tune% Then Beep
msg$ = "Enter a file name to print: "
Title$ = "Filename" ' Set title.
Default$ = ""
NewName$ = InputBox$(msg$, Title$, Default$) ' Get user input.
If Len(NewName$) = 0 Then ' Check if valid.
msg$ = "You did not input a valid Filename." + NL$
msg$ = msg$ + "Click on OK to End Program"
MsgBox msg$, 0, Title$ ' Display message.
GoTo OutHere
End If
End If
'Build index array for pages in FileName$
'Have not converted status display
'Print
'Print "Reading file "; filename$
Call BuildArray(ptrarray&(), page%) 'Built pointer array
'Figure number of pages needed
If page% Mod 4 Then 'Even multiples of 4 only
page% = page% + (4 - page% Mod 4) ' correct for less
End If
'Have not converted status display
'Print
'Print "You will print "; Page% \ 4; "sheets" 'Report total number of pages
'Print
'JustCount% is set to false always due to status section not being
'converted to VB
If JustCount% Then
Print "Press any key to continue, or ESC to cancel printing"
GoSub KeyIn
End If
Open OUTFILE$ For Output As #2 'Open printer or output file
Call PrintSetup 'Set up printer
'Page parsing variables
LeftSide% = page%
RightSide% = 1
FirstPass% = -1
Open filename$ For Binary As #1 'Open the input file
'Have not converted status display
'Print "Printing Side 1 to "; outfile$; 'Track what is going on
'Start of print routine
DoPass:
Bookmark% = (page% \ 4) 'Flag for halfway through
If Bookmark% = 0 Then Bookmark% = 1 'Force 1 if too small
'Read text and send to printer or file
Do 'Print the right side of the page first
If ptrarray&(RightSide% + 1) = 0 Then 'If blank, then skip it
GoTo NextPage
End If
Call DoMacro("2") 'Start on right side
LJLocate 95, 0 'Home the cursor
If PC.DoHeader Then Call Header(RightSide%) 'Header if needed
Buffer$ = Space$(ptrarray&(RightSide% + 1) - ptrarray&(RightSide%))
Get #1, ptrarray&(RightSide%), Buffer$ 'Read in a page
If InStr(Buffer$, FF$) Then 'If the last character is a PF
Print #2, Left$(Buffer$, InStr(Buffer$, FF$) - 1); 'print only text
Else
Print #2, Buffer$; 'Otherwise print full line
End If
NextPage:
If ptrarray&(LeftSide% + 1) = 0 Then 'Don't print blank pages
GoTo NextPage1
End If
Call DoMacro("1") 'Reset margins for left side
LJLocate 0, 0 'Home the cursor
If PC.DoHeader Then Call Header(LeftSide%) 'Header if needed
Buffer$ = Space$(ptrarray&(LeftSide% + 1) - ptrarray&(LeftSide%)) 'Setup buffer for input
If LeftSide% = 0 Then 'If pointing at blank page, skip
GoTo NextPage1
End If
Get #1, ptrarray&(LeftSide%), Buffer$ 'Read in a page
If InStr(Buffer$, FF$) Then 'if the last character is a PF
Print #2, Left$(Buffer$, InStr(Buffer$, FF$) - 1); 'print only text
Else 'print only text
Print #2, Buffer$; 'otherwise print all
End If
NextPage1:
Print #2, FF$; 'Page feed
LeftSide% = LeftSide% - 2 'Calculate next page in series
RightSide% = RightSide% + 2
Bookmark% = Bookmark% - 1 'Track our progress
Loop Until Bookmark% = 0 'Print pages until halfway through
'Pause between sides to allow for paper reinsertion
If FirstPass% Then 'If side one, prompt and get 2nd side
msg$ = "First Pass has been Completed." + NL$
msg$ = msg$ + "Insert paper back in tray and Click OK"
If tune% Then Beep
WaitKey: 'Press any key to continue loop
MsgBox msg$, 0, "Waiting"
FirstPass% = 0 'Flag for second pass
'Have not converted status display
'msg$ = "Printing Side 2 to " + outfile$
'Print msg$ 'Report on progress
GoTo DoPass
End If 'End of first pass
'Printing is done now
msg$ = "Printing completed."
If tune% Then Beep
MsgBox msg$, 64, "Done"
PrtReset:
Print #2, ESC$; "E"; 'Reset laserjet
OutHere:
Close 'Close all files
End 'Thats all for now
'Error handler. Converted to VB errors.
ErrorDept:
Beep
msg$ = "*** Error ***" + NL$
Select Case Err
Case 482
msg$ = msg$ + "Printer error."
Case 68
msg$ = msg$ + "Device is unavailable."
Case 71
msg$ = msg$ + "Insert a disk in the drive and close the door."
Case 57
msg$ = msg$ + "Device Input/Output Error (Check Printer!)."
Case 61
msg$ = msg$ + "Disk is full."
Case 64, 52
msg$ = msg$ + "That filename is illegal."
Case 76
msg$ = msg$ + "That path doesn't exist."
Case 54
msg$ = msg$ + "Can't open your file for that type of access."
Case 55
msg$ = msg$ + "This file is already open."
Case 62
msg$ = msg$ + "This file has a nonstandard end-of-file marker" + NL$
msg$ = msg$ + "or an attempt was made to read beyond the end-" + NL$
msg$ = msg$ + "of-file marker."
Case Else
msg$ = msg$ + "Error number " + Str$(Err)
End Select
GoSub AWayOut
Resume
AWayOut:
abort% = MsgBox(msg$, 17, "ERROR")
KeyIn:
If abort% = 2 Then 'If user presses Cancel, Exit
Close
End
End If
Return
'End of main module
End Sub
Sub Dir1_Change ()
file1.path = dir1.path
file1.SetFocus
End Sub
Sub Dir1_Click ()
lastchange = dirsboxclick
End Sub
Sub File1_Click ()
'use the following line to put filename in frame
'if using a frame:
'inname.caption = "Load " + file1.filename
lastchange = fileboxclick
End Sub
Sub File1_DblClick ()
'Allow the user to double-click on an input file and start printing
Call go_click
End Sub
'CLKx Subs are the Check Boxes for selecting whether to use speaker, etc
Sub clk1_Click ()
'Toggle on/off
If PC.FileTitle = 0 Then
PC.FileTitle = -1
PC.DoHeader = -1
Else
PC.FileTitle = 0
'Still have to do the Header if clk2 or clk3 buttons are checked
If (clk2.value = -1) Or (clk3.value = -1) Then
PC.DoHeader = -1
Else
PC.DoHeader = 0
End If
End If
End Sub
Sub clk2_Click ()
'Toggle on/off
If PC.CurDate = 0 Then
PC.CurDate = -1
PC.DoHeader = -1
Else
PC.CurDate = 0
'Still have to do the Header if clk1 or clk3 buttons are checked
If (clk1.value = -1) Or (clk3.value = -1) Then
PC.DoHeader = -1
Else
PC.DoHeader = 0
End If
End If
End Sub
Sub clk3_Click ()
'Toggle on/off
If PC.PgNumber = 0 Then
PC.PgNumber = -1
PC.DoHeader = -1
Else
PC.PgNumber = 0
'Still have to do the Header if clk1 or clk2 buttons are checked
If (clk1.value = -1) Or (clk2.value = -1) Then
PC.DoHeader = -1
Else
PC.DoHeader = 0
End If
End If
End Sub
Sub clk4_Click ()
'Toggle on/off
tune% = Not tune%
End Sub
Sub clk5_Click ()
'Toggle on/off
PC.LineWrap = Not PC.LineWrap
End Sub
Sub Drive1_Change ()
dir1.path = drive1.drive
End Sub
Sub Cancel_Click ()
'If user clicks on the Cancel button then ...
Close
End
End Sub
'This Sub is ran when the VBBINP.FRM is loaded (ie, Showed)
Sub Form_Load ()
'Put the options in the output port/filename Combobox
comboutname.AddItem "LPT1"
comboutname.AddItem "LPT2"
comboutname.AddItem "COM1"
comboutname.AddItem "COM2"
comboutname.AddItem "file"
comboutname.text = comboutname.list(0) 'default to LPT1
OUTFILE$ = "LPT1"
'set default check-box values
tune% = -1
PC.FileTitle = -1
PC.DoHeader = -1
PC.CurDate = -1
PC.PgNumber = -1
PC.LineWrap = -1
'set some variables
ESC$ = Chr$(27) 'Standard ESC code
FF$ = Chr$(12) 'Page Feed
LF$ = Chr$(10) 'Line Feed
NL$ = Chr$(13) + Chr$(10) 'CR and LF (New Line)
JustCount% = 0 'Not allowing "just counting"
PC.LineLen = 80 'Maximum length of line
End Sub
'User clicks on the Combobox
Sub comboutname_Click ()
'Select where to send the output
Select Case comboutname.text
Case "LPT1"
OUTFILE$ = "LPT1"
Case "LPT2"
OUTFILE$ = "LPT2"
Case "COM1"
OUTFILE$ = "COM1"
Case "COM2"
OUTFILE$ = "COM2"
Case "file"
If file1.filename = "" Then 'If no input filename is selected
comboutname.text = "LPT1" ' default back to LPT1
OUTFILE$ = "LPT1"
msg$ = "You must select an input filename first!"
MsgBox msg$, 32
file1.SetFocus 'set focus to file list box
Exit Sub
End If
'Now make up a default output filename with same
'name and PRN as the extension
OUTFILE$ = UCase$(Left$(file1.filename, InStr(file1.filename, ".")) + "PRN")
msg$ = "WAIT" + NL$ + "Enter filename to print to:"
OUTFILE$ = InputBox$(msg$, "Output File Name", OUTFILE$) 'Get a filename
If OUTFILE$ <> "" Then
comboutname.text = UCase$(OUTFILE$) 'put filename in combo box
go.SetFocus
Else
'Insist on a filename
comboutname.text = "LPT1"
OUTFILE$ = "LPT1"
file1.SetFocus 'set focus to file list box
End If
End Select
End Sub
Sub Picture1_Click ()
Call printlogo 'Show the "about" box
End Sub