Re: Mike: Better informed, Fundamental questions
- From: "Mike Williams" <Mike@xxxxxxxxxxxxxxxxx>
- Date: Tue, 11 Jul 2006 19:22:27 +0100
"Randy Gardner" <RandyGardner@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message news:23232E02-A654-4AC6-8299-3AD7831AD90D@xxxxxxxxxxxxxxxx
Hi Mike: I have been studing hard, still confused! <big snip>
I understand 90% of your code. I believe my problem is how
VB deals with scaling, the term "units"
The following is and example of a portion of my confusion:
dw = Picture1.ScaleX(1, vbInches, vbTwips)
dw = 1440 " Right"
dw = Picture1.ScaleX(1, vbInches, vbMillimeters)
dw = 25 " almost Right"
dw = Picture1.ScaleX(1, vbMillimeters, vbInches)
dw = 0 " Wrong" = .03937"
The reason you're getting incorrect answers in the above code is simply because you are getting the result into the variable dw, which in my code example was declared as a Long. Longs of course can hold only integers (whole numbers). If you change the declaration to [ Dim dw as Single ] then all the above lines of code will produce the correct result. The reason I used a Long in my own code is simply that I was calculating a value to use to set the DrawWidth. If you check the VB help files you'll see that DrawWidth is expressed in pixels, regardless of the ScaleMode you are using. Pixels are the smallest unit on the device (screen or printer or whatever). It isn't possible to have fractions of a pixel (apart from in some esoteric and rarely used cases which I won't go into here). Therefore a Long is a suitable variable type when you are converting other units to pixels, but for general purpose conversions between different units of measurement you need to use a Single.
. . . and especially VB actual unit of measure(Twips ???)
for drawing on forms, printers, etc.
As you're probably already aware, Visual Basic uses eight different ScaleModes. Of these, five are "real world units" (that is to say, they are units of measurement commonly used in the real world) and these five units of measurement have a fixed size relationship, each to the other. These units are:
Inches
Points (there are 72 points in one inch)
Twips (there are 20 twips in one point)
Centimeters (there are 2.54 centimeters in one inch)
Millimeters (there are 10 millimeters in one centimeter)
On a computer, and in the real world, those five units of measurement always bear the relationship to each other as shown above. Twips are nothing special. There are always 1440 twips in an inch, just as there are always 2.54 centimeters in an inch. (By the way, before someone pulls me up on this, there have throughout the years been all sorts of different definitions of a twip, and different definitions of a point and of an inch for that matter, but the twips used by Windows and by VB and by almost everyone else in the world these days have 72 of them in a point and 1440 of them in an inch).
At this point I think I should make it clear that as far as Windows is concerned (the screen display) an inch is a "logical inch" and it is not necessarily the same size as a "real world inch". In other words, if you set a Form's ScaleMode to vbInches and draw a rectangle that is one inch wide it will not necessarily be the same size as an inch on a ruler that you might hold up against the screen. On some computers it will be smaller than a real world inch and on others it will be larger than a real world inch and on a few machines it will be exactly the same size. This doesn't matter though for most purposes. The important thing is that all five "computer measuring units" bear a fixed relationship to each other, and that relationship is exactly the same as the relationship between those five measuring units in the real world. Printers are different. On a printer a "logical inch" is exactly the same size as a "real world inch".
Now we come to pixels. A computer display, as I'm sure you are aware, is essentially a large matrix of pixels. When the system draws something on the display it has to "light up" specific pixels in specific colours. In order to know what to do, the computer needs to be told how many pixels it needs to light up to draw a line of pixels that is one logical inch wide. The Windows operating systems tells the computer how many pixels there are in a logical inch. It can be different on different machines, and is actually user definable (it used to be almost totally user definable in Win98, but WinXP gives the user less choice in the matter). On most systems there are 96 pixels in a logical inch, and on some systems there are 120 pixels in a logical inch. Other systems can have different settings. Windows (and VB) generally look after all this stuff for you. For example, if you set a Form's ScaleMode to vbInches and draw a line one unit wide (one inch) then VB will check the oiperating system to see how many pixels there are in a logical inch and it will draw the required number of pixels for you (typically 96 on most machines). However, if you're using something that requires you to specify its size in pixels (such as setting the DrawWidth property of a Picture Box) and if you want the DrawWidth to be a specific thickness in inches then you need to perform the conversion yourself. The ScaleX and the ScaleY methods will convert between different units for you (one is used for measurements in the horizontal direction and the other for measurements in the vertical direction, but they usually both return the same result except on certain quite unusual systems). The ScaleX and ScaleY methods need to be told which device to check (because a screen will have a different number of pixels per logical inch than a printer) so you always need to specify the device you are interested in. For example, if you want to know how many screen pixels there are in a logical inch on your own machine you could use:
Dim p As Single
p = Picture1.ScaleX(1, vbInches, vbPixels)
MsgBox p
Printers are similar in that a printer al;so needs to know how many "printer pixels" there are in a logical inch, and to check this you could use:
Dim p As Single
p = Printer.ScaleX(1, vbInches, vbPixels)
MsgBox p
One little problem with the above code for the printer is that on many systems it will produce a runtime error when run on its own, because it attempts to perform a calculation in respect of a printer that might not yet have been initialised, so it is wise to "give the printer a little kick" to wake it up first. This is usually performed by a Printer.Print statement (which you should always start all print jobs with), but you can also do it in various other ways that will not cause a print job to be started:
Printer.Orientation = Printer.Orientation
Dim p As Single
p = Printer.ScaleX(1, vbInches, vbPixels)
MsgBox p
I think it would be wise of you to make sure you fully understand all of the above before delving any deeper into this stuff, so I think I'll leave it at that for now. Post again if you have any questions.
Mike
.
- Follow-Ups:
- Re: Mike: Restating your explanation
- From: Randy Gardner
- Re: Mike: Restating your explanation
- References:
- Re: Custom ScaleMode setting problem
- From: Mike Williams
- Re: Mike: it's Working, more explanation Please.
- From: Randy Gardner
- Re: Mike: it's Working, more explanation Please.
- From: Mike Williams
- Re: Mike: Better informed, Fundamental questions
- From: Randy Gardner
- Re: Custom ScaleMode setting problem
- Prev by Date: Re: vb6 bcoming irrelevant?
- Next by Date: Re: encrypt strings so they contain legal characters and can be used as filenames
- Previous by thread: Re: Mike: Better informed, Fundamental questions
- Next by thread: Re: Mike: Restating your explanation
- Index(es):
Relevant Pages
|
Loading