Using MFC to access MathType's OLE subsystem

Please note this document applies only to MathType 6.9 and later.

The purpose of this document is to describe how to access MathType's OLE server (MathType 6.5 and greater) through the Microsoft Foundation Class Library (MFC). Two methods of interacting with MathType are demonstrated. The first is invoking MathType's user interface to have the user insert any equation, the second demonstrates programmatically inserting a MathML equation. See the SDK sample application OLECont which contains the code described below.

The following directions all pertain to Visual Studio 2005. Everything described here should work in previous versions of Visual Studio, and VS 2008 as well, though the specifics may need to be modified somewhat.

  1. In Visual Studio select File\New\Project.
  2. Under Visual C++, select MFC for the Project type.
  3. Select the MFC Application template.
  4. Enter a name for the project, and select the directory location.
  5. Select defaults for the Application Type.
  6. Select Container for Compound document support.
  7. Select the defaults for everything else.

You should now have an MFC Application project with compound document support that can host OLE objects. The next step is to set up routines that are called in response to user action to insert a MathType OLE object.

The next step is to create two menu options, and two toolbar buttons (if you wish) to insert a new equation, and to insert a MathML equation. You should be familiar enough with Visual Studio to accomplish this. After this step is done you'll have two method stubs that are called by the menu and toolbar options. The next step is to implement the code that inserts the equations.

The first step in inserting a new equation is to create a COleClientItem derived object. When you created the application, one of these classes was created for you. In the sample application COLECont, this class is named COLEContCntrItem. Next, you'll need to get the CLSID for MathType equations which are represented by the string Equation.DSMT4. You can then create the OLE object by calling the CreateNewItem method on the COleClientItem object, passing in the CLSID as the lone parameter.

The next step is to invoke MathType to permit the user to enter an equation, and this is done by calling the COleClientItem method DoVerb with the OLEIVERB_SHOW parameter. Again, refer to the code to see this in action. Keep in mind that to later refer to this OLE object, you'll need to keep a pointer around that dereferences it, in this case, m_pSelection. Also, this code was written to manage only one such pointer, if your code permits more than one OLE object, you'll need to add the functionality to manage more than one such pointer.

To programmatically insert a MathML equation follow the steps above for Inserting a new equation, with the exception of the call to DoVerb. Instead, you'll be making a call to IDataObject's SetData method, but this requires two structures to be passed as parameters, and these structures need to be set up correctly before that call. In the FORMATETC structure, the cfFormat member needs to be set to the return value of a call to RegisterClipboardFormat, with "MathML" passed in as a parameter. dwAspect should be set to DVASPECT_CONTENT, and tymed should be set to TYMED_HGLOBAL. This parameter describes how the MathML data is to be sent to the function in the STGMEDIUM structure.

The STMEDIUM member hGlobal needs to point to globally allocated memory that contains the MathML string. Set the tymed member to TYMED_HGLOBAL again.

To call the IDataObject method SetData, a pointer to IDataObject needs to be obtained. This is done by creating a COleDataObject object, and attaching it to the COLEClientItem by calling its AttachDataObject method. Then you can get the IDataObject pointer by calling the GetIDataObject method on the COleDataObject object.

You're now ready to call SetData, passing in the FORMATETC and STGMEDIUM structures you created earlier.

Once you've set the MathML data on the object, you need to convert it to a MathType OLE object by calling the DoVerb method on the COLEClientItem object, with the parameter set to 2. In the sample code this value is set as the enum kCovert. After this call has been made you should have a MathType OLE object with an equation set to the converted value of the MathML string that you passed in as the STGMEDIUM hGlobal member.