Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Digital Audio, Video > QuickTime

QuickTime Movies and File Handling

📄 Contents

  1. QuickTime Movies and File Handling
  2. QuickTime Movies
  3. For More Information
In this sample chapter you'll see how Mac OS X programs can open and play a QuickTime movie.
This chapter is from the book

This chapter is from the book

At this point, you know all about interface elements such as windows, controls, and menus, and you have a firm grasp on how your program recognizes and handles a variety of types of events. So it's on to the fun stuff. In this chapter, you'll see how your program opens and plays a QuickTime movie. QuickTime is movie-playing software that is part of the system software of every Macintosh in your target audience.

It's possible for a program to cause a QuickTime movie to spring forth from (seemingly) nowhere. However, it's more likely that a movie-playing application will enable the user to select the file that holds the movie to play. Giving the user the power to open a QuickTime movie file, or any other type of file, involves the Open dialog box. We'll look at the Open dialog box first in this chapter.

Files and Navigation Services

A file is a sequence of bytes stored on physical media, such as a hard drive, and a directory is another name for a folder. A volume can be an entire physical storage device or it can be part of the device (the result of formatting the device to consist of multiple volumes). For a program to access a file, it needs to know the file's name, the directory in which the file is located, and the volume on which that directory resides. In certain circumstances, a program that's to open a file includes these values (the file name and location) directly within its code, but that's a scenario few programs use. In addition, this hard-coding of file information prevents the user from choosing what file to open, and it also sets up an application failure should the user move or delete the sought-after file.

A better way to handle the situation is to call Navigation Services routines to make use of the Open dialog box. By displaying the Open dialog box, you enable a user to select the file to open. Handling file opening in this way also forces the system to do the work of determining a file's name and location, and it leaves it to the system to convey this important file information to your program.

The Open dialog box provides the user with a standard interface for opening a file. This same Open dialog box is used by any real-world application. You can see it by choosing Open from the File menu of programs such as Apple's TextEdit or by looking at Figure 9.1.

Navigation Services is part of the Carbon API that makes is possible for your programs to include standard dialogs such as the Open dialog box. In addition, it is an important and useful part of the Carbon API. It routines provide interface consistency for the user and removes the burden of file location determination from the programmer. In this chapter, you'll see how to make use of Navigation Services, so brace yourself for a barrage of information about key Navigation Services routines.

Implementing an Open Dialog Box

You'll make use of a number of Navigation Services routines to display and handle an Open dialog box that is similar to the one TextEdit and other Mac OS X applications use. To do that, your code will perform the following:

  1. Create and display the standard Open dialog box.

  2. Become aware of the user's action in the Open dialog box.

  3. Respond to the user's action (for instance, open the appropriate file if the user clicks the Open button).

  4. Clean up by disposing of the Open dialog box when appropriate.

The overall look and behavior of an Open dialog box usually is the same. Such a dialog box includes Cancel and Open buttons and a list view of the folders and files on the user's machine. The general behavior of this type of dialog box is the same from one implementation to another as well; the user navigates through the file list, clicks the name of a file to open within the list, and then clicks the Open button to open the selected file. To promote this consistent look and behavior, Navigation Services defines the NavDialogCreationOptions data structure as the following:

struct NavDialogCreationOptions {
  UInt16                version;
  NavDialogOptionFlags  optionFlags;
  Point                 location;
  CFStringRef           clientName;
  CFStringRef           windowTitle;
  CFStringRef           actionButtonLabel;
  CFStringRef           cancelButtonLabel;
  CFStringRef           saveFileName;
  CFStringRef           message;
  UInt32                preferenceKey;
  CFArrayRef            popupExtension;
  WindowModality        modality;
  WindowRef             parentWindow;
  char                  reserved[16];
};
typedef struct NavDialogCreationOptions NavDialogCreationOptions;
Figure 9.1 A typical Open dialog box (as displayed in TextEdit).

The NavDialogCreationOptions structure defines the features (such as size and location) of an Open dialog box. The Navigation Services routine NavGetDefaultDialogCreationOptions is used to fill the fields of a NavDialogCreationOptions structure with default values. Use this routine by declaring a variable of type NavDialogCreationOptions and then passing that variable's address as the routine's one argument:

OSStatus                  err;
NavDialogCreationOptions  dialogAttributes;

err = NavGetDefaultDialogCreationOptions( &dialogAttributes )

After setting the values of the members of a structure to default values, you can customize the structure by changing the value of any individual member. For instance, to make the Open dialog box take over the application and disallow other application actions to take its place, the value of the dialog box's NavDialogCreationOptions modality member can be set to the Apple-defined constant kWindowModalityAppModal:

dialogAttributes.modality = kWindowModalityAppModal;

