RichEdit Place Holder

Murray Sargent

Sometimes you need a text box that cues the user to type something in, such as, “Start a conversation”. As soon as the user types something, the cue text vanishes, and the user sees what the user typed. If the user deletes all the text, the cue text reappears. Such a text box is called a place-holder control. The Microsoft 365 RichEdit has such a control. This post explains how to include it in your application.

Send two messages to set up a place-holder control: 1) EM_SETTEXTEX‎ to set the place-holder text, and 2) EM_SETEDITSTYLEEX‎ to enable the place-holder functionality. For setting the text, write something like

    const WCHAR wszPlaceholder [] = L"Start a conversation";
    SETTEXTEX settext = {ST_PLACEHOLDERTEXT, 1200};

    SendMessage (hwndRE, EM_SETTEXTEX, (WPARAM)&settext, (LPARAM)wszPlaceholder);

To enable the place-holder functionality, send EM_SETEDITSTYLEEX to an empty control by

    SendMessage (hwndRE, EM_SETEDITSTYLEEX, SES_EX_SHOWPLACEHOLDERONFOCUS,
        SES_EX_SHOWPLACEHOLDERONFOCUS);

At this point, the place-holder text “Start a conversation” is displayed. The constants ST_PLACEHOLDERTEXT and SES_EX_SHOWPLACEHOLDERONFOCUS aren’t documented on the web, so here they are

    #define SES_EX_SHOWPLACEHOLDERONFOCUS     0x80000000
    #define ST_PLACEHOLDERTEXT                0x0010

Internally, the place-holder functionality is implemented using two stories, one for the main text and one for the place-holder text. A story is a programming object that stores rich text. More about this kind of story in another post. Whenever the main text is empty, the place-holder story is displayed on screen. As soon as the user types something, the main story is displayed. The initial place-holder facility was added in 2005, but SES_EX_SHOWPLACEHOLDERONFOCUS functionality was added in 2018 and isn’t in the Windows msftedit.dll. The XAML TextBox uses RichEdit and supports place-holders.