Prev: VB3 anyone...?
Next: rsidll32
From: mjimeno on 7 Jun 2005 15:48 Mike, or gaga(a)momo: Barcodes are this simple: Every code you need to print (0 to 255 ascii) is represented by a 6 digits code. For example, if you need to print the "A", you need to print "211 12", where a 1 is a thin line, 2 is a fat line, and the space is a space. So, you usually print the fat line twice the width of the thin line, but you could also use a ratio like 5:2, 6:3, 2:1, and so. The space is exacly the width of a thin line, but white, not black. That's the way I can explain you barcodes, I hope you got it. Now, I use Printer.ScaleMode in vbPixels, but didn't work neither. As I understand what you told me, I must print where the printer can print, not where I want to. But, should I better use some points mode or scale, as I guess it's the mode it can print perfectly? and how to know where it's able to print? Thanks, M
From: Gaga on 7 Jun 2005 20:26 "mjimeno" <miguelangeljimeno(a)hotmail.com> wrote in message news:e35b6407bb5cc4e8d068e017f35f4cdb(a)localhost.talkaboutprogramming.com... > Mike, or gaga(a)momo: Barcodes are this simple: Every code you need > to print (0 to 255 ascii) is represented by a 6 digits code. For example, > if you need to print the "A", you need to print "211 12", where a 1 is a > thin line, 2 is a fat line, and the space is a space. So, you usually > the fat line twice the width of the thin line . . . The space is exacly > the > width of a thin line, but white, not black. Thanks for the info. If that's all there is to it then it should be fairly easy to write some code to draw them without the need to use True Type barcode fonts. However, is it really that simple? Or is there a bit more to it? For example, how does the barcode reader know that is has got to the end of a character. As an example, suppose a particular character was represented by "121 21" and the next character drawn was reppresented by "11 212". The final "1" of the first character and the initial "1" of the following character (both thin lines according to your explanation) would together form one thick line, and so the reader might wrongly interpret the initial "121 21" as "121 22". Presumably, therefore, there must be some kind of seperator between the characters? Or is there some other way that the reader can tell where one character ends and the other starts? > Now, I use Printer.ScaleMode in vbPixels, but didn't work > neither. Changing the ScaleMode doesn't actually do anything except allow you (the programmer) to work in units with which you are comfortable. However, in the specific case of a ScaleMode of vbPixels it guarantees you a "one to one" relationship between your chosen units (pixels) and the units that the printer natively uses (also pixels). For example, if you use twips or millimeters or any other scalemode and you draw a dot at an x coordinate of 100 it will be unlikely that coordinate 100 exactly corresponds to a "whole pixel position" on the page, and so the printer will draw the dot a little to the left (or to the right) of the position you asked for. However, if you use a Scalemode of pixels and you draw a dot at position 100 then you are guaranteed that such a position actually exists and the dot will be draw at exactly the position you have asked for. Basically, you set the printer scalemode to pixels and you use integers (whole numbers) to specify all of your x and y coordinates. To do that, of course, you must draw all of your lines that make up the barcode in such a way. If you use True Type barcode fonts (as I assume you are still doing) then using a scalemode of pixels will not help you at all, because although the "start position of the character" will be at a "whole pixel position" the position of the individual lines in the True Type character will not be. If you answer my question about the separation of individual characters and if you also give me a list of all of the character codes (the "112 21" things) I'll come up with some code to show you what I mean. Mike
From: Gaga on 7 Jun 2005 22:08 "Gaga" <Gaga(a)momo.com> wrote in message news:42a63b2b$0$29336$afc38c87(a)news.optusnet.com.au... > "mjimeno" <miguelangeljimeno(a)hotmail.com> wrote in message .. . . also, what (exactly) is inbetween the individual lines. For example, how would you draw the sequence "211 12" from your earlier example (which from your explanation I take to be thick, thin, thin, space, thin, thick. I presume that there must be some space between the individual lines, otherwise "211" would be drawn exactly the same as "22" ? Mike
From: Gaga on 9 Jun 2005 06:25 "mjimeno" <miguelangeljimeno(a)hotmail.com> wrote in message news:0f1787becb707a6c5b99084d473f2128(a)localhost.talkaboutprogramming.com... > Now, I use Printer.ScaleMode in vbPixels, but didn't work neither. > As I understand what you told me, I must print where the printer > can print, not where I want to. But, should I better use some points > mode or scale, as I guess it's the mode it can print perfectly? and > how to know where it's able to print? Okay. As I said earlier, as far as printing True Type barcode fonts is concerned the ScaleMode you use will not help at all (other than to allow you to use units of measurement that you are comfortable with). However, a scalemode of vbPixels will help you a lot when you draw your barcodes using the VB Line method. This is because you can arrange it so that every line in the barcode is a whole number of pixels (an integer) and those pixels will relate directly to the dots of ink that the printer dumps to the page. Rather than attempt to explain this further I think it would be better for me to give you an example, with some code. I've had a little "dig" into barcode information and it appears that there are dozens (possibly even hundreds!) of different barcode formats. I've decided to base my example on the UPC (Universal product Code) barcodes, since they seem to be the ones that appear on all the tins of beans and bottles of rum and the cans of Cokeý that I buy from time to time! From what I can gather, The UPC code consists of twelve digits (all in the range 0 to 9). Each digit contains four lines of various widths. There are four different widths of line, with the width relationship 1, 2, 3, 4 (with the thinnest line being 1). The encoding is arranged in such a way that every digit contains four lines whose total width is seven times the width of the thinnest line (see the Form Load code). This comes to a width of 7 * 12 = 84 times the width of a "thin" line. In addition to that there are three thin lines at the start, five in the middle and three at the end. This means that the overall width of every barcode is exactly 95 times the width of the thinnest line used. Now if we arrange it so that the thinnest line is an integer (a whole number of printer pixels) then the other three "thicker" lines will also be whole numbers of printer pixels wide, and the printer will be able to draw these widths exactly. Having said that, there will be a problem on some high resolution printers if you print a barcode at a size such that the thinnest line is just one pixel wide. For example on a 600 dpi printer a single pixel will be just 1/600 inches wide. IUf you are using standard copier paper then this is small enough for the "bleed into the paper" of the ink dot to be a problem, making the black line look a little wider than we really want. You can overcome the problem by using high quality paper (photo paper, for example), but you don't really need to do that because on such a high resolution printer the overall size of a barcode printed at a "single pixel thin line" size will be very much smaller than any barcode that you could reasonably want to produce. Have a look at the following code. Paste it into a VB Form containing one Command Button. Click the button and it should print three barcodes on the page. The first one is printed such that the "thinnest line" is exactly 7 pixels wide (with the others thicker lines being proportionally thicker). Such a barcode will have a printed size that depends on the actual resolution (dots per inch) of the printer you are using, so using a "fixed pixel size" isn't really useful for general purpose (although I've included it so that you can more easily see what i am doing). The second printed barcode is printed at a size such that the thinnest line is exactly one printer pixel wide. This produces the smallest barcode that your particular printer can reliably produce using this technique. The third barcode printed is much more useful. In the example it is printed at such a size that the complete barcode will be 1.5 inches wide (or the nearest to that size that can be produced on the currently attached printer using a "whole number" of pixels for the thinnest line. It shopuld be approximately 1.5 inches wide on virtually all printers. Let me know if this stuff is useful to you (code appears below). Mike Option Explicit Private chardata(0 To 9) As String Private Sub Form_Load() ' note that every digit in the UPC (Universal Product Code)barcode has an ' overall thickness of "seven thin lines" (a total of 84 "thin lines" for ' the 12 digits. In addition there is a total of 11 thin lines for the ' start, centre and stop codes. Therefore each bar code has a total ' thickness of 95 "thin lines". chardata(0) = "3211" chardata(1) = "2221" chardata(2) = "2122" chardata(3) = "1411" chardata(4) = "1132" chardata(5) = "1231" chardata(6) = "1114" chardata(7) = "1312" chardata(8) = "1213" chardata(9) = "3112" End Sub Private Sub PrintBarCode(code As String, x As Single, y As Single, barwidth As Long) Dim oldmode As Long, nchar As Long, nline As Long, clr As Long Dim xp As Long, yp As Long, high As Long Dim wide As Long, n As Long, digit As Long 'pixwide = printer.scalex(barwidth oldmode = Printer.ScaleMode Printer.ScaleMode = vbPixels ' add error checking later (for the moment assume that all parameters are correct) xp = Printer.ScaleX(x, oldmode, vbPixels) ' convert x and y to the nearest yp = Printer.ScaleY(y, oldmode, vbPixels) ' whole number of printer pixels high = barwidth * 60 ' typical ratio of height to width of a single line ' draw the "start code" of "111" wide = barwidth * 1 Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbBlack, BF: xp = xp + wide Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbWhite, BF: xp = xp + wide Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbBlack, BF: xp = xp + wide ' now print digits 1 to 6 clr = vbWhite For nchar = 1 To 6 digit = Val(Mid$(code, nchar, 1)) For n = 1 To 4 wide = barwidth * Val(Mid$(chardata(digit), n, 1)) ' pixel width of current line Printer.Line (xp, yp)-(xp + wide - 1, yp + high), clr, BF: xp = xp + wide If clr = vbWhite Then clr = vbBlack Else clr = vbWhite Next n Next nchar ' now print the "centre code" of "11111" wide = barwidth * 1 Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbWhite, BF: xp = xp + wide Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbBlack, BF: xp = xp + wide Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbWhite, BF: xp = xp + wide Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbBlack, BF: xp = xp + wide Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbWhite, BF: xp = xp + wide ' now print digits 7 to 12 clr = vbBlack For nchar = 7 To 12 digit = Val(Mid$(code, nchar, 1)) For n = 1 To 4 wide = barwidth * Val(Mid$(chardata(digit), n, 1)) ' pixel width of current line Printer.Line (xp, yp)-(xp + wide - 1, yp + high), clr, BF: xp = xp + wide If clr = vbWhite Then clr = vbBlack Else clr = vbWhite Next n Next nchar ' now print the "stop code" of "111" wide = barwidth * 1 Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbBlack, BF: xp = xp + wide Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbWhite, BF: xp = xp + wide Printer.Line (xp, yp)-(xp + wide - 1, yp + high), vbBlack, BF: xp = xp + wide Printer.ScaleMode = oldmode End Sub Private Sub Command1_Click() ' Print some UPC (Universal Product Code) barcodes Printer.ScaleMode = vbInches Dim incheswide As Single, pixwide As Long ' ' print barcode at position (1, 1) inches using 7 pixels as the width of a thin line ' (the actual printed size will depend on the resolution of the printer). pixwide = 7 PrintBarCode "639382000393", 1, 1, pixwide ' ' print barcode at position (1, 6.5) inches using 1 pixel as the width of a thin line ' which is the smallest barcode that can be reliably printed on the printer (see ' notes in newsgroup posting regarding printing at such sizes) pixwide = 1.5 PrintBarCode "639382000393", 1, 6.5, pixwide ' ' print barcode at position (1, 8.5) at a total barcode size of 1.5 inches (actually, ' at the nearest "whole pixel per thin line" value to the desired 1.5 inch size) incheswide = 1.5 ' desired width of the entire barcode (1 inch in this example) incheswide = incheswide / 95 ' because every barcode is 95 times as wide as a thin line pixwide = Printer.ScaleX(incheswide, vbInches, vbPixels) If pixwide < 1 Then pixwide = 1 PrintBarCode "639382000393", 1, 8.5, pixwide ' this should be about 1.5 inches wide ' Printer.EndDoc End Sub
From: Gaga on 9 Jun 2005 08:06
"Gaga" <Gaga(a)momo.com> wrote in message news:42a81912$0$10696$afc38c87(a)news.optusnet.com.au... .. . . by the way, sorry about the line wrap problems with the sample code I posted. I didn't realise it would be so severe on this computer (which isn't mine and which I'm not used to). Post again if you want me to post the same code without the line wrap problem. Mike |