Wojtek Skulski wrote:
>I have a problem printing a view. It is a perfectly
>healthy view on screen, but when I select File --> Print
>from the menu, I am getting a TRAP. The trap says
>all pointer fields in the view are NIL, among them
>v.fnt (which should contain a font). The Restore
>bombs on v.fnt NIL dereference.
>
>These pointer fields of the view are obviously
>OK when the view is plotted on screen,
>because on screen I am getting all as I should,
>and everything works. But when printing, all the pointers
>"automagically" disappear. Actually, when I follow
>the "v" link in the TRAP viewer, it looks as if
>all view fields are not initialized.
>
>Is there a method that I should implement before I can
>print? I looked at Views and there is a CopyFrom there that
>I have not implemented. Do I need to implement CopyFrom
>before I can print? (If yes, then why?)
Wojtek,
I believe that when you print a view, it is not the original view that is
printed. It must be reformatted for a different underlying display device.
Thus, the system makes a copy of your view and initilises it with a
different rider (ie. for the printer device rather than the screen).
According to the documentation, you need to implement InitFrom (if your
view has a model) or CopyFrom (if your view does not have a model). I
suspect that the default InitFrom calls CopyFrom, because it seems to also
work if you implement only CopyFrom for views with models (as was done in
1.2).
For my views, I use the following scheme. Define an Init procedure which
you call when creating a new View. This should initialise all persistent
and non-persistent View fields to sensible values. Call Init at the start
of InitFrom. If InitFrom passed you the right type of View (it is
guaranteed to do this), these can be overwritten with the appropriate values.
PROCEDURE (v : View) Init* (), NEW;
BEGIN
.. initialisation ..
v.model := NIL;
v.font := Fonts.dir.Default();
END Init;
PROCEDURE (v : View) InitFrom- (source: Views.View; model: Models.Model);
BEGIN
v.Init();
v.model := NIL;
IF model # NIL THEN v.model := model(Model) END;
WITH source: View DO
.. copy relevant parameters from source ..
END
END InitFrom;
In my experience, you also need to initilise the font in Views.Internalize.
I have found that if I don't do this, the system will trap when copying the
view to an OLE container. This leads me to suspect that there is an implied
Externalize/Internalize process involved when a View is copied in this way.
This means that Internalize MUST also initialise any non-persistent fields
of your view. It also means that you MUST implement Internalize even if
your view has no persistent state, because it will not be initilized in any
other way. Strange ...
PROCEDURE (v: View) Internalize- (VAR rd: Stores.Reader);
BEGIN
v.Init();
.. internalisation ..
END Internalize;
Some of these issues are a little unclear in the documentation. There seem
to be several ways in which views are created:
1) NEW(v); v.Init(..) (* your own view-specific initialisation *);
2) InitFrom
3) Internalize
InitFrom cannot be used as a generalised View initialiser because it
requires an existing view of the same type. It might be better if the
framework included a parameterless Init - this would remove the need for
some of this magic. Or perhaps I'm missing something here ...
Hope this helps.
- Stewart
Received on Fri Feb 12 1999 - 07:01:18 UTC