Watermark your reports with FoxyPreviewer

Adding watermarks to reports is something that I've already blogged years ago during the development of GdiPlusX. In those times, we needed to create a specific ReportListener to manage the report pages, and draw the watermarks. We needed another external library, GdiPlusX, that was responsible for drawing at the report surface, and for applying some special effects to the images, such as transparencies and converting to grey scale.

Finally, we have this feature in FoxyPreviewer too ! That means that from now on, you can add watermarks to your reports without having absolutely any knowledge about GDI+ or ReportListeners, just by setting some few properties! In fact, by filling just one property you can have watermarks in all pages of your reports. In fact, this feature was asked by many people, but I had to postpone it because I had to implement to the original Gdi+ classes some new classes and functions, to create the transparencies and grey-scale effects. If you're curious, and want to check for these functions, have a look at the file pr_gdiplushelper.prg in the sources folder.

The usage is, as always, super simple. The only requirement is that you use FoxyPreviewer in the simplified mode.

Related properties:

cWatermarkImage - character, the name of the WM image. Important: this image MUST be stored locally, CAN'T be embedded in your EXE, obligatory property if you want to show the watermark. To remove the watermark from the next reports, just store an empty value to this property.

nWatermarkType - numeric, 1 = Colored (default), 2 = Converts the source image to grey scale, optional property

nWatermarkTransparency - numeric, from .10 to 1, default = 0.25, the transparency level of the WM image; 1 = Opaque, optional property

nWaterMarkWidthRatio - numeric, default = 0.75, the width size in proportion of the watermark in the report page, optional property

nWaterMarkHeightRatio  - numeric, default = 0.75, the height size in proportion of the watermark in the report page, optional property


DO FoxyPreviewer.App
* Adding watermarks to reports
_Screen.oFoxyPreviewer.cWatermarkImage = ADDBS(HOME()) + "Graphics\Gifs\Morphfox.gif"
_Screen.oFoxyPreviewer.nWaterMarkType = 1 && 1 = Colored (default), 2 = B&W

_Screen.oFoxyPreviewer.nWatermarktransparency = .30 && (0-1) Transparency, 0 = Transparent, 1 = Opaque
_Screen.oFoxyPreviewer.nWaterMarkWidthRatio = .75 && (0-1) Proportion that the WM will occupy in page width
_Screen.oFoxyPreviewer.nWaterMarkHeightRatio = .75 && (0-1) Proportion that the WM will occupy in page height

REPORT FORM LOCFILE(_Samples + "\Solution\Reports\Colors.frx") PREVIEW

If you only set the "cWatermarkImage" property to a valid image file existing on the disk, you'll have your first watermark.
To reset your reports to the original settings, without the watermark, just clear the value of the property '.cWatermarkImage = "" '.


Below you can see how the watermarks will appear, depending on the property values that you choose:

1 -
.nWatermarkType         = 1 && 1 = colored ; 2 = greyscale
.nWatermarkTransparency = 1 && 0 = transparent ; 1 = opaque
.nWatermarkWidthRatio   = 0.90 && 0 - 1
.nWatermarkHeightRatio  = 0.90 && 0 - 1 


2 -
.nWatermarkType         = 1 && 1 = colored ; 2 = greyscale
.nWatermarkTransparency = 0.25 && 0 = transparent ; 1 = opaque
.nWatermarkWidthRatio   = 0.50 && 0 - 1
.nWatermarkHeightRatio  = 0.50 && 0 - 1 


3 -
.nWatermarkType         = 2 && 1 = colored ; 2 = greyscale
.nWatermarkTransparency = 0.10 && 0 = transparent ; 1 = opaque
.nWatermarkWidthRatio   = 1.00 && 0 - 1
.nWatermarkHeightRatio  = 1.00 && 0 - 1


4 -
.nWatermarkType         = 2 && 1 = colored ; 2 = greyscale
.nWatermarkTransparency = 0.25 && 0 = transparent ; 1 = opaque
.nWatermarkWidthRatio   = 0.75 && 0 - 1
.nWatermarkHeightRatio  = 0.75 && 0 - 1

THOR Tools – A must have for all Foxers!!!

Thor is one of the newest VFPX projects, that brings probably the most helpful set of tools for VFP9 developers, bringing for FREE, TONS of features that were available only in other languages, or even as paid tools. As it’s described in the THOR main web page:

