Click here to Skip to main content
15,884,778 members
Articles / Desktop Programming / MFC
Article

A compact filename edit control

Rate me:
Please Sign up or sign in to vote.
4.57/5 (13 votes)
4 Feb 2003CPOL4 min read 76.5K   1.8K   22   8
An edit control that encapsulates compacting of filenames

Sample Image - CompactFilename.gif

Introduction

Often in applications, there is a need to show a filename, for example in a read only edit control. However, the filename maybe larger than can be accommodated in the edit control. Many Microsoft applications show the filename "compacted", whereby part of the path is replaced by ellipsis ("..."). The need arose to do the same for the application that I am currently developing. My solution, presented below, was to create my own class, based on the MFC CEdit control, to handle the filename appropriately.

Path compaction

A short investigation into how to go about compacting the path led me to the function PathCompactPath(). This function is part of the shlwapi.dll, which means that it is not available on systems running Windows 95 or Windows NT unless Internet Explorer 4.,0 or greater is installed. Fortunately, this covered all of the users of our system, and I would imagine it covers most users of 32 bit Windows operating systems.

Using the function is exceedingly simple. It takes three parameters, an HDC, the filename to compact, and the amount of space the text is to fit into. Therefore, to compact the path sufficiently to fit into the edit control, we simply use the following code :

CString CFilenameEdit::GetDisplayName()
{
    // Get the DC for the control, and the rectangle into which we draw text
    CDC * pDC = GetDC();
    CRect rectClient;
    GetRect(&rectClient);

    // Select the correct font into the DC
    CFont * pFontOld = pDC->SelectObject(GetFont());

    // Get the display name, and truncate it to fit into the control
    // Note that we make the buffer larger than max path 
    // in case we have some bizarre
    // situation where a load of ellipsis are inserted 
    // and it overruns the buffer
    // Member variable containing filename; set by caller
    CString strDisplayName = m_strFilename; 
    PathCompactPath(pDC->GetSafeHdc(),
                    strDisplayName.GetBuffer(_MAX_PATH + 1 + BUFFER_EXTRA),
                    rectClient.Width());
    strDisplayName.ReleaseBuffer();

    // Clean up!
    pDC->SelectObject(pFontOld);
    ReleaseDC(pDC);

    return strDisplayName;
}

Note that we have to select the correct font (obtained by calling CEdit::GetFont()) into the DC, before using the function, otherwise the incorrect font is used when determining the text length.

A concern was that, the function would return a string longer than _MAX_PATH characters, in which case we would suffer buffer overrun. This could happen in the case that the ellipsis (essentially three period characters) had a shorter text extent than two characters, and hence two characters in the string were replaced by three. Hence, the call to CString::GetBuffer() requests a slightly larger buffer, just in case!

Using the control

CFilenameEdit, derived from CEdit, is designed to be read only, the idea being that the filename can be set by the parent application, say for example when a user selects a file from a CFileDialog.

The control has just two public functions, SetFilename() and GetFilename, which set and retrieve the filename to be displayed. The call to SetFilename() maintains an internal copy of the full filename, and sets the control text to the compacted filename, obtained using the code above. GetFilename retrieves the full filename, regardless of how it is compacted in the control.

Because the control text will differ from the filename that is to be displayed, the normal DDX_Text routines are no good - when the text is loaded into the control, the full filename will be placed in the control. Similarly, if the compacted filename is displayed in the control, this is exactly what the DDX_Text routine will return when saving the content of the control. Hence, in addition to the control, there is also a DDX_??? routine, DDX_Filename, which calls the SetFilename() and GetFilename() functions accordingly.

As a visual aid to the user, a tooltip control is created. When the mouse hovers over the control, the tooltip displays the complete path.

Demonstration project

The demonstration project has two edit controls, one of which has been subclassed to provide the CFilenameEdit functionality. The other is a standard edit control, which can be used to compare the contents of the controls when a filename is placed into them.

The Browse button allows a file to be chosen, the name of which will be shown in both edit controls. The Get Content button displays the filename shown in the filename edit control, proving that the DDX_Filename routine works correctly.

Conclusion

The control as it stands is exactly what was need for the application I am currently developing. There are so many things that could be added to it, and maybe when I get chance I will add more. Other articles here show how to make the control accept files that have been dragged and dropped onto it, and how to build a Browse button into the control - both ideas that could be incorporated to enhance this control.

At this point, I really ought to pass on my thanks to Roger Allen, whose snippet of information about setting the font in the DC before calling PathCompactPath made the result somewhat more accurate!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United Kingdom United Kingdom
I started computer programming on the Spectrum (writing nothing more complicated than "Hello World" and a few programs that tunelessly Beeped ad infinitum) but then progressed to slightly more serious programming on the Amiga.

After A-Levels in Maths, Physics and Chemistry, I went to the University of East Anglia, Norwich, and studied beer, women and Computing Science.
Some years after graduating, I still have an appreciation of Computing Science, but as I am now married, my other studies are frowned upon.

Since graduating, I have worked on many diverse projects in areas including call centres, logistics, architecture and engineering, and heritage.

Comments and Discussions

 
QuestionPathCompactPath Pin
sarfaraznawaz6-Jun-12 3:29
sarfaraznawaz6-Jun-12 3:29 
NewsIf the tooltip never shows... Pin
MesaTwo30-Jan-06 13:36
MesaTwo30-Jan-06 13:36 
GeneralWM_COPY Pin
56789012345-Feb-03 23:13
56789012345-Feb-03 23:13 
GeneralRe: WM_COPY Pin
Martyn Pearson6-Feb-03 2:22
Martyn Pearson6-Feb-03 2:22 
GeneralAn easier way - SS_PATHELLIPSIS Pin
Neville Franks5-Feb-03 8:59
Neville Franks5-Feb-03 8:59 
GeneralRe: An easier way - SS_PATHELLIPSIS Pin
Martyn Pearson6-Feb-03 2:29
Martyn Pearson6-Feb-03 2:29 
GeneralAhhh... Pin
Roger Allen5-Feb-03 6:37
Roger Allen5-Feb-03 6:37 
GeneralRe: Ahhh... Pin
Martyn Pearson6-Feb-03 2:22
Martyn Pearson6-Feb-03 2:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.