Monday, September 29, 2008
Visual FoxPro 9.0 SP2 or not... Post 5

Well it has been so long since my last post, I almost forgot how to login...

I have been super busy the past few months, but I have been researching bugs and working on the Reporting APPs on VFPX when I can. I have some info I would like to post to try and get back into the swing of things, these are all related to reporting bugs, that have been reported as SP2 bugs on the Visual FoxPro WIKI SP2 Bug List.

Issue: SP2 broke data group headers repeated on subsequent pages
Submitted By: Cathy Pountney
New to SP2: Yes
Impact for SP2: Med-High
Feedback ID: 312568
Solution Available: No
Workaround Available: Yes
Bug Location: VFP9 Core

This is one of the few true bugs that was introduced in VFP 9.0 SP2 core product. The bug was introduced when another reporting issue was addressed: "Group headers don't always print on a new page" per SP2 Bug Fix List. The original issue occurred under the following circumstances:

  1. Your report had a Group Header with "Reprint group header on each page" activated
  2. The last detail band in the Group finished at the bottom of the page with not enough room to print the Group Footer band
  3. The Group Footer band was printed at the top of the next page, without the Group Header

SP2 was changed to force the Group Header to appear on the new page, above the Group Footer. However, the record pointer is on the wrong record when the Group Header is rendered. If you have any fields in the Group Header that reference fields in the underlying report alias, they will render the data from the next record and not the record you are expecting.

Cathy Pountney was the first to report this issue and she painstakingly documented it in her Blog. She even provides a possible workaround. I don't want to duplicate her efforts here. I highly recommend you follow the links to her blog for more details. What I would like to do here is to offer an alternative workaround for the issue. This is very similar to Cathy's solution, but it may be a little easier to manage since it doesn't require duplicate fields.

Since the problem only affects fields in the Group Header that reference values in the underlying Report cursor. You can convert any of those fields to reference variables instead. Then tie the variables to the underlying cursor fields.

Add a report variable for each field in the Group Header.

Change the Group Header field to reference the report variable.

This sample report has both references in the Group Header. The Variable has the correct value. The Field contains the value from the next record.

NOTE: This issue also occurs when using the new Detail Header band feature with the "Reprint Detail header on each page" feature. If you have any field references in the Detail Header band, those will need to be changed to report variables also.

Another point I would like to make here is that because this issue is in the VFP 9.0 SP2 core engine, you cannot bypass it using SET REPORTBEHAVIOR 80. The issue occurs using the old and new report engine.

There is a rumor that Microsoft may be working on a fix for this issue. But I'm not one to spread rumors. I have been working on a technique to try and get around this issue by using the ReportListener. I'll keep you posted on the progress.

Should this stop you from upgrading to SP2? Maybe. Only if you have a ton of reports that use the "Print group header on each page" feature with field values in the Group Header and you don't want to update them all.

 

Issue: Print When logic is evaluated at the wrong time in VFP Reports
Submitted By: Cathy Pountney
New to SP2: No
Impact for SP2: Low to Med
Feedback ID: 293615
Solution Available: No
Workaround Available: Yes
Bug Location: VFP9 Core

This bug is not new to SP2, it has been there since VFP 9.0 RTM. The problem occurs when you have a "Print When" expression on a report control in the Detail Footer band. The "Print When" expression is evaluated while on the next record. This is similar to the problem above, except the evaluation error is happening only on the Print When expression of the Detail Footer band.

The workaround is similar. If your Print When expression is based on a field value, create a new report variable and set the variable to the field value. Then replace the field value in your Print When expression with the report variable.

This was a good catch by Cathy. But this should not prevent you from upgrading to SP2. This issue is new to VFP 9.0 (because Detail Footer bands were introduced in 9.0) but it is not a new issue to VFP 9.0 SP2.

This issue occurs whether you are using SET REPORTBEHAVIOR 80 or 90. Hopefully Microsoft will fix this issue in the near future. If I can find a ReportListener solution I will let you know.

 

Issue: VFP SYS(1037) no longer has a PRINTER button in Vista
Submitted By: Cathy Pountney
New to SP2: No
Impact for SP2: None
Feedback ID: 286313
Solution Available: Yes
Workaround Available: N/A
Bug Location: N/A

The issue here is that the "Page Setup" dialog no longer has a "Printer..." button on it when using Vista. This is evident from calling the SYS(1037) function or choosing "Page Setup" from the "File" menu.