You've seen how a program includes an application-defined event handler routine that's associated with a window or other object. The Open dialog box also needs an application-defined event handler routine associated with it. This event handler will be called by the system when the user dismisses the Open dialog box. Navigation Services creates, displays, and runs the Open dialog box, but it is this event handler that should perform the actual work of opening a user-selected file. Like other event handlers, this Open dialog box event handler can have a name of your choosing, but it must include arguments of specific types. Here's the prototype for such a routine:

pascal void MyNavEventCallback(
               NavEventCallbackMessage callBackSelector, 
               NavCBRecPtr             callBackParms, 
               void*                   callBackUD );

In a moment, you'll pass a pointer to this event handler to the Navigation Services routine that creates the Open dialog box. The pointer should be of type NavEventUPP. The UPP in NavEventUPP stands for universal procedure pointer, which is a pointer that is capable of referencing procedures, or routines, in different executable formats. In this case, a NavEventUPP can point to a routine that is in native Mac OS X executable format or in pre-Mac OS X executable format. You'll also need this pointer elsewhere in your program, so declaring this pointer globally makes sense:

NavEventUPP  gNavEventHandlerPtr;

Use the Navigation Services routine NewNavEventUPP to set this routine pointer variable to point to the Open dialog box event handler:

gNavEventHandlerPtr = NewNavEventUPP( MyNavEventCallback );   

Now it's time to make a call to the Navigation Services routine NavCreateGetFileDialog to create the Open dialog box. This routine requires seven arguments, many of which can typically get set to NULL. Here's the function prototype:

NavCreateGetFileDialog(
  const NavDialogCreationOptions *  inOptions,
  NavTypeListHandle                 inTypeList,
  NavEventUPP                       inEventProc,
  NavPreviewUPP                     inPreviewProc,
  NavObjectFilterUPP                inFilterProc,
  void *                            inClientData,
  NavDialogRef *                    outDialog );

Using the previously declared dialogAttributes and gNavEventHandlerPtr variables, here's how a call to NavCreateGetFileDialog could look:

NavDialogRef  openDialog;

err = NavCreateGetFileDialog( &dialogAttributes, NULL, 
                              gNavEventHandlerPtr, NULL, NULL, 
                              NULL, &openDialog );

The inOptions parameter is a pointer to the set of Open dialog box features that was returned by a prior call to NavGetDefaultDialogCreationOptions. In the preceding code snippet, dialogAttributes holds that set of default values, with the exception of the modality that was altered after NavGetDefaultDialogCreationOptions was called.

The inTypeList is a list of file types to display in the Open dialog box's browser; pass NULL to display all file types.

The inEventProc parameter is the procedure pointer that points to the Open dialog box's event handler routine. In the preceding snippet, the global UPP variable gNavEventHandlerPtr, which was assigned its value from a call to NewNavEventUPP, is used.

The next three arguments each can be set to NULL. The inPreviewProc parameter is a pointer to a custom file preview routine. The inFilterProc parameter is a pointer to a custom file filter routine. The inClientData parameter is a value that gets passed to either of the just-mentioned custom routines (if present). The preceding snippet uses NULL for each of these three arguments.

The last argument is a pointer to a variable of type NavDialogRef. After NavCreateGetFileDialog executes, this argument will hold a reference to the newly created Open dialog box.

NavCreateGetFileDialog creates an Open dialog box, but it doesn't display or control it. To do those chores, call the Navigation Services routine NavDialogRun:

err = NavDialogRun( openDialog );

NavDialogRun handles the user's interaction with the Open dialog box, so you don't need to write any code to follow the user's actions as he or she uses the dialog box to browse for a file to open. When the user clicks the Cancel or Open button, the application-defined event handler associated with this Open dialog box is called. In doing this, Navigation Services passes on information about the event that initiated the event handler call.

As you'll see a little later in this chapter, the event handler takes care of the opening of the selected file and the dismissing of the Open dialog box. Control then returns to the code that follows the call to NavDialogRun. That code should look something like this:

if ( err != noErr )
{
  NavDialogDispose( openDialog );
  DisposeNavEventUPP( gNavEventHandlerPtr );
}

If NavDialogRun completes without an error, your work is done. If there was an error, the variable err will have a nonzero (non-noErr) value. Your code should call the Navigation Services routines NavDialogDispose to dispose of the Open dialog box reference and DisposeNavEventUPP to dispose of the pointer to the Open dialog box event handler.

Whew. That covers the process of displaying and running the Open dialog box. Now it's time to take a look at all the code as it might appear in an application-defined routine that is used to enable a user to choose a file to open:

