Using RichEdit 6.0 for Math

A number of readers have asked how to use the RichEdit 6.0 shipped with Office 2007 to edit and display mathematical text. This post explains one way to do so. The code assumes that you already have an application that knows how to instantiate a RichEdit control with a window identified by hwndRE. The function ToggleMathZone() is designed to be hooked up to the Alt+= hot key, which Word 2007 uses to toggle a math zone on and off.

#include "windows.h"

#include "richedit.h"

#define CFE_MATH 0x10000000

#define CFM_MATH CFE_MATH

#define MATH_LCID 0x0001007F

#define SCF_ONLYCFEFFECTS 0x0200 // Only set/get CF

#define EM_SETADJUSTTEXTPROC (WM_USER + 234)

void ToggleMathZone(HWND hwndRE)
{
HRESULT hr;
CHARFORMAT2W cf;

cf.cbSize = sizeof(CHARFORMAT2W);
SendMessage(hwndRE, EM_GETCHARFORMAT,

                SCF_SELECTION | SCF_ONLYCFEFFECTS, (LPARAM)&cf);
cf.dwEffects ^= CFE_MATH; // Toggle math zone

if (cf.dwEffects & CFE_MATH) // Turn on math zone
{

       // Turn on LineServices

       SendMessage(hwndRE, EM_SETTYPOGRAPHYOPTIONS,

  TO_ADVANCEDTYPOGRAPHY, TO_ADVANCEDTYPOGRAPHY);

// Enable built-in math autocorrect
SendMessage(hwndRE, EM_SETADJUSTTEXTPROC, 1, 0);

              // Setup math font and lcid

              cf.dwMask = CFM_FACE | CFM_LCID;

       wcscpy(cf.szFaceName, L"Cambria Math");

              cf.lcid = MATH_LCID;

              SendMessage(hwndRE, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);

    }
cf.dwMask = CFM_MATH;
    SendMessage(hwndRE, EM_SETCHARFORMAT,

               SCF_SELECTION | SCF_ONLYCFEFFECTS, (LPARAM)&cf);

}

There is a somewhat strange message to control math transformations, namely EM_TRANSFORMMATH (WM_USER + 264). The wparam bits are

defined by

#define XM_LINEARIZE 0

#define XM_BUILDUP 1

#define XM_LINEARFORMAT 2

#define XM_TEX 3

#define XM_NEEDTERMOP 4

#define XM_BMPALPHABETICS 8

#define XM_MATHALPHABETICS 9

#define XM_BUILDMATHZONES 16

#define XM_NOMATHAUTOCORRECT 32

#define XM_MATHAUTOCORRECT 33

So you should be able to select the range you want and then send EM_TRANSFORMMATH with wparam = XM_BUILDUP to build it up. The XM_BUILDUP/ XM_LINEARIZE, XM_LINEARFORMAT/TEX, XM_MATHALPHABETICS/ XM_BMPALPHABETICS, and NOMATHAUTOCORRECT/ XM_MATHAUTOCORRECT pairs have to be handled in separate messages, since they all depend on bit 0. That’s why the message is somewhat strange.

TeX isn’t supported in RichEdit 6.0, but the XM_TEX definition is included for completeness.

 

TOM2 has better methods, but it requires a new tom.h, more documentation, etc., and we don’t have a current plan for releasing this info.

 

The Office 2007 RichEdit 6.0 shipped without having math RTF conversions enabled. So it you want to save a file with math in it, you need to use RichEdit’s binary file format or convert the math zones to linear format. The binary format is used by the EM_STREAMIN and EM_STREAMOUT messages if SF_RTF is replaced by SF_BINARY defined by

#define SF_BINARY 0x0008

Only RichEdit 5.0 and later versions understand RichEdit’s binary file format and RichEdit 5.0 doesn’t understand RichEdit 6.0’s math properties. The next version of RichEdit understands math RTF as well.