Re: Mike: Better informed, Fundamental questions



Hi Mike:

I have been studing hard, still confused!

You can read the following for insight into my confusion, but, what would
probaly help the most is a bare bones ( Form1, Picture1 & Text1) piece of
code that drew the x,y axis at the origin set by the range of X and Y as
vbUser.

In text1: +X,-X,+Y,-Y(enter)
In picturebox1: draw the X,Y axis

Sub SetPicture1XYrange(Xp As Single, Xn As Single, Yp as Single, Yn As
Single) '
p is the positive range, n is the
negative range

Sub DrawXYaxis ( Xp As Single, Xn As Single, Yp As Single, Yn As Single)

I can play with it to better understand what VB is doing.
If there are multiple ways to implement the same effect as I suggest below
and it is
not to much trouble you could code those as an options. I will cut and paste
them into the beginning of the sub and limit execution by Exit Sub.

I really appreciate your help!!!!!!!!

more confusion: ************************

I understand 90% of your code.

I believe my problem is how VB deals with scaling, the term "units" and
especially
VB actual unit of measure(Twips ???) for drawing on forms, printers, etc.
Maybe it varies by device?

There seems to be some redundency with Methods and Properties.

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"

Also, the documentation for ScaleX/Y says ToScale or FromScale can use VBUser
but it errors for me. I could not get Custom Unit to work!

See Below my signature:
****************************************
Creating a Custom Scale
****************************************

I believe the ScaleMode property sets the default conversion for VB drawing
and if
you need to change units and STAY PROPORTIONAL ScaleX/Y provide the
conversion.
Also Scale(x1,y1)-(x2-y2) seems to be another way of forcing an
Objects.Scale_____ Properties

I think the key for me to understand all of this is to understand how VB
implements
drawing regardless of the scale.

The 10% of you code I haven't interpreted yet is how you get (0,0) in the
lower left corner. Could you point that out, please.

How VB actually effects drawing is like a big black box to me,
therefore, I can't understand how the Methods and properties influence its
operation.

I appreciate your patients, I'm a little slow sometimes!

--
Thank you,

Randy

**********************************************
Changing an Object's Coordinate System


You set the coordinate system for a particular object (form or control)
using the object’s scale properties and the Scale method. You can use the
coordinate system in one of three different ways:

Use the default scale.


Select one of several standard scales.


Create a custom scale.
Changing the scale of the coordinate system can make it easier to size and
position graphics on a form. For example, an application that creates bar
charts in a picture box can change the coordinate system to divide the
control into four columns, each representing a bar in the chart. The
following sections explain how to set default, standard, and custom scales to
change the coordinate system.

Using the Default Scale
Every form and picture box has several scale properties (ScaleLeft,
ScaleTop, ScaleWidth, ScaleHeight, and ScaleMode) and one method (Scale) you
can use to define the coordinate system. The default scale for objects in
Visual Basic places the coordinate (0,0) at the upper-left corner of the
object. The default scale uses twips.

If you want to return to the default scale, use the Scale method with no
arguments.

Selecting a Standard Scale
Instead of defining units directly, you can define them in terms of a
standard scale by setting the ScaleMode property to one of the settings shown
in the following table.

ScaleMode setting Description
0 User-defined. If you set ScaleWidth, ScaleHeight, ScaleTop, or ScaleLeft
directly, the ScaleMode property is automatically set to 0.
1 Twips. This is the default scale. There are 1,440 twips to one inch.
2 Points. There are 72 points to one inch.
3 Pixels. A pixel is the smallest unit of resolution on the monitor or
printer. The number of pixels per inch depends on the resolution of the
device.
4 Characters. When printed, a character is 1/6 of an inch high and 1/12 of
an inch wide.
5 Inches.
6 Millimeters.
7 Centimeters.


All of the modes in the table, except for 0 and 3, refer to printed lengths.
For example, an item that is two units long when ScaleMode is set to 7 is two
centimeters long when printed.

' Set scale to inches for this form.
ScaleMode = 5
' Set scale to pixels for picPicture1.
picPicture1.ScaleMode = 3

