Sunday, June 17, 2007
Insert Images into an RTF control using GDIPlusX

The RichText control that ships with VFP is very useful for providing a formatted text edit box. While this control does support the displaying of images, there is nothing built in to the control that allows you to insert an image. I have included a function below that will allow you insert an image into the RichText control at the current cursor position.

Just specify the object reference to the RTF control and the fullpath of the image you want to insert. The image can be in any format supported by the GDIPlus library (BMP, JPEG, GIF, TIFF, EMF, PNG, etc...). You can also optionally specify the Width and Height you would like the image to be rendered.

This function requires the GDIPlusX library which can be downloaded from the VFPX project site: http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX.

***********************************************************

* Function: InsertRTFImage

*

* Inserts an image into an RTF control at the current cusor position

*

* Parameters:

*   toRTF - specifies an object reference to the RTF control

*   tcImage - secifies the image to insert into the RTF

*   tnWidth - Optional - Specifies the width to use for the image

*   tnHeight - Optional - Specifies the height to use for the image

***********************************************************

FUNCTION InsertRTFImage(toRTF, tcImage, tnWidth, tnHeight)

   LOCAL lcRTF, lcPict, lqData

   LOCAL loImg AS xfcImage

   LOCAL loGfx AS xfcGraphics

   LOCAL loEMF AS xfcMetaFile

   LOCAL lhDC, lhEMF, lnWMFLen

  

   DECLARE Long GetDC IN WIN32API Long

   DECLARE Long ReleaseDC IN WIN32API Long, Long

   DECLARE Long DeleteEnhMetaFile IN WIN32API Long

   DECLARE Long GdipEmfToWmfBits IN GDIPLUS.DLL ;

         Long hemf, Long cbData16, String @pData16, ;

         Integer iMapMode, Integer eFlags

  

   ** Make sure we have initialized the GDIPlusX library

   ** http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX

   IF VARTYPE(_SCREEN.System) <> "O"

      ADDPROPERTY(_SCREEN,"System",NEWOBJECT("xfcSystem",LOCFILE("system.vcx")))

   ENDIF

  

   lcPict = ""

   WITH _SCREEN.System.Drawing

      loImg = .Image.FromFile(tcImage)

      IF loImg.GetLastStatus() <> 0

         ERROR "Could not open file: "+tcImage

      ELSE

         ** If we didn't specify a width, use the image's width and height

         IF EMPTY(tnWidth)

            tnWidth = loImg.Width

            tnHeight = loImg.Height

         ENDIF

         ** Get the default screen HDC as a reference

         lhDC = GetDC(0)

         ** Create a new metafile

         loEMF = .Imaging.MetaFile.New(lhDC, ;

            .Rectangle.New(0,0,tnWidth,tnHeight), ;

            .Imaging.MetafileFrameUnit.Pixel, ;

            .Imaging.MetafileType.Emf)

         ** We are done with the HDC reference, release it

         ReleaseDC(lhDC, 0)

         ** Get a graphics context for the metafile so we can draw to it

         loGfx = .Graphics.FromImage(loEMF)

         loGFX.SmoothingMode = .Drawing2D.SmoothingMode.HighQuality

         loGFX.InterpolationMode = .Drawing2D.InterpolationMode.HighQualityBicubic

         ** Draw the image

         loGfx.DrawImage(loImg, 0, 0, tnWidth, tnHeight)

         loGfx = NULL

        

         ** Convert the Metafile to a "Windows Metafile".

         ** This is the best format for the RTF control.

         lhEMF = loEMF.GetHenhmetafile()

         lnWMFLen = GdipEmfToWmfBits(lhEMF, 0, NULL, 2, 0)

         lqData = REPLICATE(0h00,lnWMFLen)

         GdipEmfToWmfBits(lhEMF, lnWMFLen, @lqData, 2, 0)

         DeleteEnhMetaFile(lhemf)

         loImg = NULL

        

         ** This is the RTF tags for the image

         lcPict = [{\pict\wmetafile8]+;

                  [\picwgoal]+ALLTRIM(STR(tnWidth*15))+;

                  [\pichgoal]+ALLTRIM(STR(tnHeight*15))+;

                  CHR(13)+CHR(10)+;

                  STRCONV(lqData, 15)+;

                  CHR(13)+CHR(10)+[}]

      ENDIF

   ENDWITH

  

   ** Stuff the image into the RTF control

   toRTF.SelRTF = [{\rtf1\ansi\ansicpg1252\deff0\deflang1033\uc1 ]+lcPict+[}]

 

   RETURN

ENDFUNC

You can also download a sample program using this function here: RTFInsertImage.zip (2.19 KB)

Bo Durban

Keywords: RichText RTF FoxPro VFP GDIPlus GDIPlusX Image


Sunday, June 17, 2007 10:11:49 PM (Eastern Daylight Time, UTC-04:00)  #     Comments [11]   |