Title Banner

Previous Book Contents Book Index Next

Inside Macintosh: OpenDoc Cookbook /
Chapter 2 - SamplePart Tutorial


Opening the Part Into a Window

OpenDoc calls the Open method of a part editor in three cases: when the part is initially created, when the part is the root part of a document being opened, and when the part is embedded and the user opens it into a separate part window.

If the frame parameter has a value of kODNULL, then the part is being created for the first time. If the frame parameter points to a root frame, then an existing document is being opened. If the frame parameter points to a frame that is not a root frame, then an embedded frame is being opened into a part window.

The basic steps in the process of opening the part into a window are as follows:

  1. If a frame pointer was passed into the Open call, check for an existing part window. If there is one, skip to step 4.
  2. If no frame pointer was passed or the part window no longer exists, create a new window (to add the root frame).
  3. Open the window (to add the root facet).
  4. Show the window (to make it visible).
  5. Select the window (to bring it to the front).
  6. Return the window ID number.

The order of the sequence--opening, then showing, then selecting the window--is very important. In SamplePart, these steps are accomplished by the Open and CreateWindow methods, with some help from utility methods.

The Open Method

The SamplePart object's implementation of the Open method performs the following actions:

  1. Creates pointer variables for a window object and a window properties structure.
    The ODWindow object is a wrapper for a platform-specific window. The WindowProperties object is a C structure (defined in the file WinUtils.h) to contain the attributes of a Mac OS-specific window, such as bounding rectangle, title string, and so forth.

    The method uses the macro ODVolatile, which is defined in the OpenDoc exception-handling utility file Except.h. This macro ensures that the variable will remain valid in the CATCH_ALL block after having been modified in the TRY block. The ODVolatile macro is documented in Appendix A, in the section "Make Variables That You Modify Volatile".

  2. Handles the new document case.
    If the frame parameter is null, the part must create a window for a new document. In this case, there are no saved window properties, so the method calls the SamplePart internal method GetDefaultWindowProperties to create a default set.

    Having filled in the window properties structure, the method then calls the SamplePart internal method CreateWindow to create the platform window and OpenDoc window wrapper. The CreateWindow method is described in "The CreateWindow Method".

  3. Handles the existing document case.
    If the frame parameter points to a root frame, the part must create a window to display the root frame of an existing document. In this case, the window properties were previously saved in a separate storage unit, to which a strong reference exists in the root frame's storage unit. The SamplePart internal method GetSavedWindowProperties retrieves the information using the BeginGetWindowProperties utility method defined in the file WinUtils.cpp.

    Having obtained the window properties, the method calls the SamplePart internal method CreateWindow. In this block, the method also uses the ODReleaseObject utility method to decrement the reference count of the frame object because it was incremented in GetSavedWindowProperties.

  4. Handles the embedded frame case.
    If the frame parameter is not null, and it's not a root frame, then it's an embedded frame being opened into a part window. In this case, the method first tries to retrieve an existing window for the frame using the SamplePart internal method AcquireFramesWindow. A window can exist for the frame if it was previously opened into a part window.

    Otherwise, the method proceeds as in the new document case, except that it uses the frame to determine window size and property values. Finally, the method saves the part-window pointer in the frame's CFrameInfo object.

  5. Calls the window activation methods.
    When it has created the window, the Open method calls three methods belonging to the OpenDoc window-wrapper object: Open, Show, and Select. The window's Open method creates the root facet for the window and notifies the part editor. The Show method makes the window visible. The Select method activates and selects the new window, bringing it to the front.

  6. Cleans up and returns the window's ID number to OpenDoc.
Listing 2-7 shows the implementation of the Open method.

Listing 2-7 Open method

ODID SamplePart::Open( Environment*ev, ODFrame* frame )
{
    SOM_Trace("SamplePart","Open");

   ODID windowID;
   TempODWindow window(kODNULL);

   WindowProperties* windowProperties = kODNULL;
   ODVolatile(windowProperties);

   TRY
      if ( frame == kODNULL )
      {
         Rect windowRect = this->CalcPartWindowSize(ev, kODNULL);
         windowProperties = this->GetDefaultWindowProperties(ev, 
                                             kODNULL, &windowRect);
         window = this->CreateWindow(ev, kODNULL, kODFrameObject, windowProperties);
      }
      else if ( frame->IsRoot(ev) )
      {
         windowProperties = this->GetSavedWindowProperties(ev, frame);
         
         if ( windowProperties == kODNULL )
         {
            Rect windowRect = this->CalcPartWindowSize(ev, frame);
            windowProperties = this->GetDefaultWindowProperties(ev, 
                                             kODNULL, &windowRect);
         }

         window = this->CreateWindow(ev, frame, kODFrameObject, windowProperties);
         
         ODReleaseObject(ev, windowProperties->sourceFrame);
      }
      else // frame is a source frame
      {
         window = this->AcquireFramesWindow(ev, frame);
   
         if ( window == kODNULL )
         {
            Rect windowRect = this->CalcPartWindowSize(ev, frame);
            windowProperties = this->GetDefaultWindowProperties(ev, 
                                                frame, &windowRect);
            // Create a Mac Window and register it with OpenDoc.
            window = this->CreateWindow(ev, kODNULL, 
                                       kODFrameObject, windowProperties);
            CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
            frameInfo->SetPartWindow(ev, window);
         }
      }
   
      window->Open(ev);
      window->Show(ev);
      window->Select(ev);
   
      ODDeleteObject(windowProperties);
      windowID = (window ? window->GetID(ev) : kODNULLID);
   
   CATCH_ALL
      if ( windowProperties )
         ODSafeReleaseObject(windowProperties->sourceFrame);
      ODDeleteObject(windowProperties);
      windowID = kODNULLID;
      RERAISE;
   ENDTRY

   return windowID;
}

