Search code examples
vbalistviewpositionuserform

VBA UserForm Listview control - mouse click coordinates and positioning


VBA userforms, and listviews in particular, are tricky when it comes to spatial distances and coordinates. The question I am trying to solve is: the mousedown event gives the coordinates in pixles - how do I transform that into the units required for repositioning another user control and also incorporate the width property of user controls.

To give the very specific problem: I have a listview with multiple columns and a horizontal scroll bar. I want to get the selected row and column of the mouse click and then reposition a frame to the point at which the mouse was clicked.

Googling only came up with partial answers - nothing solving the full problem.


Solution

  • There are three different units of measurement. Pixels, twips and imperial points.

    • Converting between twips and imperial points is easy - 1 imperial point is 20 twips.
    • Converting between pixels and twips is harder - though many solutions are easily googleable. It is dependant on the pixel density of your screen.

    Once you have gotten your functions/subs down to convert between pixels, twips and imperial points, you can then use the correct coordinate units for each different task:

    • MouseDown event gives the coordinates in pixels.
    • HitTest (the listview function to return the selected row - although not the selected column) takes coordinates in twips.
    • Column widths and all other user control widths are in imperial point.
    • GetScrollPos (the Windows API function to return the scrollbar position) gives a value in pixels.
    • Repositioning user controls on the userform takes imperial points.