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.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.