The CreateWindow Method

The SamplePart object's internal CreateWindow method is called by the part's Open method to create a window for a frame that is being opened. The method uses information passed in its windowProperties parameter to set the window attributes--the size of the new window, the string for its title bar, and so forth. The method then creates a Mac OS-specific window structure, and integrates the window into the OpenDoc environment by registering it in an OpenDoc window-state object, thereby creating an OpenDoc window pointer, which is returned from the method.

The CreateWindow method performs the following actions:

  1. Creates a platform-specific window structure.
    The method creates the window structure using the Mac OS toolbox routine NewCWindow and the OpenDoc memory manager utility. The ODNewPtr function allocates space for the window structure in temporary memory rather than the application heap.

  2. Creates an OpenDoc window object.
    The window-state object, available through the session object, instantiates OpenDoc window objects, which are wrappers for the platform-specific windows. OpenDoc uses the window-state object and window objects to keep track of each of the windows it handles in a platform-independent manner.

    If the Open method is opening a new document, CreateWindow calls the ODWindowState method RegisterWindow to create the OpenDoc window object and register it as a new window. To create and register the window for an existing document, the method calls the ODWindowState method RegisterWindowForFrame.

If the method fails to create the window successfully, it generates a dialog box to notify the user, using the SamplePart utility method DoDialogBox. It also uses the exception-handling utility SetErrorCode to let OpenDoc know the user was already notified of the error.

Listing 2-8 shows the implementation of the CreateWindow method.

Listing 2-8 CreateWindow method

ODWindow* SamplePart::CreateWindow( Environment*       ev,
                                    ODFrame*           frame,
                                    ODType             frameType,
                                    WindowProperties*  windowProperties)
{
    SOM_Trace("SamplePart","CreateWindow");

   ODPlatformWindow  platformWindow = kODNULL;
   ODWindow*         window         = kODNULL;
   
   platformWindow = NewCWindow((Ptr)ODNewPtr(sizeof(WindowRecord)),
                               & (windowProperties->boundsRect),
                               windowProperties->title,
                               kODFalse, /* visible */
                               windowProperties->procID,
                              (WindowPtr)-1L,
                               windowProperties->hasCloseBox,
                               windowProperties->refCon);

   if ( platformWindow )
   {
      TRY
         ODWindowState* windowState = ODGetSession(ev,fSelf)->GetWindowState(ev);
         ODBoolean saveWindow = (ODISOStrCompare(frameType,kODFrameObject) == 0);
         ODBoolean shouldDispose = kODFalse;
                        
         if ( frame == kODNULL )
         {                       
            window = windowState->                     RegisterWindow(ev, 
                        platformWindow,                     // Mac OS WindowPtr
                        frameType,                          // Frame persistent?
                        windowProperties->isRootWindow,     // Document window?
                        windowProperties->isResizable,      // Resizeable?
                        windowProperties->isFloating,       // Floating?
                        saveWindow,                         // Window persistent?
                        shouldDispose,                      // Dispose when done?
                        fSelf,                              // Self reference
                        gGlobals->fFrameView,               // What view?
                        gGlobals->fMainPresentation,        // What presentation?
                        windowProperties->sourceFrame);     // Source frame, if any
         }
         else
         {
            window = windowState->                     RegisterWindowForFrame(ev,
                        platformWindow,
                        frame,
                        windowProperties->isRootWindow,
                        windowProperties->isResizable,
                        windowProperties->isFloating,
                        saveWindow,
                        shouldDispose,
                        windowProperties->sourceFrame);
         }
      CATCH_ALL
         CloseWindow(platformWindow);
         ODDisposePtr(platformWindow);
         ODSShort errMsgNum = (!frame && windowProperties->sourceFrame)
                           ? kErrCantOpenPartWindow : kErrCantOpenDocWindow;
         this->DoDialogBox(ev, frame, kErrorBoxID, errMsgNum);
         SetErrorCode(kODErrAlreadyNotified);
         RERAISE;
      ENDTRY
   }

   return window;
}

Previous Book Contents Book Index Next

© Apple Computer, Inc.
16 JUL 1996




Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help