Thor is a tool for managing add-on tools in the IDE, managing menus and hot key assignments for IDE Tools.

But as you’ll see below, it’s much more than that !!!

Today I found myself having to do lots of data manipulations, and to create several SQL INSERT instructions. I remember to have seen a discussion running about this last year, so I decided to see if it was implemented already in THOR.

See how easy it is now for us to create our SQL (Insert, Update, Delete), Cursor creation and even Browsing !

Having THOR installed, just follow some few steps:

1 – Open the table that you want to work with, For example, I did:

USE (_Samples + "\Data\Employee")

2 – In the main menu, go to “Thor Tools”, “Tables” and “Super browse”


All the rest is super intuitive, no need of further explanations at all !

Then, it will open the window below, allowing you to:

1 - select the fields you desire
2 – Click on the “Field picker” tab
3 – At the right optio group panel, select and play with the options you need
4 – And Copy to the clipboard !!!

Paste the contents (CTRL+V) to have the script available in your Code window!

But there’s more… It’s a very nice table / cursor viewer, with filtering and other facilities

Need a schema for documenting ? Here it is !!!

Hey !!!

But there’s even more !!!

THOR brings another tool for a similar task! Again at the main menu, “Tables”, then “INSERT INTO from cursor Wizard”. The name says everything!

This project is under constant development. The architecture of THOR allows it to receive several tools from the community, so if you’re willing to offer any tool, just go ahead, and contact Jim Nelson, the project manager and creator of this gem. For example, the tools shown here were developed and offered by Tore Bleken, and included in THOR.

Visit the project pages, and see the documentation is online. Installing the tool will not take more than 3 minutes from you!

As always, the authors are always looking for feedback, please contact them via VFPX on CodePlex to let them know if you have any issues, or even to let them know it works fine !

Thanks again to Jim and Tore for these magnificent tools... They have saved my day!



Jim Nelson, very kindly just sent me a list of more features, some of them ingenious, see:

Things you could not possibly know -- not a long list, but worth the effort.

(1) In the list of fields on the left, you can click on the column heading to sort by the column. This
also sorts the columns in the grid to match.

(2) When browsing the grid, you can click on a column heading to select a field. This is always
the way that I select fields, to make sure I am getting the right ones.

(3) Two buttons at the bottom -- you can turn off read-only so you can edit the table.  You can
decide to hide unselected fields -- just show the ones you want.

(4) "Save selections" allows you to your selection of fields for this table from one session to the next.

(5) There's a combobox at the top which shows the current table. You can use that to navigate to
other open tables.

