Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Cyberdog Programmer's Kit / Part 2 - Programming in Cyberdog
Chapter 3 - Adding Cyberdog Features to an OpenDoc Part


Displaying Cyberdog Menus

A Cyberdog service menu object handles the display of the Cyberdog menu and the Mail/News menu. It also allows services, such as FTP and Gopher, to install their menus as well. Collectively, these menus are called the Cyberdog service menus. You set up these menus by creating a CyberServiceMenu object and calling its ICyberServiceMenu method. When your part is destroyed, you can delete the service menu object. See Listing 3-3 (page 95).

Listing 3-11 shows the button part's CreateMenus method, which creates and initializes the Cyberdog service menu object and adds it to the menu bar.

Listing 3-11 Creating Cyberdog's menus

void CybTxtBtn::CreateMenus(Environment* ev)
{
   ODSession* session = ODGetSession(ev,fSelf);
   
   // Copy the base menu bar.
   fMenuBar = session->GetWindowState(ev)->CopyBaseMenuBar(ev);

   // Extend it with Cyberdog's menus.
   fCyberServiceMenu = new CyberServiceMenu;
   if (fCyberServiceMenu)
      fCyberServiceMenu->ICyberServiceMenu(ev, fMenuBar, 
                                    fSelf, kBaseResourceID);
}
In the call to the ICyberServiceMenu method, the kBaseResourceID constant specifies the first value to use for Cyberdog menu commands. The value you choose must allow Cyberdog menus to fall within the range supported by OpenDoc. In this example, the kBaseResourceID constant is defined as follows:

#define  kBaseResourceID20001
For more information about the Cyberdog command numbers, see the CyberServiceMenu class (page 341).

You must anticipate that the menu bar changed between activations of your part. You should recreate the menu bar each time your part is activated or its menus are adjusted. Listing 3-12 shows the button part's CheckMenus method, which recreates the menu bar.

Listing 3-12 Recreating the menu bar

void CybTxtBtn::CheckMenus(Environment* ev, ODFrame* frame)
{
   if (fMenuBar->IsValid(ev) == kODFalse)
   {
      // Release the old menu bar and the CyberServiceMenu object
      if (fCyberServiceMenu)
      {
         delete fCyberServiceMenu;
         fCyberServiceMenu = kODNULL;
      }
      
      ODReleaseObject(ev, fMenuBar);
      fMenuBar = kODNULL;
      
      // Recreate the menus.
      CreateMenus(ev);
      
      // If the part has the menu focus, inform the newly created
      // CyberServiceMenu object and display the newly created menu bar
      if (frame != kODNULL)
      {
         ODBoolean hasMenuFocus;
         ODArbitrator* arbitrator 
                     = ODGetSession(ev,fSelf)->GetArbitrator(ev);
         TempODFrame menuOwner 
          = arbitrator->AcquireFocusOwner(ev, gGlobals->fMenuFocus);
         hasMenuFocus = ODObjectsAreEqual(ev, frame, menuOwner);
         
         if (hasMenuFocus)
         {
            if (fCyberServiceMenu)
               fCyberServiceMenu->MenuFocusAcquired(ev, frame);
            // Display the menu bar.
            fMenuBar->Display(ev);
         }
      }
   }
}
When your part has the menu focus, you must call the service menu object's MenuFocusAcquired method to activate Cyberdog's menus. Listing 3-13 shows the button part's PartActivated method, which calls the service menu's MenuFocusAcquired method.

Listing 3-13 Acquiring the Cyberdog service menu's focus

void CybTxtBtn::PartActivated(Environment* ev,
                      ODFrame* frame )
{
   CheckMenus(ev, kODNULL);

   fCyberServiceMenu->MenuFocusAcquired(ev, frame);
   fMenuBar->Display(ev);
   ...
}
When your part is no longer active, you must call the service menu's MenuFocusLost method to deactivate Cyberdog's menus. Listing 3-14 shows the button part's FocusLost method, which calls the MenuFocusLost method.

Listing 3-14 The button part's FocusLost method

void CybTxtBtn::FocusLost(Environment* ev, ODTypeToken focus, 
                                       ODFrame* ownerFrame )
{
   if ( focus == gGlobals->fSelectionFocus )
   {
   ...
   }
   else if( focus == gGlobals->fMenuFocus )
   {
      // Tell the CyberServiceMenu object that the menu focus is lost.
      if (fCyberServiceMenu)
         fCyberServiceMenu->MenuFocusLost(ev, ownerFrame);
   }
}
You must also allow menus to adjust their items and allow the menu items to handle menu events.

In this example, these methods are called by the button part's AdjustMenus and HandleMenuEvents methods, respectively, as shown in the following section. The AdjustMenus method also deletes and recreates the Cyberdog service menu object when a root part's menus are adjusted.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
13 JUL 1996