Setting a value for ScaleMode causes Visual Basic to redefine ScaleWidth and
ScaleHeight so that they are consistent with the new scale. ScaleTop and
ScaleLeft are then set to 0. Directly setting ScaleWidth, ScaleHeight,
ScaleTop, or ScaleLeft automatically sets ScaleMode to 0.

****************************************
Creating a Custom Scale
****************************************

You can use an object’s ScaleLeft, ScaleTop, ScaleWidth, and ScaleHeight
properties to create a custom scale. Unlike the Scale method, these
properties can be used either to set the scale or to get information about
the current scale of the coordinate system.

Using ScaleLeft and ScaleTop
The ScaleLeft and ScaleTop properties assign numeric values to the
upper-left corner of an object. For example, these statements set the value
of the upper-left corner for the current form and upper-left corner for a
picture box named picArena.

ScaleLeft = 100
ScaleTop = 100
picArena.ScaleLeft = 100
picArena.ScaleTop = 100

These scale values are shown in Figure 12.4.

Figure 12.4 The ScaleLeft and ScaleTop properties for a form and a control



These statements define the upper-left corner as (100, 100). Although the
statements don’t directly change the size or position of these objects, they
alter the effect of subsequent statements. For example, a subsequent
statement that sets a control’s Top property to 100 places the object at the
very top of its container.

Using ScaleWidth and ScaleHeight
The ScaleWidth and ScaleHeight properties define units in terms of the
current width and height of the drawing area. For example:

ScaleWidth = 1000
ScaleHeight = 500

These statements define a horizontal unit as 1/1,000 of the current internal
width of the form and a vertical unit as 1/500 of the current internal height
of the form. If the form is later resized, the units remain the same.

Note ScaleWidth and ScaleHeight define units in terms of the internal
dimensions of the object; these dimensions do not include the border
thickness or the height of the menu or caption. Thus, ScaleWidth and
ScaleHeight always refer to the amount of room available inside the object.
The distinction between internal and external dimensions (specified by Width
and Height) is particularly important with forms, which can have a thick
border. The units can also differ: Width and Height are always expressed in
terms of the container’s coordinate system; ScaleWidth and ScaleHeight
determine the coordinate system of the object itself.

Setting Properties to Change the Coordinate System
All four of these scale properties can include fractions and they can also
be negative numbers. Negative settings for the ScaleWidth and ScaleHeight
properties change the orientation of the coordinate system.

The scale shown in Figure 12.5 has ScaleLeft, ScaleTop, ScaleWidth, and
Scale Height all set to 100.

Figure 12.5 Scale running from (100, 100) to (200, 200)



Using the Scale Method to Change the Coordinate System
A more efficient way to change the coordinate system, other than setting
individual properties, is to use the Scale method. You specify a custom scale
using this syntax:

[object.]Scale (x1, y1) – (x2, y2)

The values of x1 and y1 determine the settings of the ScaleLeft and ScaleTop
properties. The differences between the two x-coordinates and the two
y-coordinates determine the settings of ScaleWidth and ScaleHeight,
respectively. For example, suppose you set the coordinate system for a form
by setting end points (100, 100) and (200, 200):

Scale (100, 100)-(200, 200)

This statement defines the form as 100 units wide and 100 units high. With
this scale in place, the following statement moves a shape control one-fifth
of the way across the form:

shpMover.Left = shpMover.Left + 20

Specifying a value of x1 > x2 or y1 > y2 has the same effect as setting
ScaleWidth or ScaleHeight to a negative value.


"Mike Williams" wrote:

"Randy Gardner" <RandyGardner@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:6AE4F10D-3C63-4417-BE55-4630DFB21EFA@xxxxxxxxxxxxxxxx

Mike: Wow! Great help, I really apreciate it!!!!!

I could just use your code, BUT, I wouldn't have learn anything,
so would you please explain what is happening in the functions:
pConvertX/Y . . . . .

