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 [2]  

 Wednesday, June 13, 2007
HTML Tables and Styles

Have you ever tried to add borders to individual cells in an HTML table using style sheets? Something similar to <table border="1"> only done with CSS.

I had a requirement to put a 1 pixel black border between all cells in an HTML table. I wanted to do this without having to put a style or class attribute into every cell in the table. I thought: "How hard can this be?". There has to be a way of doing this with a single style attribute.

But after a quick search on the web with too many non-relevant results, (I mean what can you search for that doesn't bring back over a million hits). I decided to come up with my own technique:

<style type="text/css">

  table.border tr td,
  table.border tr th
{border:1px solid black;}

  table.border {border-collapse:collapse;}

</style>

 

<table class="border">

  <tr>

    <th>Header 1</th> 

    <th>Header 2</th> 

    <th>Header 3</th> 

    <th>Header 4</th> 

  </tr>

  <tr>

    <td>Data 1</td> 

    <td>Data 2</td> 

    <td>Data 3</td> 

    <td>Data 4</td> 

  </tr>

  <tr>

    <td>Data 1</td> 

    <td>Data 2</td> 

    <td>Data 3</td> 

    <td>Data 4</td> 

  </tr>

</table>

Yields the following output:

Header 1 Header 2 Header 3 Header 4
Data 1 Data 2 Data 3 Data 4
Data 1 Data 2 Data 3 Data 4

Is there a better way of doing this?

Bo Durban


Wednesday, June 13, 2007 2:13:21 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [2]  

 Tuesday, June 12, 2007
I have entered the world of blogging

After much prodding, mostly by Craig Boyd, I have finally set up a blog. I plan to post some of my daily ramblings here under the Moxie Data banner.

I’m using the dasBlog based on Craig’s recommendation. It was fairly easy to set up and customize. So far, so good.

Tomorrow I will post something a little more technical, but for now I want to encourage anyone who has not signed up for a conference yet this year, to do so. The quality of session topics is better than ever plus there are several new speakers bringing in some fresh ideas.

FoxForward 2006 - Alpharetta, GA USA - September 7th-9th I will be speaking at the FoxForward conference in Alpharetta, GA on September 7th-9th, 2007. It is super convenient for me (about 30 miles away) and only a few miles north of downtown Atlanta. Kevin Cully did a great job putting this conference together last year. His first ever. So I look "forward" to what he has in store for this year.

Southwest Fox 2007, Mesa, AZ, October 18 - 21, 2007I will also be at the Southwest Fox conference in Mesa, AZ on October 18th-21st, 2007. I will hopefully be doing a vendor session to show off some of the new reporting enhancements in Sedna and how we are leveraging them in our Moxie Objects 2.0 product.  I have attended SWFox for the past 2 years and have always had a great time. If you are going, I recommend you plan an extra day to take in the sites in and around Phoenix.

Anyway, thanks for stopping by. Check back soon. Over the next few days I will be posting some examples using the GDIPlusX library, part of the VFPX project on Codeplex. I have a long way to go to catch up to the number of great articles and blog entries potsed by Cesar Chalom.

Bo Durban


Tuesday, June 12, 2007 3:51:47 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [4]