Hi,
I came across your discussion and found out I am not alone

I've just tackled the problem and would like to share the solution.
Code in a module
'==============================================================================
'Describes the width, height, and location of a rectangle.
Public Type RECT
x1 As Long
Y1 As Long
x2 As Long
Y2 As Long
End Type
'Number of pixels per logical inch along the screen width. In a system with multiple display monitors, this value is the same for all monitors.
Public Const WU_LOGPIXELSX = 88
'Number of pixels per logical inch along the screen height. In a system with multiple display monitors, this value is the same for all monitors.
Public Const WU_LOGPIXELSY = 90
' Retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue.
Public Declare Function GetFocus& Lib "user32" ()
'Retrieves the coordinates of a window's client area. The client coordinates specify the upper-left and lower-right corners of the client area. Because client coordinates are relative to the upper-left corner of a window's client area, the coordinates of the upper-left corner are (0,0).
Public Declare Function GetClientRect& Lib "user32" (ByVal hWnd As Long, lpRect As RECT)
' The GetDeviceCaps function retrieves device-specific information for the specified device.
Public Declare Function GetDeviceCaps& Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long)
' The GetDC function retrieves a handle to a device context (DC) for the client area of a specified window or for the entire screen. You can use the returned handle in subsequent GDI functions to draw in the DC. The device context is an opaque data structure, whose values are used internally by GDI.
Public Declare Function GetDC& Lib "user32" (ByVal hWnd As Long)
' The ReleaseDC function releases a device context (DC), freeing it for use by other applications. The effect of theReleaseDC function depends on the type of DC. It frees only common and window DCs. It has no effect on class or private DCs
Public Declare Function ReleaseDC& Lib "user32" (ByVal hWnd As Long, ByVal hdc As Long)
'==============================================================================
code in a form's module:
'=============================
Private Function controlWidth(ctrl As control) As Long
Dim r As RECT
ctrl.SetFocus
GetClientRect& GetFocus&, r
controlWidth = Round((ctrl.Width * (r.x2 - r.x1)) / ConvertTwipsToPixels(ctrl.Width, 0), 0) + _
ctrl.LeftPadding + ctrl.RightPadding + ctrlGridlineSideWidth(ctrl)
End Function
Private Function ctrlGridlineSideWidth(ctrl As control) As Long
Dim lngWidth As Long
Const lngPointsInTwips As Long = 20 'Twips in a point
If ctrl.GridlineStyleLeft <> 0 Then
lngWidth = lngWidth + ctrl.GridlineWidthLeft * lngPointsInTwips
End If
If ctrl.GridlineStyleRight <> 0 Then
lngWidth = lngWidth + ctrl.GridlineWidthRight * lngPointsInTwips
End If
ctrlGridlineSideWidth = lngWidth
End Function
Function ConvertTwipsToPixels(lngTwips As Long, _
lngDirection As Long) As Long
'Twips to pixels
'Handle to device
Dim lngDC As Long
Dim lngPixelsPerInch As Long
Const nTwipsPerInch = 1440
lngDC = GetDC(0)
If (lngDirection = 0) Then 'Horizontal
lngPixelsPerInch = GetDeviceCaps(lngDC, WU_LOGPIXELSX)
Else 'Vertical
lngPixelsPerInch = GetDeviceCaps(lngDC, WU_LOGPIXELSY)
End If
lngDC = ReleaseDC(0, lngDC)
ConvertTwipsToPixels = (lngTwips / nTwipsPerInch) * lngPixelsPerInch
End Function
'=============================
To get the full width of a control call the controlWidth function.
My controls were arranged in a layout, so I had to take into account this:
ctrl.LeftPadding + ctrl.RightPadding + ctrlGridlineSideWidth(ctrl)
If you don't need this part then drop it.
Hope it helped.
Sergiy Vakshul