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)
    Destination.ReleaseHdc(hDC)
    If Success Then
        Dim p As Integer = Strings.InStr(Path, ControlChars.NullChar) - 1
        If p > 0 Then
            Return Strings.Left(Path, p)
        Else
            Return Path
        End If
    Else
        Throw New Exception("String does not fit into space.")
    End If
End Function

Usage:

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

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. Basing the control on System.Windows.Forms.Label would be possible too:

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 _
        )
        Me.UpdateStyles()
        m_StringFormat.Trimming = StringTrimming.EllipsisPath
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        MyBase.OnPaintBackground(e)
        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.Dispose()
        m_ForeColorBrush = New SolidBrush(Me.ForeColor)
        MyBase.OnForeColorChanged(e)
    End Sub

    Protected Overrides Sub OnTextChanged(ByVal e As EventArgs)
        Me.Invalidate()
        MyBase.OnTextChanged(e)
    End Sub
End Class