Results 1 to 10 of 10
  1. #1
    New Lounger
    Join Date
    Aug 2002
    Posts
    21
    Thanks
    0
    Thanked 0 Times in 0 Posts

    UserForm Control Absolute Position (XP/2002)

    Is there a way (perhaps API) to determine the absolute position of a Control within an XL Userform?

    The Left and Top Control properties are referenced to the container (Form, Frame, etc.)

    Example:
    I would like to be able to get an absolute reference with respect to the UserForm 0,0 of the Top and Left position of a CommandButton that lies within a Frame within a Frame within a Frame, etc.

    Thanks in advance

    Lorne

  2. #2
    Platinum Lounger
    Join Date
    Nov 2001
    Location
    Melbourne, Victoria, Australia
    Posts
    5,016
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: UserForm Control Absolute Position (XP/2002)

    Hi Lorne

    I tried this in XL2000 VBA. This is a bit quirky, but seems to work for a few controls I tested. The "quirky" part comes from the fact that TypeName(MyUserForm) will return the name of the userform ("MyUserForm"), since userforms don't seem to be a "TypeName" anything. I thought this would be a handy indicator of when I'd drilled down to userform level. But when I try to do a string comparison:
    If TypeName(ThisControl) = ThisControl.Name
    I get a type mismatch when ThisControl is a Userform; this despite the string values being identical. <img src=/S/confused.gif border=0 alt=confused width=15 height=20>
    Hence the error trap.

    Alan

  3. #3
    New Lounger
    Join Date
    Aug 2002
    Posts
    21
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: UserForm Control Absolute Position (XP/2002)

    Thanks Alan

    There is a little glitch in your code. You need to sum the Left and Top control properties as you move down through the containers... see the code below. However, I have been down this road before and what is calculated is not the true absolute location. The Left location is not bad but the Top is way off. You can prove this by creating another form of exactly the same dimensions as the first, then adding a command button with the absolute Left and absolute Top that were calculated from the first form. Display each form, do a screen capture into somthing like IrfanView and compare the two forms. (hit Alt-Print Screen while the form is being displayed to place it on the clipboard).
    The problem is the Frame control caption height. When a Frame is placed on the form, its Top, Left properties lie at the Top, Left of the caption which can vary by the font size used. However, each control placed inside the Frame has a 0,0 origin that begins at the top, left of the frame border (below the caption). The absolute Top calculation that you are calculating does not include the Frame caption heights and is too small.
    I assume that there would be an API call that could return the true location of the control... I just have to find it.

    Lorne

    Sub GetAbsoluteCoordinates(ctlName As String)
    Dim ctl As Control
    Dim absLeft As Single
    Dim absTop As Single
    Dim msg As String

    Set ctl = Me.Controls(ctlName) 'ctl

    Do
    If TypeName(ctl) = ctl.Name Then Exit Do
    MsgBox ctl.Name & " " & TypeName(ctl)
    On Error GoTo ExitDo

    absLeft = absLeft + ctl.Left
    absTop = absTop + ctl.Top

    Set ctl = ctl.Parent
    Loop

    ExitDo:
    ' absLeft = ctl.Left + ctl.Left
    ' absTop = ctl.Top + ctl.Top

    msg = "Local Coordinates:" & vbCrLf & _
    "Left: " & ctl.Left & vbCrLf & _
    "Top: " & ctl.Top & vbCrLf

    msg = msg & "Absolute Coordinates: " & vbCrLf & _
    "Left: " & absLeft & vbCrLf & _
    "Top: " & absTop

    MsgBox msg

    End Sub

  4. #4
    Platinum Lounger
    Join Date
    Nov 2001
    Location
    Melbourne, Victoria, Australia
    Posts
    5,016
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: UserForm Control Absolute Position (XP/2002)

    Yep, sorry about the incrementing blunder! I think you're going to have quite a job, getting coordinates the way you want them. The relative positions of child controls are always measured from within the client area, offered by the parent container, for the placement of child windows. For a form for instance, the "origin" is just below the title bar, and just to the right of the inside of the left border.

    All that said though, it may be possible to do what you're after using API Rectangle struct. The attached demo provides some "basics". Try moving the controls within the form at design time, and the form around the screen at run time.

    Alan

  5. #5
    Gold Lounger
    Join Date
    Dec 2000
    Location
    New Hampshire, USA
    Posts
    3,386
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: UserForm Control Absolute Position (XP/2002)

    If I undestand what you are looking for, you are on the right track.
    You just have to adjust each left/top for the point of origin, be it within a frame or the form itself.
    API does not apply here.

  6. #6
    New Lounger
    Join Date
    Aug 2002
    Posts
    21
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: UserForm Control Absolute Position (XP/2002)

    It think it is actually fairly complicated. I have attached a PNG graphic to illustrate the problem as I see it. One can iterate out through the container controls and sum the Left and Top properties. I had already tried that approach but it was not giving the right answers. When I looked more closely, it became apparent that a Frame Left , Top settings and the Frame interior 0,0 setting are displaced by the height of the Frame Caption text and the Frame borders and the Frame caption height is tied to the Frame.Font.Size. One has to add those Caption heights and border widths into the overall Top and Left summations. I believe that stand-alone versions of VB and the VB.NET languages provide Text metrics measuring methods; however, I don't think that VBA supports that feature. There is probably an API solution that would give an absolute reference for the control wrt to the Form origin if I can find it.

    Why do I want to do this? I am trying to use the VBA visual forms editor for something it is not designed to do. I want to use the visual tools to "easily" develop a Form for a totally different program that does not support visual Form creation (convert the visual controls to Form Code for the 2nd program). That program uses absolute coordinates... every control's Left and Top are referenced to the Left, Top Interior form area and container controls do not exist. I have the VBA application working well but I am just using fudge factors to get the correct results.

    Lorne

  7. #7
    Platinum Lounger
    Join Date
    Nov 2001
    Location
    Melbourne, Victoria, Australia
    Posts
    5,016
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: UserForm Control Absolute Position (XP/2002)

    > There is probably an API solution that would give an absolute reference for the control wrt to the Form origin if I can find it.

    Did you look at the code in the second attachment I posted?
    These API methods might use the reference datum you're after.

    Alan

  8. #8
    New Lounger
    Join Date
    Aug 2002
    Posts
    21
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: UserForm Control Absolute Position (XP/2002)

    I may have missed something in what you sent me Alan. The RECT structure is used in many API's but I could not find any API declarations or calls in your code. I am probably overlooking something.

    When I run your example application, I am getting the location for the inner Image control as Left 48 Top 0 (the coordinates relative to the frame).
    What I want to determine is the Image Control Top, Left in reference to the upper left of the Userform interior which is going to be something like:
    Left equals approximately 48 plus 12 equals 60 (I say approximately because I'm not sure if control borders are included in these numbers)
    Top equals 0 plus 0 plus Frame caption height (maybe 6)

    Another way to illustrate this would be to create a second userform exactly like you first but only place the Image control on it. Try to place the Image Control in exactly the same location as on your first form (relative to the interior top left of the form.). When I do this, and check the property settings I read the Image.Left as 60 and the Image.Top as 6. Those are the numbers I what but you can't get them by simply cycling out through the containers and adding the Top properties which would yield zero on the form you sent me.

    On a different topic... I notice something curious on the workbooks you have sent me. The Top UserForm property on your examples are always set to -12.75. When I create a new Userform the Top property is always set to zero. Is this determined by an Option setting?
    Thanks
    Lorne

  9. #9
    New Lounger
    Join Date
    Aug 2002
    Posts
    21
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: UserForm Control Absolute Position (XP/2002)

    Solution:
    I'm close to a solution on the API front but it turns out that it is not required anyway. I should have looked closer at the available properties of container controls. It turns out that containers like UserForms and Frames have both Width / Height properties and InsideWidth / InsideHeight properties. These can be used to find the caption and border dimensions of the container. So one can iterate up through the container stack adding Top and Left properties... you just have to add in the extra distances. See Alan's modified code below.
    Lorne

    Sub GetAbsoluteCoordinates(CtlName As String)
    Dim ctl As Control
    Dim absLeft As Single
    Dim absTop As Single
    Dim msg As String

    Set ctl = Me.Controls(CtlName) 'ctl

    Do
    If TypeName(ctl) = ctl.Name Then Exit Do
    On Error GoTo ExitDo

    If TypeName(ctl) = "Frame" Then
    absLeft = absLeft + ctl.Left + (ctl.Width - ctl.InsideWidth)
    absTop = absTop + ctl.Top + (ctl.Height - ctl.InsideHeight)
    Else
    absLeft = absLeft + ctl.Left
    absTop = absTop + ctl.Top
    End If

    Set ctl = ctl.Parent
    Loop

    ExitDo:
    msg = CtlName & vbCrLf & _
    "Local Coordinates:" & vbCrLf & _
    "Left: " & ctl.Left & vbCrLf & _
    "Top: " & ctl.Top & vbCrLf

    msg = msg & "Absolute Coordinates: " & vbCrLf & _
    "Left: " & absLeft & vbCrLf & _
    "Top: " & absTop

    MsgBox msg

    End Sub

  10. #10
    Platinum Lounger
    Join Date
    Nov 2001
    Location
    Melbourne, Victoria, Australia
    Posts
    5,016
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: UserForm Control Absolute Position (XP/2002)

    That's a very handy "find". I was hoping that the combination of the API RECT values and the VBA Height/ Width values might be able to be used to generate the same sort of result i.e. giving both inside and outside values. Your solution seems a better way to go regardless. Does it now work as you'd hoped?

    Alan

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •