1. Herfried K. Wagner’s VB.Any
  2. .NET
  3. Frequently Asked Questions

Compacting a path to a certain number of pixels

Compacting a path to a certain number of pixels

Compacting a path to a certain number of pixels

The function 'CompactPath' can be used to compact a path for being
displayed on a 'Graphics' object with a specific font:

Private Declare Auto Function PathCompactPath Lib "shlwapi.dll" ( _
    ByVal hDC As IntPtr, _
    ByVal lpszPath As String, _
    ByVal dx As Int32 _
) As Boolean

Public Function CompactPath( _
    ByVal Path As String, _
    ByVal Destination As Graphics, _
    ByVal MaxWidth As Integer _
) As String
    Dim hDC As IntPtr = Destination.GetHdc()
    Dim Success As Boolean = PathCompactPath(hDC, Path, MaxWidth)
    If Success Then
        Dim p As Integer = Strings.InStr(Path, ControlChars.NullChar) - 1
        If p > 0 Then
            Return Strings.Left(Path, p)
            Return Path
        End If
        Throw New Exception("String does not fit into space.")
    End If
End Function


Dim g As Graphics = Me.CreateGraphics()
    MsgBox( _
        CompactPath( _
            "C:\Program Files\Some Company\Some Product\Data\File.txt", _
            g, _
            180 _
        ) _
Catch ex As Exception
End Try

Catching the exception is a very costly operation, returning a Boolean
variable that indicates the success of the operation would be the better
approach when calling the method several times.

If the compacted path string is not needed, there is a managed alternative
to the code shown above that can be used to draw the compacted path to a
'Graphics' object.  The listing below contains a skeleton of an
implementation for a label control displaying a compacted path.  In order to
use this control in a real-world application, objects need to be disposed
and some other properties need to be taken into account when drawing the
text.  Basing the control on 'System.Windows.Forms.Label' would be possible

Imports System.Drawing
Imports System.Windows.Forms

''' <summary>
'''   Provides a simple label control for displaying a compacted path.
''' </summary>
Public Class TrimmedLabel
    Inherits Control

    Private m_ForeColorBrush As SolidBrush = New SolidBrush(Me.ForeColor)
    Private m_StringFormat As StringFormat = _
        New StringFormat(StringFormatFlags.NoWrap)

    ''' <summary>
    '''   Creates a new instance of <c>PathLabel</c>.
    ''' </summary>
    Public Sub New()
        Me.SetStyle( _
            ControlStyles.AllPaintingInWmPaint Or _
            ControlStyles.DoubleBuffer Or _
            ControlStyles.ResizeRedraw, _
            True _
        m_StringFormat.Trimming = StringTrimming.EllipsisPath
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        e.Graphics.DrawString( _
            Me.Text, _
            Me.Font, _
            m_ForeColorBrush, _
            RectangleF.op_Implicit(Me.ClientRectangle), _
            m_StringFormat _
    End Sub

    Protected Overrides Sub OnForeColorChanged(ByVal e As EventArgs)
        m_ForeColorBrush = New SolidBrush(Me.ForeColor)
    End Sub

    Protected Overrides Sub OnTextChanged(ByVal e As EventArgs)
    End Sub
End Class