Providing a Custom Wordbreak Function in Edit Controls

Last reviewed: November 2, 1995
Article ID: Q109551
The information in this article applies to:
  • Microsoft Windows Software Development Kit (SDK) versions 3.1
  • Microsoft Win32 Application Programming Interface (API) included with:

        - Microsoft Windows NT versions 3.5 and 3.51
        - Microsoft Windows 95 version 4.0
    

SUMMARY

An application sends the EM_SETWORDBREAKPROC message to an edit control to replace the default wordwrap function with an application-defined wordwrap function. The default wordwrap function breaks a line in a multiline edit control (MLE) at a space character. If an application needs to change this functionality (that is, to break at some character other than a space), then the application must provide its own wordwrap (wordbreak) function.

MORE INFORMATION

A wordwrap function scans a text buffer (which contains text to be sent to the display), looking for the first word that does not fit on the current display line. The wordwrap function places this word at the beginning of the next line on the display.

A wordwrap function defines the point at which Windows should break a line of text for multiline edit controls, usually at a space character that separates two words. This can be changed so that the line in an MLE can be broken at any character. For more information on the EM_SETWORDBREAKPROC message, please refer to the Windows 3.1 SDK "Programmer's Reference, Volume 3: Messages, Structures, and Macros" manual.

Below is sample code that demonstrates how to break a line in a multiline edit control at the "~" (tilde) character (for example) instead of the regular space (" ") character.

The sample code assumes that the edit control is a multiline edit control and that it is a child control in a dialog box.

Sample Code

//Prototype the application-defined wordbreakproc.
int CALLBACK WordBreakProc(LPSTR, int, int, int) ;

//Install wordbreakproc in the WM_INITDIALOG case.
  case WM_INITDIALOG:

    lpWrdBrkProc = MakeProcInstance(WordBreakProc, hInst);


    //Send the EM_SETWORDBREAKPROC message to the edit control
    //to install the new wordbreak procedure.
     SendDlgItemMessage(hDlg, ID_EDIT, EM_SETWORDBREAKPROC, 0,
                        (LPARAM)(EDITWORDBREAKPROC)lpWrdBrkProc) ;
     return (TRUE);

int FAR PASCAL WordBreakProc(LPSTR lpszEditText, int ichCurrent,
                             int cchEditText, int wActionCode)
{

   char FAR *lpCurrentChar;
   int  nIndex;
   int  nLastAction;

   switch (wActionCode) {

     case WB_ISDELIMITER:

     // Windows sends this code so that the wordbreak function can
     // check to see if the current character is the delimiter.
     // If so, return TRUE. This will cause a line break at the ~
     // character.

      if ( lpszEditText[ichCurrent] == '~' )
         return TRUE;
      else
         return FALSE;

      break;

     // Because we have replaced the default wordbreak procedure, our
     // wordbreak procedure must provide the other standard features in
     // edit controls.

     case WB_LEFT:

     // Windows sends this code when the user enters CTRL+LEFT ARROW.
     // The wordbreak function should scan the text buffer for the
     // beginning of the word from the current position and move the
     // caret to the beginning of the word.

         {
            BOOL bCharFound = FALSE;

            lpCurrentChar = lpszEditText + ichCurrent;
            nIndex = ichCurrent;

            while (nIndex > 0  &&
                  (*(lpCurrentChar-1) != '~' &&
                   *(lpCurrentChar-1) != 0x0A) ||
                  !bCharFound )
            {
               lpCurrentChar = AnsiPrev(lpszEditText ,lpCurrentChar);
               nIndex--;

               if (*(lpCurrentChar) != '~' &&  *(lpCurrentChar) != 0x0A )

                  // We have found the last char in the word. Continue
                  // looking backwards till we find the first char of
                  // the word.
                 {
                   bCharFound = TRUE;

                   // We will consider a CR the start of a word.
                   if (*(lpCurrentChar) == 0x0D)
                       break;
                 }

            }
            return nIndex;

         }
      break;

     case WB_RIGHT:

     //Windows sends this code when the user enters CTRL+RIGHT ARROW.
     //The wordbreak function should scan the text buffer for the
     //beginning of the word from the current position and move the
     //caret to the end of the word.

      for (lpCurrentChar = lpszEditText+ichCurrent, nIndex = ichCurrent;
           nIndex < cchEditText;
           nIndex++, lpCurrentChar=AnsiNext(lpCurrentChar))

       if ( *lpCurrentChar == '~' ) {
      lpCurrentChar=AnsiNext(lpCurrentChar);
         nIndex++;

         while ( *lpCurrentChar == '~' ) {
           lpCurrentChar=AnsiNext(lpCurrentChar);
           nIndex++;
          }

         return nIndex;
       }

       return cchEditText;
       break;

  }
}

The wordwrap (wordbreak) function above needs to be exported in the .DEF file of the application. The function can be modified and customized according to the application's needs.


Additional reference words: 3.00 3.10 3.50 3.51 4.00 95 multi-line
KBCategory: kbui
KBSubcategory: UsrCtl


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: November 2, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.