This issue is not an SP2 nor a VFP 9.0 issue. This was a behavior change in Vista. I haven't found any "Official" documentation from Microsoft, highlighting this change, but I did find a post on MSDN forums by a Microsoft employee. His post references a change to the Windows API in Vista. The PAGESETUPDLG structure used by the PageSetupDlg function now shows the PSD_DISABLEPRINTER flag as "Obsolete". This means that any application that utilizes the PageSetupDlg function no longer has a "Printer" button in Vista.

The reason given in the forums was that it was not safe to change the printer from the "Page Setup" dialog because there could be printer specific information in the dialog. The suggested workaround is to use the "Print" dialog to change printers or change advanced printer settings.

To do this interactively in VFP you can choose "Print..." from the "File" menu. Change your printer, set your advanced printer options and then click "Apply". Then choose "Cancel" to close the dialog. Whatever options you choose, prior to clicking the "Apply" button, are now your default printer settings for the current VFP session. (Verify using SET("Printer",3) ). You can use SYS(1500,"_MFI_SYSPRINT","_MFILE") to activate the "Print" dialog programmatically. However, this is problematic for 2 reasons.

  1. If you accidentally click "Print" instead of cancel, you have just sent the active window to the printer. Whatever the active window happened to be, whether it was a 200 page report or a 2,000 line PRG.
  2. The "Print..." menu option may not always be enabled, depending on the active window. And if you can't choose it from the menu, then the programmatic SYS(1500) isn't going to work either.

One area where this becomes problematic for VFP is when using the Report Properties dialog from the Report designer. The "Page Setup..." button used to be how you could choose the printer you wanted to use for your report. Now you can only change the paper size and orientation.

If you don't have "Printer Environment" enabled, this is probabaly good enough. Paper size and orientation is about all that gets saved anyway. The only thing missing is the Color preference.

If you do need to specify color or you want to save a particular printer environment, you have to close the "Report Properties" dialog, choose "Print..." from the "File" menu, select your printer and set the advanced properties, click the "Apply" button and then click the "Cancel" button to close the "Print" dialog. Now you can reopen your "Report Properties" dialog and your selected printer settings will be shown. These settings will also be saved with the report if you enable "Printer Environment" from the "Report" menu.

Should this stop you from upgrading to SP2? No. This is not an SP2 bug. It is a behavior change in Vista and affects all versions of VFP.

FYI, I'm working on a way to provide the missing functionality to the "Report Properties" dialog and make it part of the REPORTBUILDER.APP. If you would like to provide similar functionality in your apps, here is some sample code to get you started. This displays the "Advanced Printer Properties" dialog for the currently selected printer:

#DEFINE DM_OUT_BUFFER  2

#DEFINE DM_IN_PROMPT   4

#DEFINE CCHDEVICENAME 32

#DEFINE CCHFORMNAME   32

 

LOCAL lcPrinter   && Printer name

LOCAL lhPrinter   && Printer handle

LOCAL lnSize      && DEVMODE buffer size

LOCAL lhDevmode   && Handle to DEVMODE structure

LOCAL lnStauts

 

DoDeclare()

 

lcPrinter = SET("Printer",3)

lhPrinter = 0

 

IF OpenPrinter(lcPrinter+0h00, @lhPrinter, NULL) = 0

    ? "Error opening printer [" + lcPrinter + "]"

    RETURN

ENDIF

 

** DocumentProperties: http://msdn2.microsoft.com/en-us/library/ms535735.aspx

lnBuffSize = DocumentProperties(_VFP.hWnd, lhPrinter, lcPrinter, 0, 0, 0)

lhDevmode = LocalAlloc(0x00,lnBuffSize)

lnStatus = DocumentProperties(_VFP.hWnd, lhPrinter, lcPrinter, lhDevmode, 0, DM_OUT_BUFFER+DM_IN_PROMPT)

 

