Tuesday, March 04, 2008
Visual FoxPro 9.0 SP2 or not... Post 2

Something I didn't emphasize in my previous post, but Craig Boyd reminded me in his comments, is that many of the issues people faced with SP2 could be traced back to a problem with the installation. Not with the actual SP2 release itself.

To ensure a clean install of SP2, you MUST start from scratch. This includes uninstalling and reinstalling VFP9 RTM. You don’t have to install SP1 before SP2, but if you want to go back to SP1 or have SP1 available for testing, I highly recommend you get Rick Schummer’s white paper with instructions on installing both versions on the same machine.

Ok, so working with the SP2 Bug List from the Visual FoxPro Wiki, I’ll start from the top down:

Issue: Toolbar in Report Preview not working with VFP SP2
Submitted By: Bernard Bout and Peter de Valenca
New to SP2: No. However it was reportedly fixed in SP1 and now it’s back.
Impact for SP2: Low to Medium
Feedback ID: 306390
Solution Available: No
Workaround Available: Yes
Bug Location: VFP9 Core

This is one of the bugs that gets blamed on the new VFP9 reporting features. However, this is NOT a bug with the new reporting. It is however exposed by the new reporting. It occurs when you have a modal form, inside of a top level form along with a toolbar. The toolbar becomes unavailable. Why was it fixed in SP1 and now its back? I’m guessing that the change made to SP1 to address the issue may have broken something else and they had to roll it back.

Some background information; I was fortunate enough to make it to the February Detroit FoxPro User Group Meeting, in which Christof Wollenhaupt gave a marathon, 3 hour session on “The Dark Side of Visual FoxPro”. One of the things he covered was a solution for the VFP bug when using ActiveX controls with modal windows. He has some information available in a blog entry. I never realized this but “modal windows do not exist in the Windows API”. According to Christof, Windows creates a modal state by disabling the parent window. This explains why you cannot have a “top level” form in VFP that is also “modal” (.ShowWindow = 2). If it is a top level form, you don't have a parent to disable.

This also explains what is probably happening when you put a modal form, inside of a top level form along with a toolbar. Either the toolbar is getting disabled or VFP is just not responding to the toolbar’s events. This is really no different than issuing a MESSAGEBOX call and expecting to be able to click on the VFP toolbar. You can’t do it….by design.

So is this really a bug? Why would you want to put a modal window inside of a top level form and expect the toolbar to work? Well, because it’s a hack on a hack trying to emulate a popular technique used in VFP8 and earlier. If we wanted to preview a report, in a top level form, we could issue a “REPORT FORM PREVIEW IN WINDOW” command where the IN WINDOW clause specified a top level form. And if we left off the NOWAIT clause, this would display our report preview in a modal condition.

So what is different in VFP9 reporting? The main difference is now we have the ability to make our own custom report previewers using the ReportListener class along with real VFP forms and objects. The window we get with a VFP Form does not behave the same as the window we get when we issue “REPORT FORM PREVIEW” in VFP8. The old report preview window was handled internally by VFP. We had no control over how it was being managed or painted behind the scenes. We also have no control over how it handled its modal condition. But the biggest difference may be how it managed the toolbar. The toolbar seemed to belong to the preview window whereas in VFP9 reporting (and other VFP form uses) the toolbar belongs to the top level form.

Just to recap, this issue ONLY occurs when ALL of the following conditions are true:

1) You are using the new reporting features of VFP9 (SET REPORTBEHAVIOR 90)
2) You are displaying the report preview window in a top level form by using the WINDOW clause of the REPORT FORM PREVIEW command
3) You create a modal condition by not using the NOWAIT clause in your REPORT FORM PREVIEW command

Here is a snippet of the repro code that Peter de Valenca submitted to Microsoft

*    Peter de Valença

*    www.viafox.nl

*==============================================================\

create cursor c_effe ( f1 c(10) )

insert into c_effe values ( "aaaaa" )

insert into c_effe values ( "bbbb" )

insert into c_effe values ( "ccc" )

insert into c_effe values ( "ddddd" )

 

create report effe from c_effe

 

SET REPORTBEHAVIOR 90

 

LOCAL loReportWindow

 

loReportWindow = ReportWindow()    && creates an as-toplevel form

 

WITH loReportWindow

    .Caption     = "some title"

    .WindowState = 2    && maximize

    .Show()            && must be done to force the maximizing

ENDWITH

 

* make sure the report can load and run

REPORT FORM effe PREVIEW window ( loReportWindow.Name )

 

* Creates a window for the report.

FUNCTION ReportWindow

    local loRepForm

    loRepForm = CREATEOBJECT( "reportwindow" )

    return loRepForm

 

define class reportwindow as form

    ShowWindow = 2    && as toplevel form

enddefine

*==============================================================/

So, what can we do about it? We have a couple of options:

A) Remove any one of the conditions above and it works fine. Of course you probably have your reasons to use the new reporting and reasons to use a top level form or we wouldn’t be here. But do you really need it to be modal? This was an issue in previous versions of VFP because the previewer only processed one page at a time. If you had an environment set up, let’s say open cursors with relationships and you wanted to clean all of that up after the REPORT FORM command was issued, you had to go modal. If you let the code continue by using the NOWAIT clause, your environment would be gone and the user would get an error as soon as they tried to navigate to the next page.

With VFP9 reporting, all pages are preprocessed before the preview window even comes up, so you don’t have to be modal and preserve your environment. Just let the code continue on and let your users multi-task. If you add a NOWAIT to the sample above, (and make the loReportWindow PUBLIC) you will see that it works fine:

PUBLIC loReportWindow

. . .

REPORT FORM effe PREVIEW WINDOW ( loReportWindow.Name ) NOWAIT

