Silly VB 6 Problem Involving Control Positioning.
-
In Payback (an app that's been the subject of several WTFs on this site), I have a VB 6 form on which I am creating controls dynamically. Let's just focus on one set of button controls for now.
I'd like all of the dynamically created buttons to line up nicely in a vertical line. That's simple enough. I do:
'approximation of a snippet of code from the middle of a for loop
'buttons all have .Height = 315
Button(i).Top = (Button(i - 1).Top + Button(i - 1).Height) + Margin 'Margin = the gap I'd like to have between the buttons
This works well, unless I choose a Margin that is not evenly divisible by 15. For example, if I set Margin = 5, I get something looking like this: http://www.unclemidriff.com/images/irritatinggap.jpg
Notice how the first two marked gaps are different from the third marked gap. This pattern repeats. If I set Margin = 10, then the gap shows up every other button.
I set the up click events for the buttons to do:
MsgBox Button(Index).Top - (Button(Index - 1).Top + Button(Index - 1).Height)
The answer I get is the value of Margin, even if the button clicked on is one immediately following a gap.
This isn't all that big of a deal, but it's bothering me that it's happening and I don't really know why.
What (likely obvious thing) am I missing?
-
If I remember correctly, VB6's standard measurement unit is twips. I vague remember having to poll the display adapter's twips/pixel property to do any kind of positioning. I haven't done VB6 in years so I may be wrong.
-
VB6 uses a unit of measurement called "twips" - they are resolution-indipentent or someting, I don't know why they use them instead of pixels (at least VB.Net uses pixels). You are looking for a function called Screen.TwipsPerPixelX and Screen.TwipsPerPixelY to get the average values:
Margin = Screen.TwipsPerPixelY * (MarginInPixels)
will give you a nice even layout.
-
If you do not want to deal with twips for measurement, there is a form option that allows you to hard set the form to use pixels instead of twips. Now I can't exactly remember the name of it, but if you browse the properties you should be able to find it...
-
Something like,
Me.ScaleMode = vbPixels
and Me.ScaleLeft (... Top, Width, Height)
There is also .ScaleX and ScaleY for use in height/width calculation (NB. Any twips/pixels conversions are dependant on current dpi).
You can also change the coordinate system of a form with .Scale
-
@Albatross said:
VB6 uses a unit of measurement called "twips" - they are resolution-indipentent or someting, I don't know why they use them instead of pixels (at least VB.Net uses pixels). You are looking for a function called Screen.TwipsPerPixelX and Screen.TwipsPerPixelY to get the average values:
Margin = Screen.TwipsPerPixelY * (MarginInPixels)
will give you a nice even layout.
... twips?
Is this a joke?
-
No joke. It's equivalent to something like 1/16" divided by 1440 - don't quote me on the exact calcs. That's why you get some ridiculously large measurements where 800x600 pixels is almost 40,000x30,000 twips.
Man, twips were pain. I'm glad I gave up the WTF that was VB6 and moved on to .Net. OO and positioning that actually makes sense.
-
@lpope187 said:
No joke. It's equivalent to something like 1/16" divided by 1440 - don't quote me on the exact calcs. That's why you get some ridiculously large measurements where 800x600 pixels is almost 40,000x30,000 twips.
Man, twips were pain. I'm glad I gave up the WTF that was VB6 and moved on to .Net. OO and positioning that actually makes sense.
Oh my god.
I bet I know how that came to be:
[i]Int; MS office building. 18:45[/i]
VB Architect: "HEY JOE, I HAVE AN IDEA."
Joe the Cleaner ([i]unpacks mop and bucket[/i]): "What?"
VB Architect: "THINK OF TWO RANDOM NUMBERS, WOULDYA?"
-
I think in 10 years from now, "Pixel" will have no more meaning in PC software, since the drawing APIs will be vector-based. Maybe this will be the time when twips return.
-
@ammoQ said:
I think in 10 years from now, "Pixel" will have no more meaning in PC software, since the drawing APIs will be vector-based. Maybe this will be the time when twips return.
Agreed. At some point, the pixel will be just as invisible as a printer's ink dot. though resolution would have to be upwards of 200 dpi to make that feasible. A 19" monitor display 1600*1200 has something of 120 dpi. Games look great, even without hardware antialias, but for it to be perfect, it would have to be 150+.
Another upside of pixels too small to see individually is that expensive antialiasing calculations will become obsolete. Aliasing will then be treasured as providing sharpness.
-
@Albatross said:
VB6 uses a unit of measurement called
"twips" - they are resolution-indipentent or someting, I don't know why
they use them instead of pixels (at least VB.Net uses pixels). You are
looking for a function called Screen.TwipsPerPixelX and
Screen.TwipsPerPixelY to get the average values:Margin = Screen.TwipsPerPixelY * (MarginInPixels)
will give you a nice even layout.
Holy new forum software, Batman!
Thanks Albatross, that did the trick. I figured that problem had something to do with that whole twips versus pixels thing.
Not surprisingly, Screen.TwipsPerPixelY = 15, so multiplying my Margin by that gives me a Margin evenly divisble by 15, which I had already noticed made the problem go away. So how's that work, anyway? With Margin = 5, it places the next control 5 twips away from the current one. Since the current control's height is evenly divisible by 15, we get a X pixels with 5 twips left over. Then we place the next control and Margin of 5 twips, and we get a X more pixels with 10 twips left over. Then we place the next control and Margin of 5 twips, we get X more pixels with 15 twips left over, but since 15 twips = 1 pixel, we actually get X + 1 pixels. So on and so forth, thus the periodically recurring gap. Does that make sense?
What I don't get is why changing the form's ScaleMode property didn't change anything? Why can't I change the ScaleMode property from twips to pixels and then have Margin = 5 mean that I want a margin of 5 pixels rather than 5 twips? I tried that and it didn't solve or alter the problem.
-
@ammoQ said:
I think in 10 years from now, "Pixel" will have no more meaning in PC software, since the drawing APIs will be vector-based. Maybe this will be the time when twips return.
Oe they might just use points instead...
-
BTW, even though Screen.TwipsPerPixelY on your computer is 15, make sure that you don't hard code it (margin = 15), as Screen.TwipsPerPixelX and Y seem to be different on every computer.
-
@Albatross said:
BTW, even though Screen.TwipsPerPixelY on your computer is 15, make sure that you don't hard code it (margin = 15), as Screen.TwipsPerPixelX and Y seem to be different on every computer.
I didn't hard code it, but what determines the number of twips per pixel? I changed the resolution, font size and DPI on my computer several times to several different resolutions etc., but each time, I get 15 twips per pixel.
-
@UncleMidriff said:
@Albatross said:
BTW, even though Screen.TwipsPerPixelY on your computer is 15, make sure that you don't hard code it (margin = 15), as Screen.TwipsPerPixelX and Y seem to be different on every computer.
I didn't hard code it, but what determines the number of twips per pixel? I changed the resolution, font size and DPI on my computer several times to several different resolutions etc., but each time, I get 15 twips per pixel.
I found this article that explains that TwipsPerPixel is set by whether your using Large or Regular Font sizes.
If the forum software eats the hyperlink it is this: http://support.asna.com/kb/Generic/kb000197.asp
-
@lpope187 said:
If I remember correctly, VB6's standard measurement unit is twips. I vague remember having to poll the display adapter's twips/pixel property to do any kind of positioning. I haven't done VB6 in years so I may be wrong.
A twip is a twentieth of a point ... TWentIeth of a Point
Had to use it maintaining someone's Access database VBA thingy.