Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Top Form - Move with _Screen? or Docking Reportpreview Toolbar? 1

Status
Not open for further replies.

networkthis

Programmer
Jul 11, 2011
29
US
Is it possible to have a top form move with the Main VFP screen itself?

I am asking because I have a custom reportpreview which I have set up as a topform. I only used a topform because I need the report preview toolbar docked at the top of the window.

I can use the alwaysontop with the oform created from the reportpeviewer after the Report is generated, but then I lose the docking of the reportpreview toolbar.

Ideas?
 
You can use BindEvents() and bind to _SCREEN.Moved() event in your preview form init:

Code:
BindEvent(_Screen,"Moved",This,"Synch")

That means you add a Synch() Method to your previewform, that will be triggered, everytime the _screen moves, in which you do

Code:
Thisform.Left = _screen.Left
Thisform.Top = _screen.Top

Add whatever offset you need for left and top. You can determine these offsets by the initial difference of preview.top-_screen.top and preview.left-_screen.left and stoe them in preview form properties, whatever suits you best.

Bye, Olaf.
 
Thank you for the info!

Another question... When I'm doing this in a .prg. How or rather where would I call the init procedure? I understand where it goes in a form .scx and that the events fire load then init when creating the form. I thought to call init it is Procedure object.init. I have tried several ways with no luck in the .prg


Here is a basic example of what I have:

loNewPreview = .NULL.
DO (_REPORTPREVIEW) WITH m.loNewPreview

WITH loNewPreview
.Topform = .T.
.AllowPrintFromPreview = .F.
&& ..........
ENDWITH

loNewListener = NEWOBJECT("ReportListener")
loNewListener.ListenerType = 1
loNewListener.PreviewContainer = loNewPreview

REPORT FORM Test1 PREVIEW OBJECT loNewListener

WITH loNewPreview.oform
.movable = .F.
.minbutton = .T.
.alwaysontop = .T.
&& ..........
ENDWITH
 
No, you shouldn't call init.

I thought you have your own preview form or form class, but you let _REPORTPREVIEW generate a listener with preview form you want to move with _screen. You could have said so in the first place.

I thought you were rather doing legacy REPORT FORM... WINDOW yourwindow.

Still bindevent is applicable, this just has to be done a bit more complicated with yet another helper class to be added.
That new class will have the Synch method.

Ideally, instead of that new helper class, you would modify the base preview form class the _REPORTPREVIEW app creates. That would indeed be possible, but an overhead in comparison with this, as you'd need to change the ReportPreview pjx and compile a new ReportPreview.App. I doubt you want to go in so deep, so take this instead:

Code:
loNewPreview = .NULL.
DO (_REPORTPREVIEW) WITH m.loNewPreview

WITH loNewPreview
   .Topform = .T.
   .AllowPrintFromPreview = .F.
   && ..........      

   .AddObject("oScreenEventHandler","ScreenEventHandler")
   BINDEVENT(_Screen,"Moved",.oScreenEventHandler,"ScreenSynch")
ENDWITH

loNewListener = NEWOBJECT("ReportListener")
loNewListener.ListenerType = 1
loNewListener.PreviewContainer = loNewPreview

REPORT FORM Test1 PREVIEW OBJECT loNewListener

WITH loNewPreview.oform
   .movable = .F.
   .minbutton = .T.
   .alwaysontop = .T.
ENDWITH    

*...

* At the end of your prg:

DEFINE CLASS ScreenEventHandler as container
   Procedure ScreenSynch()
      This.Parent.oForm.Left = _screen.Left
      This.Parent.oForm.Top = _screen.Top
   Endproc 
ENDDEFINE

Now that I added the DEFINE CLASS to your code, it needs to be a prg, because inside a method or a click event of a button you can't DEFINE a CLASS.

BUT:

You could also put that DEFINE CLASS in a seperate prg and let your code SET PROCEDURE TO C:\yourprojects\yourproject\prgs\that.prg ADDITIVE to be able to use that class from your code.

See if that works at least. It will put the preview window into the left top corner of the screen, once you move the _screen, and you/we/I will need to ammend that with a shift to retain the relative postion the preview has initially, but this will do for a first test drive. Please come back if you've got so far or have another problem.

Bye, Olaf.
 
Just to add a little explaination about what that little helper class "ScreenEventHandler" and how it works:

WITH loNewPreview
&& ..........
.AddObject("oScreenEventHandler","ScreenEventHandler")
ENDWITH

Adds an instance of that helper class to loNewPreview, now loNewpreview.oScreenEventhandler exists as a sub object of the loNewPreview object, because I used Addobject it is a child object.

Bindevent now does bind the _screen Moved() event to the loNewpreview.oScreenEventhandler.ScreenSynch() method. So every time the _screen is Moved, that code will also run and change left and top of the preview form, too.

Why I needed to change from THISFORM inside the ScreenSnych() method: Now it is an object seperate from the preview form itself, I can't use THISFORM, also not loNewpreview or loNewpreview.oForm, as loNewpreview is a local var not known inside the ScreenEventHandler object.

From inside loNewpreview.oScreenEventhandler THIS is referncing loNewpreview.oScreenEventhandler and THIS.PARENT is referencing loNewpreview and THIS.PARENT.oFORM therefore is referencing loNewPreview.oform, the real preview form reference to move around with the _screen.

Hope that helps a bit understanding what's going on and why.

Bye, Olaf.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top