B) So that works, but there are a couple of annoyances. First, the preview window doesn’t look right. It is a window within a window. Peter makes mention of this in his bug report and provides a couple of screen shots comparing REPORTBEHAVIOR 80 to REPORTBEHAVIOR 90. You get the same affect whether you use the WINDOW or IN WINDOW clause. But again, this is a limitation of using VFP Forms for the report preview and placing a window within a window. The other annoyance is that we had to declare our parent form as PUBLIC. This is because we need the form to stick around after the REPORT FORM command has finished. But this should be nothing new to developers who use top level forms.

There is an easier way around both of these annoyances and it actually requires the use of LESS code. With the VFP9 reporting, we can customize the preview container with a lot more options than we had before. One of the options is to force a top level form by setting the .TopForm property of the PreviewContainer object. This eliminates a lot of goofy code that we had to do in the past. You will also notice in the sample below that our variables are declared LOCAL. We can do this because the preview container is managing our form reference for us. Here is the new code:

*==============================================================\

CREATE CURSOR c_effe ( f1 c(10) )

INSERT INTO c_effe VALUES ( "aaaaa" )

INSERT INTO c_effe VALUES ( "bbbb" )

INSERT INTO c_effe VALUES ( "ccc" )

INSERT INTO c_effe VALUES ( "ddddd" )

 

CREATE REPORT effe FROM c_effe

 

LOCAL pc, ri

DO (_REPORTPREVIEW) WITH pc

pc.TopForm = .t.

ri = NEWOBJECT("ReportListener")

ri.ListenerType = 1           && preview

ri.PreviewContainer = m.pc

REPORT FORM effe OBJECT ri

*==============================================================/

Here is what the new improved form looks like

There are other properties available to customize the report previewer, check the VFP9 help topic Leveraging the Default Preview Container for more information.

C) There may be another option, but I will have to come back to it later. Christof sent me some sample code today showing how he may have a way of switching up the parent window for the toolbar that seems to be a step in the right direction but there is an issue if you change the docking state of the toolbar. I’ll keep you posted if we make any breakthroughs.

In Closing

Should this stop you from upgrading to SP2? I don’t think so. If you are even trying to display reports in a top level form, I think you can take advantage of the new Reporting features and actually improve the user's experience and get rid of the modal window.

Honestly, I’m not sure if Microsoft should even try to address this issue. How can they modify the form behavior to allow toolbars to work for modal report windows, but not allow toolbars to work for other modal windows? I just think this would open up a can of worms. (Maybe it did in SP1 and that's why it's back) It may be best to code a workaraound in either the reporting APPs or use a known technique for simulating a modal condition when using top level forms, like a DOEVENTS loop.

I'm open to any comments related to this issue. I would also be interested in knowing how many people use this technique for previewing reports.

This one bug took a while to go through, but I felt it was an important one. The next few should be much shorter reading.


Tuesday, March 04, 2008 9:12:57 AM (Eastern Standard Time, UTC-05:00)  #    Comments [8]   | 

Tuesday, March 04, 2008 11:08:43 PM (Eastern Standard Time, UTC-05:00)
Bo, thanks a lot for all your time and efforts. I really appreciateall your help, and I'm sure there will be more workarounds
Wednesday, March 05, 2008 2:16:59 AM (Eastern Standard Time, UTC-05:00)
Bo, this was a great read - thanks!
Wednesday, March 05, 2008 4:37:31 PM (Eastern Standard Time, UTC-05:00)
Great series of posts, Bo! Thanks for all the effort and sharing.
Wednesday, March 05, 2008 9:19:34 PM (Eastern Standard Time, UTC-05:00)
Nice post, Bo. Well done.
Thursday, March 06, 2008 3:44:20 AM (Eastern Standard Time, UTC-05:00)
Thank you all for the feedback. I have a long way to go and it's nice to know it is well received.
Monday, March 10, 2008 12:53:42 PM (Eastern Daylight Time, UTC-04:00)
I tried the workaround that uses the ReportListener and it works nicely indeed. What I noticed:

1) Although there's not NOWAIT declared anywhere, it acts as such and that may worry some. I have searched for the ReportListener property that can control this behavior, but haven't found it sofar.

2) It requires a rewrite of existing code. If the REPORT FORM command is in a specializing routine, than that should pose no big problem. Otherwise, the developer will have to invest some more time.

I'm glad you came up with the workaround(s), but still think that MS should have fixed it. Or if they think your suggestion is the way to go, then they should formally tell us so, instead of being silent all the time about it.

Thanks for the great post!
Tuesday, March 11, 2008 10:25:03 PM (Eastern Daylight Time, UTC-04:00)
I have done a test and now see that the NOWAIT state is caused by: TopForm = .T.

That's relatively okay with me, but a NEW problem arises! The consequence is that the user can now invoke more reports without first closing previous ones, two, three, any number. Any number? Well, not in my case. I noticed that the second report still acted okay, but then suddenly the third report had no toolbar while the first one got two! Invoke some more or click in various reports and then suddenly BANG: C0000000005.

Apparently one of the routines gets confused and cannot keep the instances separate. Perhaps some property needs to be manipulated first, to help the routines not getting confused.
Wednesday, March 12, 2008 5:00:58 AM (Eastern Daylight Time, UTC-04:00)
Hey Peter, Thanks for the info. I was able to duplicate this problem with just 3 report windows. I found the spot in the code where the toolbar was being docked. It is expecting unique window names. Once I created unique window names I was able to open over 200 preview windows simultanously.

I started going through the windows and a couple of them complained on the rightclick menu. This may be an easy workaraound too, but I'll have to dig into it more.

I'll try to work this into the XSource and recompile. We may be ready for a beta on VFPx soon.

Thanks for testing this and letting me know about it!
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: )  

Enter the code shown (prevents robots):