(7) You can point to a table name in code and browse the table. You were working on the table
 'Employee'. If you saw that name in code, you can click on it and use the tool (you don't even have
to highlight the name) -- if the name matches an alias in use, it will SELECT it and browse it.
Otherwise it will try to USE it.  (There's a plug-in PRG that lets you customize this).  This is the
way I always use it.  ..... See a table name in code, click on it, browse it.  BAM! Can't imagine
doing it any other way.

(8) You can also call this using Dynamic Snippets, like this:
FP Employee {{Dynamic Snippet Tool}}
This actually pastes the code in for you directly (There's another button in this case).


Full justified texts in Reports with FoxyPreviewer

A relative old feature, but that I missed to blog about is the possibility of adding justified texts in your report fields.
In FoxyPreviewer, that's really very very simple !
  • Select the field that you want to justify
  • Double-click that field to access the properties dialog
  • Select the "Other" Tab
  • Click "Edit User Data" button
  • Add the "<FJ>" tag in the textbox
That simple !
When you run your report, that field will appear justified.
This setting works also when you export your report to PDF, RTF and HTML!


Full Justified Texts with GdiPlus-X

 According to Wikipedia, "In typesettingjustification (can also be referred to as 'full justification') is the typographic alignment setting of text or images within a column or "measure" to align along both the left and right margin. Text set this way is said to be "justified".


In justified text, the spaces between words, and, to a lesser extent, between glyphs or letters (kerning), are stretched or sometimes compressed in order to make the text align with both the left and right margins. When using justification, it is customary to treat the last line of a paragraph separately by left or right aligning it, depending on the language direction. Lines in which the spaces have been stretched beyond their normal width are called loose lines, while those whose spaces have been compressed are called tight lines."

To create Full-Justified texts, the main point is to know exactly the measures of each word, and to be able to draw each word exactly in a certain position. Unfortunately, VFP does not bring thiese possibilities natively. Yes, I know we have TXTWIDTH and FONTMETRIC(6), but they are not that accurate. A good but not beautiful solution was to use some monospace fonts, like Courier New or Lucida Console, that every character has the same measures.

So, if we wanted to use any fonts, one of the few options was to use the RTF Active-X control, or to use an OLE Word object in a VFP form.

With the GdiPlus-X library, from now on you can also draw Full Justified texts in a very easy way too.

GDI+ originally allows to draw texts in three String Format Alignments: Left, Center and Right. In these last years, I've noticed that it's a very common request from VFP developers the ability to draw texts in FullJustified mode.

To draw Full-Justified strings we need to have the accurate measurements of each of the words in a paragraph, and draw each word individually in a calculated position. Well, no need to say that GDI+ provides the needed tools for the task. So, we added a new method to the Graphics class of the GdiPlus-X library, DRAWSTRINGJUSTIFIED.

Maybe you find that the natural choice would be to add a new StringFormat Alignment fot FullJustifying purposes, and let the method "DrawString" deal with the text and the received parameters and draw. But we believe that the original library, GdiPlus.dll will receive some updates in the future, and MS can possibly include a specific "StringFormat.Alignment" for our case. So, we found the best solution would be to create a new method, with a different name. The usage is very similar to the original "DrawString":


MethodDrawStringJustified(tcString, toFont as xfcFont, toBrush as xfcBrush, toRectangle as xfcRectangle)


tcStringCharacter, String to Draw
toFontObject, Font that defines the text format of the string.
toBrushObject, Brush that determines the color and texture of the drawn text.
toRectangleObject, Rectangle structure that specifies the location of the drawn text.



Basically, DrawStringJustified receives the 4 parameters above, very similar to DrawString. But intead of drawing the whole text in one time, this function needs to make some calculations in order to know where exactly each word from the string will be drawn. It starts by populating an array of words and the calculated measures of each word, using GdipMeasureString. Then, calculates how many words will fit on each line. Next step is to calculate the resulting space between the words of the related line. After collecting all information needed, we draw each word at a time, at the calculated position.

For maximum performance, we used direct API calls to gdiplus.dll for the main process, measuring and drawing each string. I did some tests, and the difference is huge, about 5 times faster.


All samples below require that you have the latest PLANNED RELEASE, 0.08A. It's a little bit hidden at codeplex, so I'm putting below the link for direct downloading:



1 - Draw Full-Justified strings in image files

The PRG below shows how to draw a text in 4 ways, left, centered, right and full justified, just like the picture above, and saves he image to a file.

** Program: FullJustCode.prg
** Sample program that draws text in 4 modes:
** 1 - Left Aligned
** 2 - Centered
** 3 - Right Aligned
** 4 - Full Justified

* The code performs the following actions:
* Creates a String
* Draws text in 4 modes and shows the results
* Locate and load GdiPlus-X
DO LOCFILE("System.App")
GDIPlusX is a set of VFP 9.0 class libraries that wrap the 603 GDI+ Flat API functions of GDIPlus.dll.
The library currently consist of 83 VFP classes and 1,146 methods. The project is still under development so not all classes have been completed and several of the classes/methods are still being tested.


    * Create Image
    LOCAL loBMP AS xfcBitmap
    m.loBMP = .BITMAP.New(400, 600)

    * Create a Graphics object to be able to draw on image
    LOCAL loGfx AS xfcGraphics
    m.loGfx = .Graphics.FromImage(m.loBMP)

    * Fill Image with White Background color

    * Create a DarkBlue Brush
    LOCAL loTextBrush AS xfcSolidBrush
    m.loTextBrush = .SolidBrush.New(.COLOR.DarkBlue)

    * Create Font Object
    LOCAL loFont AS xfcFont
    m.loFont = .FONT.New("Tahoma", 11, .FontStyle.Regular)

    * Create a StringFormat object
    LOCAL loStringFormat AS xfcStringFormat
    m.loStringFormat = .StringFormat.New()

    LOCAL lnHeight, lnWidth
    m.lnWidth  = 400
    m.lnHeight = 150

    * Draw Left Aligned Text
    m.loStringFormat.ALIGNMENT = .StringAlignment.NEAR
    m.loGfx.DrawString(m.lcText, m.loFont, m.loTextBrush, ;
          .Rectangle.New(0, 0, m.lnWidth, m.lnHeight), ;

    * Draw Centered Text
    m.loStringFormat.ALIGNMENT = .StringAlignment.CENTER
    m.loGfx.DrawString(m.lcText, m.loFont, m.loTextBrush, ;
          .Rectangle.New(0, m.lnHeight + 1, m.lnWidth, m.lnHeight), ;

    * Draw Right Aligned Text
    m.loStringFormat.ALIGNMENT = .StringAlignment.Far
    m.loGfx.DrawString(m.lcText, m.loFont, m.loTextBrush, ;
          .Rectangle.New(0, m.lnHeight * 2 + 1, m.lnWidth, m.lnHeight), ;

    * Draw Full Justified
    m.loGfx.DrawStringJustified(m.lcText, m.loFont, m.loTextBrush, ;
          .Rectangle.New(0, m.lnHeight * 3 + 1, m.lnWidth, m.lnHeight))

    * Draw a Red Border
    m.loGfx.DrawRectangle(.PEN.New(.COLOR.Red, 1), 0, 0, 399, 599)

    * Save Image to Disk
    m.loBMP.SAVE("c:\TestAlignment.png", .Imaging.ImageFormat.Png)

    * Show Generated Text
    RUN /N explorer.EXE c:\TestAlignment.Png


2 - Draw Full-Justified strings in Forms

The easiest way to draw a Full-Justified string in a form is using the ImageCanvas object. Below is the code that you need to add to the "BeforeDraw" method if the ImgCanvas. In my previous post, Direct Draw with the Image Canvas from GdiPlus-X you'll get a tutorial showing how to work with it, and some tips.

Note that I chose to reduce the code of the GDI+ drawing part, to show that with only two lines of code you can draw your Full-Justified string with the image canvas.

GDIPlusX is a set of VFP 9.0 class libraries that wrap the 603 GDI+ Flat API functions of GDIPlus.dll.
The library currently consist of 83 VFP classes and 1,146 methods. The project is still under development so not all classes have been completed and several of the classes/methods are still being tested. The Readme.htm file, included with the download, shows the current coding status of each class. As of August 31, 2006, the overall status of the library is about 97% coded and 60% tested.

    * Fill Image with Background color

    * Draw the Full-Justified text
    THIS.oGfx.DrawStringJustified(m.lcText, .FONT.New("Tahoma", 12), ;
          .Brushes.Black, THIS.Rectangle)

In the samples folder of the GdiPlus-X libary you'll find the form "FULLJUSTIFIED.SCX". Don't miss to run it, and play, changing the fonts, sizes, style, alignment type. But, in my opinion the most interesting feature of that sample is that you can resize the form, and the whole image will be redrawn in a flash ! Doing that you'll see how fast this routine works.


3 - Draw Full-Justified strings in reports.

This has become very easy too, after the creation of a specific report listener... but I prefer to leave this for my next post.


Maybe you have interest in the DRAWSTRINGJUSTIFIED method. To see the code, open the class xfcGraphics from the file Drawing.vcx. Look for the method "DrawStringJustified".


FoxyPreviewer – HTML like formatting!

FoxyPreviewer brings another cool facility, that allows you to draw your texts in the report surface (and export it) having control on each word. Forget those old workarounds, generating images to draw some texts in your reports or even embedding RTF controls in your reports !

This brings a super cool new feature, allowing you to add some basic HTML texts to your fields. This means that you can from now on determine how EACH WORD in your field should be formatted!
See the image below, all the text is in ONE SINGLE FIELD !

How to do it ?
Very very simple:
  1. Open your report, in Edit mode
  2. Double-click the field that you want to add the tagged formatting. This will open the field properties dialog
  3. Click on the "Other" tab
  4. Click on the "Edit user data..." button
  5. Add the string "<TF>" as shown in the picture below:

And just add the HTML code below to that field:

The search capabilities are kept, and exporting to PDF returns an excellent output as well.
Here is the list of the available TAGS that you can use:

Feature Opening Tag Closing Tag
bold <b> </b>
italic <i> </i>
underline <u> </u>
strikethru <s> </s>
text color <color=rgb/ncolor >
<c= >
text backcolor <highlight=rgb/ncolor>
</backcolor>    && in FP v3
font name <fontname=”name”>
font size <fontsize=n>
whole font style <fontstyle=”BIUS”>
force new line (CRLF) <br>
CHR(13) + CHR(10)
NB: color could be stored a number with RGB()
NB: could prevent transform if '</' not in string

Special thanks to Eduard Alexandru, from Bucarest, Romania, for his essential help in this feature, help in discussions and for providing some procedures to deal with the tagged texts.
This feature still needs some tests. It is possible that you find some tags that are not being considered, please me!
Check the sample SAMPLE_TF.FRX in the latest FoxyPreviewer release to play with the new features.


FoxyPreviewer email configurations

FoxyPreviewer brings 4 ways for you to send emails:

1 – MAPI - Uses the WinAPI MapiSendMail to try to send the current report as an attachment.
This setting sends a standard message, with one or more attached files and a cover note. The cover note is a dialog box that allows the user to enter a list of recipients and an optional message and other sending options. It will open a dialog email sending message, waiting for a user interaction. The message will not be sent automatically. It’s up to the user to veryfy the information ofthe message and to click at the “Send” button. 
This function tries to establish a session using the messaging system's shared session. If no shared session exists, it will fail sending the message.
This works pretty well if you have your default account set using MS Outlook Express, MS Outlook or Windows Live Mail. Definitely, it’s the easiest way to send your messages, because this way, FoxyPreviewer will use the default Email configuration of the computer.

2 - MAPI Alternative – Uses the WinAPI MapiSendDocuments to try to send the current report as an attachment.
The MAPISendDocuments function sends a standard message with one or more attached files and a cover note. The cover note is a dialog box that allows the user to enter a list of recipients and an optional message and other sending options.
This function tries to establish a session using the messaging system's shared session. If no shared session exists, it will fail sending the message.
This works pretty well if you have your default account set using MS Outlook Express, MS Outlook or Windows Live Mail. Definitely, it’s the easiest way to send your messages, because this way, FoxyPreviewer will use the default Email configuration of the computer.
Although MS says that “The use of this function is discouraged. It may be altered or unavailable in subsequent versions of Windows.”, it’s been working well in all OS’s, from WinNT to WinSeven

3 – Custom Procedure
You can use your own procedure to send the current report. use foxypreviewer property "cEmailPrg", and fill it with the name of the prg responsible for sending emails. This PRG receives as a parameter the file name of the file created that you will send as attachment. Have a look at the samples provided, the file mysendmail.prg shows how you would need to make your custom procedure.

4 – CDO
Uses the CDO2000 component included in windows 2000 and later. It allows you to send emails using a SMTP server. All settings must be accurate in order to make this work. For example, below is the configuration for a “Hotmail” or “Live” account to send emails. You may check also in Sergey Berezniker's blog for more information on how to send using MSN, YAHOO or GMAIL email messages using CDO: http://www.berezniker.com/category/topic/email

People always send messages in forums asking how they should make these configurations. In fact, they change from server to server, the best you can do is to check the Email server that you are using, and get the right configurations for SMTP Server, SMTP Port and SSL Connection.
Thanks to MK Sharma, from Foxite, I found this link, that brings some SMTP general information about several servers: http://mynokiamobile.blogspot.in/2008/01/smtp-pop3port-settings-for.html
And here is a list of servers with some common configurations for people who use Brazilian servers:

Please note that I did not test any of the settings below, please make your tests!

Server SMTP adress Port(s) Use SSL
25 or 465
465 or 25
UOL smtps.uol.com.br 587 or 465 TRUE


FoxyPreviewer v2.96 updates

Updates for FoxyPreviewer v2.96

This release brings a new cool feature, allowing you to print the same report twice in the same page.
In several cases we need to print some receipts in 2 copies. Normally these reports are small, using only half the page. If you have this situation, now you can set just one property, and FoxyPreviewer will repeat the current report in the same page, starting from the half vertical part of the page.

Currently works only when you run the report in the preview.
In the preview window, the report will look as original. The 2nd copy will be printed in the same page only when you click the "Print" button in the toolbar or Context menu.

Make your tests, running any of your reports.

Works only in Simplified mode !

_Screen.oFoxyPreviewer.lRepeatInPage = .T.

Apart from this, some other minor fixes:

  • Fix in 'lExpandFields' property, now allowing exporting the "*" values correctly in PDF, XLS, RTF and HTML

  • Fix in the Preview form release, sometimes was raising file not found error on closing.