IF lnStatus = 1      && Success

   ** DEVMODE: http://msdn2.microsoft.com/en-us/library/ms535771.aspx

   ?"Orientation: ",   CTOBIN(SYS(2600,lhDevMode+44,2),"2rs")

   ?"Paper Size: ",   CTOBIN(SYS(2600,lhDevMode+46,2),"2rs")

   ?"Paper Length: ",   CTOBIN(SYS(2600,lhDevMode+48,2),"2rs")

   ?"Paper Width: ",   CTOBIN(SYS(2600,lhDevMode+50,2),"2rs")

   ?"Paper Scale: ",   CTOBIN(SYS(2600,lhDevMode+52,2),"2rs")

   ?"Paper Copies: ",   CTOBIN(SYS(2600,lhDevMode+54,2),"2rs")

   ?"Default Source: ",CTOBIN(SYS(2600,lhDevMode+56,2),"2rs")

   ?"Print Qualilty: ",CTOBIN(SYS(2600,lhDevMode+58,2),"2rs")

   ?"Color: ",         CTOBIN(SYS(2600,lhDevMode+60,2),"2rs")

   ?"Duplex: ",      CTOBIN(SYS(2600,lhDevMode+62,2),"2rs")

   ?"Y Resolution: ",   CTOBIN(SYS(2600,lhDevMode+64,2),"2rs")

   ?"TT Option: ",      CTOBIN(SYS(2600,lhDevMode+66,2),"2rs")

   ?"Collate: ",      CTOBIN(SYS(2600,lhDevMode+68,2),"2rs")

  

   lcFormName = SYS(2600,lhDevMode+70,CCHFORMNAME)

   lcFormName = ""+LEFT(lcFormName, AT(0h00,lcFormName)-1)

   ?"Form Name: ",      lcFormName

  

   ?"LogPixels: ",      CTOBIN(SYS(2600,lhDevMode+102,2),"2rs")

   ?"BitsPerPixel: ",   CTOBIN(SYS(2600,lhDevMode+104,2),"2rs")

   ?

ELSE

   ? "Error getting print properties"

ENDIF

 

ClosePrinter(lhPrinter)

LocalFree(lhDevmode)

 

 

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

FUNCTION DoDeclare()

 

   DECLARE INTEGER OpenPrinter IN winspool.drv;

       STRING pPrinterName, INTEGER @phPrinter, STRING pDefault

 

   DECLARE INTEGER ClosePrinter IN winspool.drv INTEGER hPrinter

          

   DECLARE INTEGER DocumentProperties IN winspool.drv;

       INTEGER   hWnd,;

       INTEGER   hPrinter,;

       STRING    pDeviceName,;

       LONG     pDevModeOutput,;

       LONG     pDevModeInput,;

       INTEGER   fMode

      

   DECLARE LONG LocalAlloc IN WIN32API ;

      LONG uFlags, LONG uBytes

     

   DECLARE LONG LocalFree IN WIN32API ;

      LONG HMEM

ENDFUNC

I hope to post some more SP2 entries over the next few days.


Monday, September 29, 2008 6:54:09 AM (Eastern Daylight Time, UTC-04:00)  #     Comments [8]   | Tracked by:
"Visual FoxPro 9.0" (Termékinformációk fejlesztőknek) [Trackback]


Monday, September 29, 2008 11:30:14 AM (Eastern Daylight Time, UTC-04:00)
Great to see you blogging again Bo. Very detailed explanations and helpful as always. Thanks for the example using DocumentProperties and the devmode structure breakdown.
Wednesday, May 20, 2009 4:04:02 PM (Eastern Daylight Time, UTC-04:00)
Hi everyone. Enjoyed browsing through the site. Keep up the good work. Help me! It has to find sites on the: drug addiction treatment. I found only this - <a href="http://design.ru-deluxe.ru/">photo shop uroki</a>. Residential drug and alcohol addiction treatment for men in lawrenceville, georgia from purple, Treatment for alcohol poisoning can be a stark punishment alcoholism treatment. With respect :confused:, Cala from Ukraine.
Saturday, May 23, 2009 3:00:24 PM (Eastern Daylight Time, UTC-04:00)
Excuse me. Humor is also a way of saying something serious. Help me! I can not find sites on the: Turbo Tax. I found only this - <a href="http://turbo-tax.biz">turbo tax</a>. Alcohol addiction information you need in discovery health addiction help and treatment statistics on the effects of alcohol and drug abuse. Welcome to the home page of the alcohol withdrawal treatment manual. Thank :confused: Meryle from Bosnia.
Sunday, February 07, 2010 12:57:51 PM (Eastern Standard Time, UTC-05:00)
Hi Bo,

The code sample for the printer properties dialog is very nice, but I cant see how I could send a report using the configuration that a user makes using it, because after we close the dialog, no settings are saved.

Is there a way to store the info extracted from the dialog in the user preferences, so that the reports to be printed will automatically use these configurations ?

Thanks in advance for any insight !

Regards