void DisplayOpenFileDialog( void )
{
  OSStatus                 err;
  NavDialogRef             openDialog;
  NavDialogCreationOptions dialogAttributes;

  err = NavGetDefaultDialogCreationOptions( &dialogAttributes );

  dialogAttributes.modality = kWindowModalityAppModal;   

  gNavEventHandlerPtr = NewNavEventUPP( MyNavEventCallback );   

  err = NavCreateGetFileDialog( &dialogAttributes, NULL, 
                 gNavEventHandlerPtr, NULL, NULL, 
                 NULL, &openDialog );

  err = NavDialogRun( openDialog );

  if ( err != noErr )
  {
   NavDialogDispose( openDialog );
   DisposeNavEventUPP( gNavEventHandlerPtr );
  }
}

Open Dialog Box Event Handler

After the user of an Open dialog box makes a final decision (by clicking the Cancel or Open button), the Open dialog box event handler is automatically invoked. When the system invokes this handler, the system passes information about the event initiated by the user's action:

pascal void MyNavEventCallback( 
                NavEventCallbackMessage callBackSelector,
                NavCBRecPtr             callBackParms, 
                void*                   callBackUD )

Your event handler uses the information in the callBackSelector argument to determine the action with which to deal. The bulk of the event handler consists of a switch statement that determines which of the primary dialog box-related tasks needs handling:

switch ( callBackSelector )
{
  case kNavCBUserAction: 
   // further determine which action took place (open or save)
   // handle the action (open or save selected file)
   break;

  case kNavCBTerminate:
   // clean up after the now-dismissed dialog
   break;
}

The main two tasks handled in the switch consist of a user action (kNavCBUserAction), such as the request to open a file, and the memory clean up (kNavCBTerminate), which is in response to the dismissal of the dialog box.

To respond to a user action, call the Navigation Services routine NavDialogGetReply. Pass this routine a reference to the dialog box that initiated the event and a pointer to a reply record. NavDialogGetReply will fill the reply record with information about the user's action (such as the file to open). The context field of the event handler argument callBackParms holds the dialog reference. Declare a variable of type NavReplyRecord to be used as the reply record:

OSStatus        err;
NavReplyRecord  reply;
NavUserAction   userAction = 0;   

err = NavDialogGetReply( callBackParms->context, &reply );

Now call NavDialogGetUserAction, passing this routine a reference to the affected dialog box. Once again, the context field of the callBackParams event handler argument is used. NavDialogGetUserAction tells your program the exact action the user took. In the case of an Open dialog box, you're looking for a user action of kNavUserActionOpen. Note that similar code is used to handle a Save dialog, and in such a case, you'd look for a user action of kNavUserActionSaveAs. Finish with a call to NavDisposeReply to dispose of the reply record.

userAction = NavDialogGetUserAction( callBackParms->context );

switch ( userAction )
{
  case kNavUserActionOpen:
  // open file here using reply record information
  break;
}
err = NavDisposeReply( &reply );

Note

The preceding code snippet includes one very vague comment. Obviously, some code needs to actually open the user-selected file, yet I've waved that chore off with a single comment. That's because the particulars of opening a file are specific to the type of file to open; a move file, a graphics file, and an application-defined file all require different code to be transformed from data on media to data in memory and finally to information displayed in a window. Later in this chapter, we'll jump into the general steps, and the detailed code, for opening one type of file: a QuickTime movie file.

You can put the just-described Open dialog box event handler code into a routine that looks like the one shown here:

pascal void MyOpenDialogEventCallback(
               NavEventCallbackMessage callBackSelector,
               NavCBRecPtr             callBackParms, 
               void*                   callBackUD )
{
  OSStatus     err;
  NavReplyRecord  reply;
  NavUserAction  userAction = 0;   

  switch ( callBackSelector )
  {
   case kNavCBUserAction:    
     err = NavDialogGetReply( callBackParms->context, &reply );
     userAction = NavDialogGetUserAction( callBackParms->context );   

     switch ( userAction )
     {
      case kNavUserActionOpen:
      // open file here using reply record information
      break;
     }
     err = NavDisposeReply( &reply );
     break;

   case kNavCBTerminate:
     NavDialogDispose( callBackParms->context );
     DisposeNavEventUPP( gNavEventHandlerPtr );
     break;
  }
}

The MyOpenDialogEventCallback routine is generic enough that it should work, with very little alteration, in your own file-opening program. Now all you need to do is replace the routine's one comment with a call to an application-defined function designed to open a file of the appropriate type. In the next section, you see how to write such a routine. The code for the application-defined function OpenOneQTMovieFile opens a QuickTime movie file. The OpenPlayMovie example then uses the MyOpenDialogEventCallback routine with a call to OpenOneQTMovieFile.

Peachpit Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from Peachpit and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about Peachpit products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites; develop new products and services; conduct educational research; and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email ask@peachpit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by Adobe Press. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.peachpit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020