Anda di halaman 1dari 2

Print Article

Seite 1 von 2

Issue Date: FoxTalk January 1998

Previewing a Report from an SDI Application


R. Scott Mackay

Previewing a report from an SDI application doesn't seem to work -the preview feature seems to be ignored, and the WINDOW <WindowName> clause of the REPORT FORM command ignores the top-level Form characteristic. In this article, Scott describes why this isn't actually so and presents a solution to the problem.
Visual FoxPro 5.0 introduced the ability to have a top-level form and to hide the screen (that is, the main VFP window) on startup. These highly requested features now make it possible to develop SDI (Single Document Interface) applications or MDI applications with more control than is allowed using the VFP screen as the parent form. I was quite pleased with my first SDI app, until it came time to implement the reporting features -- previewing a report from an SDI application didn't seem to work. After further investigation, it became clear that the report preview was working -- it was just being displayed in the VFP screen (which isn't visible in an SDI application). The REPORT FORM command has a WINDOW <WindowName> clause that looks like it would do the trick by giving the report preview the characteristics of a user-defined window. Unfortunately, the report preview doesn't pick up the one desired characteristic -- the top-level form. Making the VFP screen visible prior to the REPORT FORM command is an option; ugly, but it works. The VFP screen could be cosmetically dressed up a bit -- the equivalent of going on a spending spree at a thrift store. But it still didn't feel like the best solution. Time for some hacking. What about using the Windows API to set the report preview window's parent to a top-level form? Even simpler than an API command, the old ACTIVATE WINDOWIN WINDOW command can be used to set the report preview window's parent to a top-level form. First, define a class definition for a top-level form (make sure the class definition gets loaded into memory): DEFINE CLASS dlgTopLevel AS Form ShowWindow = 2 && Top Level ENDDEFINE Create an instance of a top-level form to contain the preview window, then preview the report with the NOWAIT option. Using the NOWAIT option is necessary to gain back control, but it also introduces a new problem (which I'll address later). LOCAL oDlgPreview oDlgPreview = CREATE('dlgTopLevel') REPORT FORM MyReport PREVIEW NOWAIT Now hijack the report preview and report toolbar windows and place them in the top-level form. In order to hijack live report preview and report toolbar windows, the VFP screen has to be visible; otherwise the hijacked windows act dead. So move the VFP screen out of the viewable area so that the user won't see it, and then make it visible: _Screen.Top = _Screen.Top + 2000 _Screen.Visible = .T. Maximize the preview window to fit the top-level form and move the toolbar to the upper left corner of the top-level form. Set the VFP screen back the way it was, and then show the top-level form: ACTIVATE ; WINDOW 'Report Designer' ; IN WINDOW (oDlgPreview.Name) ZOOM WINDOW 'Report Designer' MAX ACTIVATE ; WINDOW 'Print Preview' ; IN WINDOW (oDlgPreview.Name) MOVE WINDOW 'Print Preview' TO .5,1 _Screen.Visible = .F. _Screen.Top = _Screen.Top - 2000 oDlgPreview.Show This worked pretty well, but there are still a couple of problems. The toolbar still wants to belong to the VFP screen, because

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=... 07.02.06

Print Article

Seite 2 von 2

clicking on it if the top-level form is anywhere over the VFP screen will cause the VFP screen to activate. But this won't be a problem at runtime, because our intent is to rid ourselves of the VFP screen. The other problem is that, because the report is no longer modal (due to the use of the NOWAIT option), the calling program might clean up the report before the user gets a chance to preview it. My first inclination was to just show the dialog box modally, using the .Show(1) option. But that doesn't work on a top-level form. Using a DO WHILE loop could give us a wait state, but it wouldn't allow the user to do anything. What about a DO WHILE loop with a DOEVENTS inside the loop? Here's the code: DO WHILE EMPTY(WONTOP()) OR ; 'REPORT DESIGNER' $ UPPER(WONTOP()) DOEVENTS ENDDO That did the trick! To sum up, doing a little hacking by using some of the older xBase commands can pay off sometimes. The next logical step would be to gather this together into a class so that it would be a simple matter to make use of it, like this: REPORT FORM ... NOWAIT oDlgSDIPreview = CREATE('dlgSDIPreview') oDlgSDIPreview.Show I've put together a more robust public domain utility to do just that, and it's available in the accompanying Download file.

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=... 07.02.06

Anda mungkin juga menyukai