The ScaleMode of a picture box can be set to a number of different things,
for example inches, centimeters, twips and quite a few others. Taking the
simple example of a borderless picture box, if you set its ScaleMode to
vbInches then x coordinate 2 (for example) would be 2 logical inches from
the left side of the picture box. The number of available inches across the
width of the box would therefore depend on its logical size, so a picture
box that is 6 logical inches wide would have coordinate 0 at the left side,
coordinate 6 at its right side and coordinate 3 in the middle (measured
horizontally). If you consider an inch to be a "unit" then the number of
units across the width of the picture box depends on its logical width.
However, in our case we are settings the ScaleWidth of the picture box to a
specified number of units (35.75 units in the specific example because we
set it to 30 + 30/8 + 30/15 to allow for some white space at both sides of
the graph itself). Setting the ScaleWidth to a specific value automatically
causes the ScaleMode to be set to vbUser, and it means that the picture box
will be 35.75 "units" wide, regardless of its actual physical width. This
means we can make the picture box any physical size we wish and it will
always be 35.75 "units" wide. The actual width of a unit will therefore
depend on the actual width of the picture box, but whatever the size of the
picture box there will always be 35.75 units across its width.

When we draw a dot, for example, we use the picture box coordinates to
specify the dot's location (because this allows us to use units which suit
our graph scale) - but - and this is the important thing - we do not
actually draw the dot into the picture box. If you look at the code you will
see that the dot is actually drawn directly to the chosen output device
(printer or Form or whatever). Nothing is ever actually drawn into the
picture box. However, the Form (or the printer) is not set to vbUser
scalemode. It is actually set (in the specific example) to vbInches. This is
so that you can use familiar units to draw other things into the Form (or
the printer) as well as your graph. So, in order to draw the dot at the
correct location on the Form (or the printer) we need to convert between the
"easy to use for our graph" coordinates of the vbUser scalemode picture box
(Picture1) to the "easy to use for everything else" coordinates of our
vbInches scalemode Form (or printer). That is what the pConvertX and
pConvertY functions do.

If you look for example at the pConvertX function you will see that there
are basically three separate parts to the conversion. (Note that if you're
printing your graph to the printer then currentObject will be the printer
object). The first part . . .

Picture1.ScaleX(x, Picture1.ScaleMode, currentObject.ScaleMode)

.. . . converts the coordinate from "Picture1 picture box units" (vbUser) to
"currentObject units" (vbInches in the example). If that is all we did then
the coordinate would still be wrong, because the ScaleLeft setting of the
picture box effectively "shifts" coordinate zero to somewhere else other
than the left edge of the Picture1 picture box (because in our example we
want coordinate zero in Picture1 to specify the location of the bottom left
corner of the graph itself), whereas coordinate zero of currentObject (whose
ScaleMode is vbInches and whose ScaleLeft property has not been altered from
the default of zero) is the left edge of the object. So, the second part of
the pConvertX function . . .

Picture1.ScaleX(Picture1.ScaleLeft, Picture1.ScaleMode,
currentObject.ScaleMode)

.. . . makes the required adjustment. So far so good. Now we need a further
adjustment, otherwise the graph will be printed at the top left corner of
currentObject, whereas we in fact want to print it so that our graph can be
anywhere on the page . . .

+ pOffsetX

If the destination (currentObject) is a Form or another Picture Box then
pOffsetX is the same as the value you passed to the DrawGraph1 Subroutine in
its xPos parameter. However, if currentObject is a printer then xPos is
slightly different that the xPos parameter. This is because as far as VB is
concerned the printer page on most printers is a rectangle that is slightly
smaller than the physical size of the *** of paper in the printer, and
this rectangle is not positioned at the top left corner of the physical
*** of paper, but is usually set a little down from the top and a little
across from the left. The required offset to account for this is calculated
in the main body of the DrawGraph1 Subroutine as follows:

pOffsetX = xPos: pOffsetY = yPos
If TypeOf Dest Is Printer Then
' find left unprintable margin in printer pixels
borderLeft = GetDeviceCaps(Dest.hdc, PHYSICALOFFSETX)
' convert it to printer scale units and adjust pOffsetX accordingly
pOffsetX = pOffsetX - Dest.ScaleX(borderLeft, _
vbPixels, Dest.ScaleMode)

Hopefully, that explains the reasoning behind the pConvertX and pConvertY
functions. I know that you've asked other questions as well in your post,
but perhaps it might be wise for me to leave the answers to those questions
until you have read and digested the above. Post back when you've got the
pConvertX and pConvertY functions under your belt (or ask for clarification
is there is anything in the above that you are having problems with) and
then we can deal with your other questions.

Mike




.


Loading