Displaying Long Non-Breakable Text (File Path) In MessageDlg – Truncation/Ellipsis Issues

ttaskdialog-sample
Introduced way back in Delphi 2009 the TTaskDialog (defined in Dialogs.pas) implements task dialogs. Task dialogs first appeared in Windows Vista and are used in later Windows versions. In essence, a task dialog is similar to, while much more flexible and parameter-rich than the standard message dialog. You’ve surely seen such fancy dialogs in action: those containing message title and text (content), icons, push buttons, radio buttons, expandable footer area and more.

In Delphi we have several options (including ShowMessage, MessageDlg, Application.MessageBox and some more) when it comes to displaying some modal message to the user. I’m rarely using ShowMessage and Application.MessageBox as both are not as flexible as MessageDlg (actually ShowMessage internally calls MessageDlg).

MessageDlg: Bruce Banner or Hulk ?

Using MessageDlg can result in 2 different displays of the actual message dialog. What will get displayed (and more importantly how) to the user is dependent on several factors including the following: Windows version your application is running on, if the application was built including runtime themes and if Windows uses themes.

If your application is running on Windows XP, MessageDlg internally creates and displays a standard Delphi form (though set to look and work as a dialog). If your application is running on at least Windows Vista (therefore Windows Vista, 7, 8, 10, etc) and runtime themes are enabled and used by Windows, MessageDlg will internally create the shiny task dialog! Actually, the TaskDialogIndirect API call will be made. Even though this beast of a function has many parameters and options, MessageDlg will only take advantage of a few (title, text, buttons).

Finally, you end up simply using MessageDlg and Delphi determines if an old school dialog form is to be created or the new more nicer task one. Problem solved, let’s move on to other bugs… Well, not so fast!

TaskDialog Width & Long Text Truncation

One of the nasty features of TaskDialog internal implementation is that it will try to determine on its own what should be the width of the dialog. The text you specify to be displayed will be wrapped and displayed in several lines. This is, of course, something you would expect.

However! If the text to be displayed is constructed entirely of non-breakable characters (no spaces and alike) and is longer than some 50 (or so) characters, the display will get truncated and ellipses will be injected into the final display!?! TaskDialogs do not grow in width if “more” text is to be displayed – they grow in height and truncate/ellipsesize the message text. Old school dialog form on Windows XP will grow in width until it reaches screen size – and will not truncate the message for the user in any way!

Truncation / Ellipsesization Visualized

I’m running this on Windows 7, themes enabled.

I need to display the full file name of a file where the path does not contain any spaces (which seem to be default “wrap here” characters). Let’s pretend this file should be displayed (has some 250 characters, no intervening spaces) in a dialog:

const
  LongFileName = '\\server\sub-folder-name\folder0123456789folder0123456789\another-folder\morefolders\a-directory\another-directory\morefolders\morefolders\a-directory\another-directory\morefolders\a-directory\another-directory\somefile-using-hypens-in-long-filename.txt';

First, using the TTaskDialog component and only setting a few properties:

TaskDialog1.Caption := 'TaskDialog1';
TaskDialog1.CommonButtons := [tcbOk];
TaskDialog1.Text := LongFileName;
TaskDialog1.Execute;

Result :
ttaskdialog-truncated-ellipses

Trying with MessageDlg as

MessageDlg(
  Format('This file has a very long path: %s', [LongFileName]), 
  mtInformation, [mbOk], -1);

Result:
messagedlg-truncated-ellipses

Proof that MeesageDlg uses TaskDialog internally 🙂

Btw, you cannot set the width of the MessageDlg. Neither the “TDF_SIZE_TO_CONTENT” seems to help.

I Don’t Need (read: Want) No Truncation!

I really, really want to display the entire file path to the user with no truncation and ellipses.

Let’s try using the WrapText (SysUtils.pas) function:

MessageDlg(
  Format(
    'This file has a very long wrapped path: %s',
    [WrapText(LongFileName)]), 
  mtInformation, [mbOk], -1);

Result:
messagedlg-wraptext

Better! Note that WrapText has 2 overloads and the more simple one has a property “MaxCol” which defaults to 45 (have no idea why).

However, 45 is not enough, I want the line to be some 80 or so characters, so trying with the following

MessageDlg(
  Format(
    'This file has a very long wrapped path: %s',
    [WrapText(LongFileName), 80]), 
  mtInformation, [mbOk], -1);

Oh no! Again, truncation and ellipses – why oh why?!
messagedlg-wraptext-truncated-ellipses

Finally, after spending too much time on all this I’ve decided for the next option as the kind-of-I-can-live-with-it best one:

UseLatestCommonDialogs (not in this occasion, please)

Getting away from the whiny new task dialog and disabling UseLatestCommonDialogs:

UseLatestCommonDialogs := false;
MessageDlg(
  Format(
    'This file has a very long wrapped at 80 path: %s', 
    [WrapText(LongFileName, 80)]),
  mtInformation, [mbOk], -1);
UseLatestCommonDialogs := true;

Result:
messagedlg-uselatestcommondialogs-no

I’m not too happy with this – as the old school/style dialog is displayed – but I simply have to show the full file path to the user: no truncation or ellipses are allowed for me.

Do you have any idea how this can be better solved?

(I’m not looking for another 3rd party solution or some special one-time workarounds)

9 thoughts on “Displaying Long Non-Breakable Text (File Path) In MessageDlg – Truncation/Ellipsis Issues

    1. zarkogajic Post author

      @IL: Thanks, but I’d like to avoid messing with the VCL source. Note however that TDIF_SIZE_TO_CONTENT is already set (look at Delphi implementation source), still the long text is truncated.

      Reply
  1. IL

    Looks like Microsoft’s violation of very own Visual Guidelines for text (;

    Size controls and panes within a window to match their typical content. Avoid truncated text and their associated ellipses. Users should never have to interact with a window to view its typical content—reserve resizing and scrolling for unusually large content. Specifically check: Control sizes. Size controls to their typical content, making controls wider, taller, or multi-line if necessary. Size controls to eliminate or reduce scrolling in windows that have plenty of available space. Also, there should never be truncated labels, or truncated text within windows that have plenty of available space. However, to make text easier to read, consider limiting line widths to 65 characters.

    Though there is no plenty of space available in the TaskDialog.

    Reply
  2. Tatsumaro

    Great workaround! This is an annoying reality of MessageDlg… You helped me big time! Thanks!

    Reply
      1. zarkogajic Post author

        As described in the post – to use UseLatestCommonDialogs and set it to False.

        Reply
        1. Yi Zheng

          Thank you! I tried TaskDialog that was failed instead of MessageDlg when I set UseLatestCommonDialogs to false. I will use MessageDlg to see the results.

          Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.