Wednesday, February 22, 2017

What Do You Want to Learn in 2017?

We're getting close to releasing the Call for Speakers for the 2017 conferences; be sure to watch the News page for the announcement. Our blog post offers prospective speakers ideas for topics taken from suggestions from previous years' attendees. There are a lot of cool topics there so "I can't think of anything to present" isn't a valid excuse for not submitting your proposals to speak this year.

Thursday, December 22, 2016

New White Papers for 2016

I added a half-dozen new white papers to my web site, all from sessions or articles I wrote in 2015: http://doughennig.com/papers/default.html. I also added the date the paper was originally written or presented and where.

The new ones are:

  • Win32API for VFP Developers: The Windows API (Win32API) contains thousands of useful functions. However, finding which function to use when, and how to call it from a VFP application, can be challenging. This document discusses how API functions are called in VFP, where to find information on the API, and presents lots of useful API functions you can call in your VFP applications today. (This is an updated version of an earlier white paper).
  • Scheduling Tasks: Automatically executing a task on a regular schedule isn't something every application needs to do, but if you do need it, this document provides the code you need to do this from VFP.
  • 50 Shades of Grey: Whipping Your Application's UI into Shape: There's no excuse for creating a boring looking VFP application. Using some of the controls available today, you can create a new, modern user interface for your forms that'll add years to the life of your applications. With a few days of effort, your apps can be as pretty as anything out there. This document looks at several new controls that allow you to freshen your user interface and wash out the grey.
  • Creating a Plug-in Architecture for Your Applications: Adding support for plug-ins to your applications has a lot of benefits: users can extend or alter the functionality of the application, you can deploy new features without installing a new build, and you can create customer-specific versions of an application without endless sets of CASE statements. This document looks at how adding plug-in support can help your applications and looks at several techniques that can be used independently or together.
  • New UI Classes From Carlos Alloatti: Carlos Alloatti is a prolific developer of classes that can make your application's user interface sparkle. In this document, Doug looks at a couple of new libraries Carlos created that can replace the VFP Toolbar and provide a tabbed document interface to your applications.
  • Add Gauges to Your Applications: They say a picture is worth a thousand words. That's especially true with a gauge control, which allows a user to see at a glance how some value compares to a goal amount. In this document, Doug presents an easy-to-use gauge control you can use in your VFP applications. 

Friday, September 30, 2016

Announcements from Southwest Fox 2016

Southwest Fox was once again a great success. Attendance was down only two people from the previous year, and since attendance seems to go in two-year cycles, that bodes well for next year.

Here are some announcements made at the conference:

  • Southwest Fox 2017 will be held October 26 – 29 at the SanTan Elegante Conference Center in Gilbert, AZ (not in Canada, as I joked in the closing session, because 50% of American attendees will be moving there after the elections in November).
  • The 2016 VFPX Administrator’s Award went to Marco Plaza for his work on nfJSON, nfXML, and nfRegExpTest.
  • The 2015 Speaker Award went to Bobby Spyros Drakos (an Xbase++ speaker).
  • You can watch the first part of the keynote at SWFoxTV and Phil Sherwood's "You 2.0" keynote on YouTube: Part 1, Part 2, and Part 3 (unfortunately, the audio isn't very good).

Wednesday, September 07, 2016

DBI Offers New Control to Southwest Fox/Xbase++ Attendees

DBI is giving away a full license of Calendar COM (ctxCalendar) to each Southwest Fox/Southwest Xbase++ 2016 attendee. Calendar COM is a really great Outlook style scheduling control with three fully extensible views baked into one control: a multi-column Day View (a multiple day appointment scheduler for one resource or multiple resource appointment scheduler for one day at a time), a Week View Appointment Scheduler, and a Month Calendar / date picker. It comes in both 32-bit and 64-bit versions.

DBI has been a long-time supporter of Southwest Fox and we thank them for their generous support once again this year!

Tuesday, August 23, 2016

Rendering a Report Image in the Foreground

A feature I’d forgotten about in the VFP 9 reporting enhancements is the ability to absolutely position objects. As Cathy Pountney discusses in What's New in the Visual FoxPro 9.0 Report Writer, you can use this feature to add a watermark to a report. One problem, though, is that regardless of how you arrange objects using Sent to Back or Bring to Front, the image always appears in the background of the report. What if you want it to appear in the foreground (that is, on top of the detail band objects)?

A little-used reporting enhancement to the rescue. FX and GFX objects extend a report listener by hooking into the various events, allowing you to change the behavior of the report run. These objects can be of any base class, as long as they have an ApplyFX method that accepts certain parameters, but it’s easier to subclass FXAbstract in _ReportListeners.vcx in the FFC folder. The difference between an FX and a GFX object isn’t in the class definition; it’s just that the report listener pays attention to the return value of a GFX object’s ApplyFX method, whereas it doesn’t for an FX object. To add an FX or GFX object to a listener, use:

loListener.AddCollectionMember(Class, Library, APP or EXE, .T. for singleton, .T. for GFX or .F. for FX)