Cesar
Monday, February 08, 2010 10:07:59 AM (Eastern Standard Time, UTC-05:00)
Hello again,
I found a very nice solution from Barbara Peisch.
For people interested in solving this annoyance in Vista, just run the script below that I adapted from a sample posted by her in the Foxite forums:

*********************************************************************
FUNCTION SetPrinterProps
*********************************************************************
* Code from Barbara Peisch, adapted by VFPImaging
* Allows changing the current priner settings
* Using the Printer perferences dialog
* http://www.foxite.com/archives/0000158197.htm

* Lets the user set all possible printer properties
LOCAL lcRptFile, lhWindow, lcOrigDevMode, lcModifiedDevMode, lcPrinter, lhPrinter

* These constants come from the Windows.h file
#DEFINE IDOK 1
#DEFINE IDCANCEL 2

#DEFINE DM_OUT_BUFFER 2
#DEFINE DM_IN_BUFFER 8
#DEFINE DM_IN_PROMPT 4

DECLARE INTEGER OpenPrinter IN winspool.drv ;
STRING pPrinterName, ;
INTEGER @phPrinter, ;
INTEGER pDefault

DECLARE INTEGER GetActiveWindow IN user32

DECLARE INTEGER DocumentProperties IN winspool.drv ;
INTEGER hWnd, ;
INTEGER hPrinter, ;
STRING pDeviceName, ;
STRING @pDevModeOutput, ;
STRING @pDevModeInput, ;
INTEGER fMode

DECLARE INTEGER ClosePrinter IN winspool.drv INTEGER hPrinter

lcPrinter = SET("Printer", 3)
IF NOT EMPTY(lcPrinter)
lhWindow = GetActiveWindow()

lhPrinter = 0
OpenPrinter(lcPrinter, @lhPrinter, 0)
IF lhPrinter = 0
Messagebox("Could not open printer.", 48, "Error")
RETURN
ENDIF

lcRptFile = SYS(2015)+".FRX"

TRY
* Use a unique file name so we can use this in a multi-user situation
* Using a cursor instead of a physical file doesn't work, but we can
* create the FRX from a cursor.
CREATE CURSOR TempCur (Temp C (10))
CREATE REPORT (JUSTSTEM(lcRptFile)) FROM TempCur
USE IN TempCur
USE (lcRptFile) EXCLUSIVE ALIAS RptFile

* Use SYS(1037,2) to read the printer settings instead of DocumentProperties
SYS(1037,2)

* We only want to save the original settings the first time
lcOldExpr = EXPR
lcOldTag = TAG
lcOldTag2 = TAG2
lcOrigDevMode = TAG2
lcDevMode = TAG2
lcModifiedDevMode = TAG2

* Show printer settings dialog.
lnResult = DocumentProperties(lhWindow, lhPrinter, lcPrinter, @lcModifiedDevMode, @lcOrigDevMode, DM_IN_PROMPT+DM_IN_BUFFER+DM_OUT_BUFFER)

IF lnResult <> IDCANCEL
* Set the printer to the new options
SELECT RptFile
replace expr WITH '', ;
tag WITH '', ;
TAG2 WITH lcModifiedDevMode
lcDevMode = lcModifiedDevMode
SYS(1037,3) && Writes the printer settings out to the printer
ENDIF
CATCH TO loException
FINALLY
SET STEP ON
* Get rid of the temporary FRX
IF USED("RptFile")
USE IN RptFile
ENDIF
IF FILE(lcRptFile)
ERASE (JUSTSTEM(lcRptFile)+".*")
ENDIF

* Close the printer handle
IF NOT EMPTY(lhPrinter)
ClosePrinter(lhPrinter)
ENDIF
ENDTRY
ENDIF

RETURN
Thursday, February 11, 2010 11:08:18 AM (Eastern Standard Time, UTC-05:00)
Thanks for sharing this, the more bugs we know about the easier our jobs become
Friday, February 26, 2010 1:33:05 PM (Eastern Standard Time, UTC-05:00)
Sealy Beds and mattresses have been developed to deliver optimum comfort. Sealy delivers a range of beds and mattresses to suit your every desire

Wednesday, June 16, 2010 11:46:07 AM (Eastern Daylight Time, UTC-04:00)
Doctors (General Practitioners) in Washington, DC, See Reviews and Book Online Instantly.  All appointment times are guaranteed by our dentists and doctors.
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: )  

Enter the code shown (prevents robots):