I created a subclass of FXAbstract that does the following:

  • When the report run starts (tcMethodToken is “BEFOREREPORT”), create an array of Empty objects, one for each image in the FRX file that has “FOREGROUND” in its Comment property (the record number of the image in the FRX is used as the index for the object in the array).
  • When such an image is rendered (tcMethodToken is “RENDER”), save its rendering information (left, top, height, width, etc.) to the corresponding Empty object in the array and tell the listener to not render the image by returning 2.
  • When the page footer band is entered (tcMethodToken is “BEFOREBAND” and the first of the variable parameters is 7), tell the listener to render each of the images. Because they’re being drawn after the detail band text, they’ll appear on top of the text.

Here’s the code for the class:

define class SFFXRenderInForeground as FXAbstract of home() + ;

     'FFC\_ReportListener.vcx'
    dimension aForeground[1]
        && an array of rendering information
    lSelfCall = .F.
        && .T. if we're being called from ourselves (we call Render which calls
        && us)
   
    function ApplyFX(toListener, ;
        tcMethodToken, ;
        tP1, ;
        tP2, ;
        tP3, ;
        tP4, ;
        tP5, ;
        tP6, ;
        tP7, ;
        tP8, ;
        tP9, ;
        tP10, ;
        tP11, ;
        tP12)
        local lnReturn, ;
            lnSession, ;
            lnSelect, ;
            lnCurrRecno, ;
            lnRecno, ;
            lnI, ;
            loForeground
        lnReturn = 0 && OUTPUTFX_BASERENDER_AFTERRESTORE
        do case

* Before the report runs, create an array of information about objects we'll
* process.

             case tcMethodToken = 'BEFOREREPORT'
                lnSession = set('DATASESSION')
                if toListener.FRXDataSession > -1
                    set datasession to toListener.FRXDataSession
                endif toListener.FRXDataSession > -1
                lnSelect = select()
                select FRX
                lnCurrRecno = recno()
                scan for 'FOREGROUND' $ upper(COMMENT)
                    lnRecno = recno()
                    dimension This.aForeground[lnRecno]
                    This.aForeground[lnRecno] = createobject('Empty')
                endscan for 'FOREGROUND' $ upper(COMMENT)
                if between(lnCurrRecno, 1, reccount())
                    go lnCurrRecno
                endif between(lnCurrRecno, 1, reccount())
                select (lnSelect)
                set datasession to lnSession

* If we're rendering an object that's supposed to be in the foreground, save
* the rendering information.

            case not This.lSelfCall and tcMethodToken = 'RENDER' and ;
                vartype(This.aForeground[tP1]) = 'O'
                loForeground = This.aForeground[tP1]
                addproperty(loForeground, 'FRXRecno', tP1)
                addproperty(loForeground, 'Left',     tP2)
                addproperty(loForeground, 'Top',      tP3)
                addproperty(loForeground, 'Width',    tP4)
                addproperty(loForeground, 'Height',   tP5)
                addproperty(loForeground, 'ContType', tP6)
                addproperty(loForeground, 'Contents', tP7)
                addproperty(loForeground, 'Image',    tP8)
                lnReturn = 2 && OUTPUTFX_BASERENDER_NORENDER

* If we're about to do the page footer band, render all foreground objects.

             case tcMethodToken = 'BEFOREBAND' and tP1 = 7
                 && FRX_OBJCOD_PAGEFOOTER
                for lnI = 1 to alen(This.aForeground)
                    loForeground = This.aForeground[lnI]
                    if vartype(loForeground) = 'O'
                        This.lSelfCall = .T.
                        toListener.Render(loForeground.FRXRecno, loForeground.Left, ;
                            loForeground.Top, loForeground.Width, loForeground.Height, ;
                            loForeground.ContType, loForeground.Contents, ;
                            loForeground.Image)
                        This.lSelfCall = .F.
                    endif vartype(loForeground) = 'O'
                next lnI
        endcase
        return lnReturn
    endfunc
enddefine

The following code tests the GFX object by running a report with and without it.

open database _samples + 'Data\TestData'

loListener = newobject('FXListener', home() + 'FFC\_ReportListener.vcx')
loListener.ListenerType = 1 && LISTENER_TYPE_PRV
report form Foreground object loListener
loListener.AddCollectionMember('SFFXRenderInForeground', ;
    'SFFXRenderInForeground.prg', '', .T., .T.)
report form Foreground object loListener

Here’s what the report looks like without the GFX object:

Background

You can see the image is drawn under the text. Here’s the report when the GFX object is used:

Foreground

Notice the image now appears on top of the text.

You can download the source and sample files for this from the Technical Papers page of my personal web site, http://doughennig.com/papers/default.html (look for “Rendering a Report Image in the Foreground”).

Monday, August 22, 2016

The FoxShow #81 is now available

Listen to Andrew MacNeill interview Tamar Granor and me about Southwest Fox and Southwest Xbase++ 2016 on the FoxShow #81. There's a special offer for FoxShow listeners until September 2. http://www.thefoxshow.com/

Wednesday, July 27, 2016

Southwest Fox 2016: Early-bird deadline approaches

Simple quick reminder: save $50 by registering before the Early-bird registration deadline this Sunday, July 31st.

If you still need to register, please head over to the registration Web site today: http://geekgatherings.com/Registration

Every registered attendee gets admission and white papers to all regular conference sessions. Don't miss this chance to learn from the best and mix with your peers.

It’s still only July and we already have nearly $15,000 in raffle prizes, with more yet to come.

See you in September!