Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Common Files/ComFramework.c
////////// |
// |
// File: ComFramework.c |
// |
// Contains: Code for the QuickTime sample code framework that is common to both Macintosh and Windows. |
// |
// Written by: Tim Monroe |
// Based on the QTShell code written by Tim Monroe, which in turn was based on the MovieShell |
// code written by Kent Sandvik (Apple DTS). This current version is now very far removed from |
// MovieShell. |
// |
// Copyright: © 1999-2000 by Apple Computer, Inc., all rights reserved. |
// |
// Change History (most recent first): |
// |
// <25> 02/12/01 rtm fixed stupid bug in QTFrame_PutFile (was calling NavDisposeReply before |
// reading data from reply record); d'oh! |
// <24> 02/01/01 rtm fixed *Proc names to *UPP, to conform to Universal Header 3.4b4 |
// <23> 11/24/00 rtm added QTFrame_GetWindowReferenceFromWindow |
// <22> 10/09/00 rtm added QTFrame_IsMovieWindow and QTFrame_IsImageWindow; reworked the function |
// QTFrame_SizeWindowToMovie to use these calls |
// <21> 10/02/00 rtm added code in QTFrame_SaveAsMovieFile to remove empty resource fork created |
// by FlattenMovieData; commented out calls to MakeFilePreview, since it always |
// adds a resource fork; will replace MakeFilePreview by QTInfo_MakeFilePreview |
// <20> 07/26/00 rtm converted gValidFileTypes into a handle (it was previously a pointer) |
// <19> 07/07/00 rtm further work on QTFrame_AdjustMenus and QTFrame_ConvertMacToWinMenuItemLabel |
// <18> 07/06/00 rtm added theModifiers parameter to QTFrame_AdjustMenus; updated it to support |
// modifier keys under Windows; added QTFrame_ConvertMacToWinMenuItemLabel |
// <17> 04/24/00 rtm added calls to MakeFilePreview |
// <16> 03/15/00 rtm modified QTFrame_SaveAsMovieFile to create a single-fork, self-contained, |
// interleaved, Fast Start movie |
// <15> 03/02/00 rtm made changes to get things running under CarbonLib |
// <14> 02/16/00 rtm added QTFrame_GetWindowPtrFromWindowReference |
// <13> 01/19/00 rtm revised QTFrame_IsAppWindow (dialog windows no longer count as application |
// windows); added QTFrame_BuildFileTypeList and QTFrame_AddComponentFileTypes |
// to avoid calling GetMovieImporterForDataRef in QTFrame_FilterFiles; removed |
// the hard-coded file types |
// <12> 01/14/00 rtm added support for graphics files, using graphics importers |
// <11> 12/28/99 rtm added QTFrame_ConvertMacToWinRect and QTFrame_ConvertWinToMacRect |
// <10> 12/21/99 rtm hard-coded some file types into QTFrame_FilterFiles; if we let QuickTime |
// to do all the testing (using GetMovieImporterForDataRef), it takes too long |
// <9> 12/17/99 rtm added some code to QTFrame_SetMenuItemState to work around a problem that |
// appears under MacOS 8.5.1 (as far as I can tell...) |
// <8> 12/16/99 rtm added QTApp_HandleMenu calls to _HandleFileMenuItem and _HandleEditMenuItem |
// to allow the application-specific code to intercept menu item selections; |
// added QTFrame_FilterFiles |
// <7> 12/15/99 rtm added QTApp_Idle call to QTFrame_IdleMovieWindows |
// <6> 12/11/99 rtm added GetMenuState call to Windows portion of QTFrame_SetMenuItemLabel; |
// tweaked _SizeWindowToMovie to guard against NULL movie and/or controller |
// <5> 11/30/99 rtm added QTFrame_CloseMovieWindows |
// <4> 11/27/99 rtm added QTFrame_GetFileFilterUPP |
// <3> 11/17/99 rtm finished support for Navigation Services; added QTFrame_IdleMovieWindows |
// <2> 11/16/99 rtm begun support for Navigation Services |
// <1> 11/05/99 rtm first file |
// |
// This file contains several kinds of functions: (1) functions that use completely cross-platform APIs and |
// which therefore can be compiled and run for both Mac and Windows platforms with no changes whatsoever (a |
// good example of this is QTFrame_SaveAsMovieFile); (2) functions that are substantially the same on both |
// platforms but which require several short platform-dependent #ifdef TARGET_OS_ blocks (a good example of |
// this is QTFrame_AdjustMenus); (3) functions that retrieve data from framework-specific data structures (a |
// good example of this is QTFrame_GetWindowObjectFromWindow); (4) functions that provide a platform-neutral |
// interface to platform-specific operations (a good example of this is QTFrame_Beep). In a nutshell, this |
// file attempts to provide platform-independent services to its callers, typically functions in the files |
// MacFramework.c, WinFramework.c, and ComApplication.c. |
// |
// In general, you should not need to modify this file. Your application-specific code should usually be put |
// into the file ComApplication.c. |
// |
////////// |
////////// |
// |
// header files |
// |
////////// |
#include "ComFramework.h" |
////////// |
// |
// global variables |
// |
////////// |
Rect gMCResizeBounds; // maximum size for any movie window |
Handle gValidFileTypes = NULL; // the list of file types that our application can open |
long gFirstGITypeIndex; // the index in gValidFileTypes of the first graphics importer file type |
#if TARGET_OS_WIN32 |
extern HWND ghWnd; |
extern HWND ghWndMDIClient; |
extern BOOL gWeAreSizingWindow; |
#endif |
#if TARGET_OS_MAC |
extern Str255 gAppName; |
void QTFrame_HandleEvent (EventRecord *theEvent); |
#endif |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
// |
// Menu-handling functions. |
// |
// Use these functions to handle items in the File and Edit menus. |
// |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
////////// |
// |
// QTFrame_HandleFileMenuItem |
// Handle the specified File menu item. |
// |
////////// |
void QTFrame_HandleFileMenuItem (WindowReference theWindow, UInt16 theMenuItem) |
{ |
// give the application-specific code a chance to intercept the menu item selection |
if (QTApp_HandleMenu(theMenuItem)) |
return; |
switch (theMenuItem) { |
case IDM_FILENEW: |
QTFrame_CreateNewMovie(); |
break; |
case IDM_FILEOPEN: |
QTFrame_OpenMovieInWindow(NULL, NULL); |
break; |
case IDM_FILECLOSE: |
QTFrame_DestroyMovieWindow(theWindow); |
break; |
case IDM_FILESAVE: |
QTFrame_UpdateMovieFile(theWindow); |
break; |
case IDM_FILESAVEAS: |
QTFrame_SaveAsMovieFile(theWindow); |
break; |
case IDM_EXIT: |
QTFrame_QuitFramework(); |
break; |
default: |
break; |
} // switch (theMenuItem) |
} |
////////// |
// |
// QTFrame_HandleEditMenuItem |
// Perform the specified edit operation on the specified window. |
// |
////////// |
void QTFrame_HandleEditMenuItem (WindowReference theWindow, UInt16 theMenuItem) |
{ |
WindowObject myWindowObject = NULL; |
MovieController myMC = NULL; |
Movie myEditMovie = NULL; // the movie created by some editing operations |
// give the application-specific code a chance to intercept the menu item selection |
if (QTApp_HandleMenu(theMenuItem)) |
return; |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
myMC = QTFrame_GetMCFromWindow(theWindow); |
// make sure we have a valid movie controller and a valid window object |
if ((myMC == NULL) || (myWindowObject == NULL)) |
return; |
switch (theMenuItem) { |
case IDM_EDITUNDO: |
MCUndo(myMC); |
(**myWindowObject).fIsDirty = true; |
break; |
case IDM_EDITCUT: |
myEditMovie = MCCut(myMC); |
(**myWindowObject).fIsDirty = true; |
break; |
case IDM_EDITCOPY: |
myEditMovie = MCCopy(myMC); |
break; |
case IDM_EDITPASTE: |
MCPaste(myMC, NULL); |
(**myWindowObject).fIsDirty = true; |
break; |
case IDM_EDITCLEAR: |
MCClear(myMC); |
(**myWindowObject).fIsDirty = true; |
break; |
case IDM_EDITSELECTALL: |
QTUtils_SelectAllMovie(myMC); |
break; |
case IDM_EDITSELECTNONE: |
QTUtils_SelectNoneMovie(myMC); |
break; |
default: |
break; |
} // switch (theMenuItem) |
// place any cut or copied movie segment onto the scrap |
if (myEditMovie != NULL) { |
PutMovieOnScrap(myEditMovie, 0L); |
DisposeMovie(myEditMovie); |
} |
// if the size of the movie might have changed, invalidate the entire movie box |
if ((theMenuItem == IDM_EDITUNDO) || (theMenuItem == IDM_EDITCUT) || (theMenuItem == IDM_EDITPASTE) || (theMenuItem == IDM_EDITCLEAR)) { |
Rect myRect; |
#if TARGET_OS_WIN32 |
RECT myWinRect; |
#endif |
MCGetControllerBoundsRect(myMC, &myRect); |
#if TARGET_OS_MAC |
InvalWindowRect(QTFrame_GetWindowFromWindowReference(theWindow), &myRect); |
#endif |
#if TARGET_OS_WIN32 |
QTFrame_ConvertMacToWinRect(&myRect, &myWinRect); |
InvalidateRect(theWindow, &myWinRect, false); |
#endif |
} |
} |
////////// |
// |
// QTFrame_AdjustMenus |
// Adjust the application's menus. |
// |
// On Windows, the theWindow parameter is a handle to the active MDI *child* window, if any. |
// On Mac, the theWindow parameter is a pointer to the frontmost window, if any. |
// |
////////// |
int QTFrame_AdjustMenus (WindowReference theWindow, MenuReference theMenu, long theModifiers) |
{ |
WindowObject myWindowObject = NULL; |
MovieController myMC = NULL; |
MenuReference myMenu = NULL; |
long myFlags = 0L; |
#if TARGET_OS_WIN32 |
myMenu = theMenu; |
#endif |
if (theWindow != NULL) |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
if (myWindowObject != NULL) |
myMC = (**myWindowObject).fController; |
////////// |
// |
// configure the Edit menu |
// |
////////// |
#if TARGET_OS_MAC |
myMenu = GetMenuHandle(kEditMenuResID); |
#endif |
if (myMC == NULL) { |
// if there is no movie controller, disable all the Edit menu items |
QTFrame_SetMenuItemState(myMenu, IDM_EDITUNDO, kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITCUT, kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITCOPY, kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITPASTE, kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITCLEAR, kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITSELECTALL, kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITSELECTNONE, kDisableMenuItem); |
} else { |
MCGetControllerInfo(myMC, &myFlags); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITSELECTALL, myFlags & mcInfoEditingEnabled ? kEnableMenuItem : kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITSELECTNONE, myFlags & mcInfoEditingEnabled ? kEnableMenuItem : kDisableMenuItem); |
#if TARGET_OS_MAC |
// on Macintosh, we can use the MCSetUpEditMenu function to handle the 5 standard Edit menu items |
MCSetUpEditMenu(myMC, theModifiers, myMenu); |
#endif |
#if TARGET_OS_WIN32 |
MCSetUpEditMenu(myMC, theModifiers, NULL); |
// on Windows, replicate the menu-updating functionality of MCSetUpEditMenu, as much as possible |
QTFrame_SetMenuItemState(myMenu, IDM_EDITUNDO, myFlags & mcInfoUndoAvailable ? kEnableMenuItem : kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITCUT, myFlags & mcInfoCutAvailable ? kEnableMenuItem : kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITCOPY, myFlags & mcInfoCopyAvailable ? kEnableMenuItem : kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITPASTE, myFlags & mcInfoPasteAvailable ? kEnableMenuItem : kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_EDITCLEAR, myFlags & mcInfoClearAvailable ? kEnableMenuItem : kDisableMenuItem); |
QTFrame_ConvertMacToWinMenuItemLabel(myMC, myMenu, theModifiers, IDM_EDITUNDO); |
QTFrame_ConvertMacToWinMenuItemLabel(myMC, myMenu, theModifiers, IDM_EDITCUT); |
QTFrame_ConvertMacToWinMenuItemLabel(myMC, myMenu, theModifiers, IDM_EDITCOPY); |
QTFrame_ConvertMacToWinMenuItemLabel(myMC, myMenu, theModifiers, IDM_EDITPASTE); |
QTFrame_ConvertMacToWinMenuItemLabel(myMC, myMenu, theModifiers, IDM_EDITCLEAR); |
#endif |
} |
////////// |
// |
// configure the File menu |
// |
////////// |
#if TARGET_OS_MAC |
myMenu = GetMenuHandle(kFileMenuResID); |
#endif |
if (theWindow != NULL) { // there is a window open |
// handle the Close command |
QTFrame_SetMenuItemState(myMenu, IDM_FILECLOSE, kEnableMenuItem); |
// handle the Save As and Save commands |
if (myWindowObject != NULL) { |
QTFrame_SetMenuItemState(myMenu, IDM_FILESAVEAS, kEnableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_FILESAVE, (**myWindowObject).fIsDirty ? kEnableMenuItem : kDisableMenuItem); |
} else { |
QTFrame_SetMenuItemState(myMenu, IDM_FILESAVEAS, kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_FILESAVE, kDisableMenuItem); |
} |
} else { // there is no window open |
QTFrame_SetMenuItemState(myMenu, IDM_FILESAVE, kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_FILESAVEAS, kDisableMenuItem); |
QTFrame_SetMenuItemState(myMenu, IDM_FILECLOSE, kDisableMenuItem); |
} |
// adjust any application-specific menus |
QTApp_AdjustMenus(theWindow, theMenu); |
return(0); |
} |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
// |
// Movie-handling functions. |
// |
// Use these functions to create new movies, open existing movies, save movies, and so forth. |
// |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
////////// |
// |
// QTFrame_CreateNewMovie |
// Create a new movie in a window; returns true if successful. |
// |
// NOTE: There are several user interface issues that are blissfully ignored by this routine, |
// principally the preferred names and the on-screen locations of the new windows. |
// |
////////// |
Boolean QTFrame_CreateNewMovie (void) |
{ |
Movie myMovie = NULL; |
FSSpec myFSSpec; |
StringPtr myName = QTUtils_ConvertCToPascalString(kNewMovieName); |
myMovie = NewMovie(newMovieActive); |
if (myMovie == NULL) |
return(false); |
// create a default FSSpec |
FSMakeFSSpec(0, 0L, myName, &myFSSpec); |
free(myName); |
return(QTFrame_OpenMovieInWindow(myMovie, &myFSSpec)); |
} |
////////// |
// |
// QTFrame_OpenMovieInWindow |
// Open a movie in a new movie window; return true if successful. |
// |
// This function is called from several places in our framework. The following combinations are possible: |
// * theMovie == NULL, theFSSpec == NULL: no movie, no file; elicit a movie file from user and open it |
// * theMovie != NULL, theFSSpec == NULL: new movie, no file (yet) |
// * theMovie == NULL, theFSSpec != NULL: no movie, but we have an FSSpec; so just open the specified movie file |
// * theMovie != NULL, theFSSpec != NULL: new movie, theFSSpec contains (at least) the movie name |
// |
////////// |
Boolean QTFrame_OpenMovieInWindow (Movie theMovie, FSSpec *theFSSpec) |
{ |
WindowObject myWindowObject = NULL; |
Movie myMovie = NULL; |
MovieController myMC = NULL; |
GraphicsImportComponent myImporter = NULL; |
WindowReference myWindow = NULL; |
FSSpec myFSSpec; |
short myRefNum = kInvalidFileRefNum; |
short myResID = 0; |
OSType myTypeList[] = {kQTFileTypeMovie, kQTFileTypeQuickTimeImage}; |
short myNumTypes = 2; |
GrafPtr mySavedPort; |
Rect myRect = {0, 0, 0, 0}; |
Point myPoint; |
QTFrameFileFilterUPP myFileFilterUPP = NULL; |
OSErr myErr = noErr; |
#if TARGET_OS_MAC |
myNumTypes = 0; |
#endif |
// get the current port; we may need to restore it if we cannot successfully create a new window |
GetPort(&mySavedPort); |
// if we got neither a movie nor an FSSpec passed in, prompt the user for a movie file |
if ((theMovie == NULL) && (theFSSpec == NULL)) { |
myFileFilterUPP = QTFrame_GetFileFilterUPP((ProcPtr)QTFrame_FilterFiles); |
myErr = QTFrame_GetOneFileWithPreview(myNumTypes, (QTFrameTypeListPtr)myTypeList, &myFSSpec, myFileFilterUPP); |
if (myFileFilterUPP != NULL) |
DisposeNavObjectFilterUPP(myFileFilterUPP); |
if (myErr != noErr) |
goto bail; |
} |
// if we got an FSSpec passed in, copy it into myFSSpec |
if (theFSSpec != NULL) { |
FSMakeFSSpec(theFSSpec->vRefNum, theFSSpec->parID, theFSSpec->name, &myFSSpec); |
} |
// if we got no movie passed in, read one from the specified file |
if (theMovie == NULL) { |
// see if the FSSpec picks out an image file; if so, skip the movie-opening code |
myErr = GetGraphicsImporterForFile(&myFSSpec, &myImporter); |
if (myImporter != NULL) |
goto gotImageFile; |
// ideally, we'd like read and write permission, but we'll settle for read-only permission |
myErr = OpenMovieFile(&myFSSpec, &myRefNum, fsRdWrPerm); |
if (myErr != noErr) |
myErr = OpenMovieFile(&myFSSpec, &myRefNum, fsRdPerm); |
// if we couldn't open the file with even just read-only permission, bail.... |
if (myErr != noErr) |
goto bail; |
// now fetch the first movie from the file |
myResID = 0; |
myErr = NewMovieFromFile(&myMovie, myRefNum, &myResID, NULL, newMovieActive, NULL); |
if (myErr != noErr) |
goto bail; |
} else { |
myMovie = theMovie; |
} |
////////// |
// |
// at this point, myMovie is an open movie, but myFSSpec may or may not be a valid FSSpec |
// |
////////// |
// set the default progress procedure for the movie |
SetMovieProgressProc(myMovie, (MovieProgressUPP)-1, 0); |
gotImageFile: |
// create a new window to display the movie in |
myWindow = QTFrame_CreateMovieWindow(); |
if (myWindow == NULL) |
goto bail; |
myWindowObject = QTFrame_GetWindowObjectFromWindow(myWindow); |
if (myWindowObject == NULL) |
goto bail; |
// set the window title |
QTFrame_SetWindowTitleFromFSSpec(myWindow, &myFSSpec, true); |
// make sure the movie or image file uses the window GWorld |
if (myMovie != NULL) |
SetMovieGWorld(myMovie, (CGrafPtr)QTFrame_GetPortFromWindowReference(myWindow), NULL); |
if (myImporter != NULL) |
GraphicsImportSetGWorld(myImporter, (CGrafPtr)QTFrame_GetPortFromWindowReference(myWindow), NULL); |
// create and configure the movie controller |
myMC = QTFrame_SetupController(myMovie, myWindow, true); |
// store movie info in the window record |
(**myWindowObject).fMovie = myMovie; |
(**myWindowObject).fController = myMC; |
(**myWindowObject).fGraphicsImporter = myImporter; |
(**myWindowObject).fFileResID = myResID; |
(**myWindowObject).fFileRefNum = myRefNum; |
(**myWindowObject).fCanResizeWindow = true; |
(**myWindowObject).fIsDirty = false; |
(**myWindowObject).fIsQTVRMovie = QTUtils_IsQTVRMovie(myMovie); |
(**myWindowObject).fInstance = NULL; |
(**myWindowObject).fAppData = NULL; |
(**myWindowObject).fFileFSSpec = myFSSpec; |
// do any application-specific window object initialization |
QTApp_SetupWindowObject(myWindowObject); |
// size the window to fit the movie and controller or image |
QTFrame_SizeWindowToMovie(myWindowObject); |
// set the movie's play hints to allow dynamic resizing |
SetMoviePlayHints(myMovie, hintsAllowDynamicResize, hintsAllowDynamicResize); |
// set the movie's position, if it has a 'WLOC' user data atom |
myErr = QTUtils_GetWindowPositionFromFile(myMovie, &myPoint); |
// show the window |
#if TARGET_OS_MAC |
MoveWindow(myWindow, myPoint.h, myPoint.v, false); |
ShowWindow(myWindow); |
SelectWindow(myWindow); // make it front-most, since it's just been created |
InvalWindowRect(myWindow, GetWindowPortBounds(myWindow, &myRect)); |
#endif |
#if TARGET_OS_WIN32 |
SetWindowPos(myWindow, 0, myPoint.h, myPoint.v, 0, 0, SWP_NOZORDER | SWP_NOSIZE); |
ShowWindow(myWindow, SW_SHOW); |
UpdateWindow(myWindow); |
#endif |
// if the movie is a streamed movie, then start it playing immediately |
if (QTUtils_IsStreamedMovie(myMovie)) |
MCDoAction(myMC, mcActionPrerollAndPlay, (void *)GetMoviePreferredRate(myMovie)); |
// if the movie is an autoplay movie, then start it playing immediately |
if (QTUtils_IsAutoPlayMovie(myMovie)) |
MCDoAction(myMC, mcActionPrerollAndPlay, (void *)GetMoviePreferredRate(myMovie)); |
return(true); |
bail: |
if (myWindow != NULL) |
#if TARGET_OS_MAC |
DisposeWindow(myWindow); |
#endif |
#if TARGET_OS_WIN32 |
SendMessage(ghWndMDIClient, WM_MDIDESTROY, (WPARAM)myWindow, 0L); |
#endif |
if (myMC != NULL) |
DisposeMovieController(myMC); |
if (myMovie != NULL) |
DisposeMovie(myMovie); |
if (myRefNum != 0) |
CloseMovieFile(myRefNum); |
if (myImporter != NULL) |
CloseComponent(myImporter); |
MacSetPort(mySavedPort); // restore the port that was active when this function was called |
return(false); |
} |
////////// |
// |
// QTFrame_SetupController |
// Create and configure the movie controller. |
// |
////////// |
MovieController QTFrame_SetupController (Movie theMovie, WindowReference theWindow, Boolean theMoveWindow) |
{ |
#if TARGET_OS_WIN32 |
#pragma unused(theMoveWindow) |
#endif |
MovieController myMC = NULL; |
Rect myRect; |
WindowObject myWindowObject = NULL; |
GrafPtr mySavedPort; |
if ((theMovie == NULL) || (theWindow == NULL)) |
return(NULL); |
// get our window specific data |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
if (myWindowObject == NULL) |
return(NULL); |
GetPort(&mySavedPort); |
MacSetPort(QTFrame_GetPortFromWindowReference(theWindow)); |
// resize the movie bounding rect and offset to 0,0 |
GetMovieBox(theMovie, &myRect); |
MacOffsetRect(&myRect, -myRect.left, -myRect.top); |
SetMovieBox(theMovie, &myRect); |
AlignWindow(QTFrame_GetWindowFromWindowReference(theWindow), false, &myRect, NULL); |
// create the movie controller |
myMC = NewMovieController(theMovie, &myRect, mcTopLeftMovie); |
if (myMC == NULL) |
return(NULL); |
// enable the default movie controller editing |
MCEnableEditing(myMC, true); |
// suppress movie badge |
MCDoAction(myMC, mcActionSetUseBadge, (void *)false); |
// set the initial looping state of the movie |
QTUtils_SetLoopingStateFromFile(theMovie, myMC); |
// install an action filter that does any application-specific movie controller action processing |
MCSetActionFilterWithRefCon(myMC, NewMCActionFilterWithRefConUPP(QTApp_MCActionFilterProc), (long)myWindowObject); |
// add grow box for the movie controller |
if ((**myWindowObject).fCanResizeWindow) { |
#if TARGET_OS_WIN32 |
RECT myRect; |
GetWindowRect(GetDesktopWindow(), &myRect); |
OffsetRect(&myRect, -myRect.left, -myRect.top); |
QTFrame_ConvertWinToMacRect(&myRect, &gMCResizeBounds); |
#endif |
#if TARGET_OS_MAC |
GetRegionBounds(GetGrayRgn(), &gMCResizeBounds); |
#endif |
MCDoAction(myMC, mcActionSetGrowBoxBounds, &gMCResizeBounds); |
} |
#if TARGET_OS_MAC |
if (theMoveWindow) |
MoveWindow(theWindow, kDefaultWindowX, kDefaultWindowY, false); |
#endif |
MacSetPort(mySavedPort); |
// add any application-specific controller functionality |
QTApp_SetupController(myMC); |
return(myMC); |
} |
////////// |
// |
// QTFrame_SaveAsMovieFile |
// Save the movie in the specified window under a new name. |
// |
// Human interface guidelines for "Save As..." dictate that, if the user selects a new file name |
// for the current movie, then that new file shall become the active one. This means that we need |
// to close the current movie file and open the new one. |
// |
////////// |
OSErr QTFrame_SaveAsMovieFile (WindowReference theWindow) |
{ |
WindowObject myWindowObject = NULL; |
Movie myMovie = NULL; |
FSSpec myFile; |
Boolean myIsSelected = false; |
Boolean myIsReplacing = false; |
StringPtr myPrompt = QTUtils_ConvertCToPascalString(kSavePrompt); |
StringPtr myFileName = QTUtils_ConvertCToPascalString(kSaveMovieFileName); |
OSErr myErr = paramErr; |
// get the window object associated with the specified window |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
if (myWindowObject == NULL) |
goto bail; |
myMovie = (**myWindowObject).fMovie; |
if (myMovie == NULL) |
goto bail; |
QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); |
if (myIsSelected) { |
Movie myNewMovie = NULL; |
MovieController myMC = NULL; |
short myRefNum = kInvalidFileRefNum; |
short myResID = movieInDataForkResID; |
////////// |
// |
// we have a valid FSSpec for the new movie file; now we want to flatten the existing |
// movie into the new movie file, then open the new movie file and read the movie out |
// of it; then we need to swap the window object data |
// |
////////// |
// delete any existing file of that name |
if (myIsReplacing) { |
myErr = DeleteMovieFile(&myFile); |
if (myErr != noErr) |
goto bail; |
} |
myNewMovie = FlattenMovieData( myMovie, |
flattenAddMovieToDataFork | flattenForceMovieResourceBeforeMovieData, |
&myFile, |
sigMoviePlayer, |
smSystemScript, |
createMovieFileDeleteCurFile | createMovieFileDontCreateResFile); |
myErr = GetMoviesError(); |
if ((myNewMovie == NULL) || (myErr != noErr)) |
goto bail; |
// FlattenMovieData creates a new movie file and returns the movie to us; but it doesn't |
// return the file reference number or the movie resource ID, which we want to have; so |
// we will dump the movie returned by FlattenMovieData and open the movie file ourselves |
DisposeMovie(myNewMovie); |
// also, on MacOS, FlattenMovieData *always* creates a resource fork, even if we told it |
// not to do so (didn't we say "createMovieFileDontCreateResFile"?); so we'll explicitly |
// delete the resource fork now.... |
#if TARGET_OS_MAC |
myErr = FSpOpenRF(&myFile, fsRdWrPerm, &myRefNum); |
if (myErr == noErr) { |
SetEOF(myRefNum, 0L); |
FSClose(myRefNum); |
} |
#endif |
myErr = OpenMovieFile(&myFile, &myRefNum, fsRdWrPerm); |
if (myErr != noErr) |
goto bail; |
// TO DO: use QTInfo_MakeFilePreview here, which doesn't always create a resource fork |
// MakeFilePreview(myRefNum, (ICMProgressProcRecordPtr)-1); |
// get the new movie from the file |
myErr = NewMovieFromFile(&myNewMovie, myRefNum, &myResID, NULL, newMovieActive, NULL); |
if (myErr != noErr) |
goto bail; |
// create a new movie controller |
myMC = QTFrame_SetupController(myNewMovie, theWindow, false); |
////////// |
// |
// if we got to here, we've successfully created a new movie file, and NewMovieFromFile has |
// returned the new movie to us; so we need to close down the current movie and install the |
// new movie in its place |
// |
////////// |
// close the existing movie file |
if ((**myWindowObject).fFileRefNum != kInvalidFileRefNum) |
CloseMovieFile((**myWindowObject).fFileRefNum); |
// dispose of the existing movie controller and movie resource |
if ((**myWindowObject).fController != NULL) |
DisposeMovieController((**myWindowObject).fController); |
DisposeMovie(myMovie); |
// keep track of the new info |
(**myWindowObject).fMovie = myNewMovie; |
(**myWindowObject).fController = myMC; |
(**myWindowObject).fFileFSSpec = myFile; |
(**myWindowObject).fFileResID = myResID; |
(**myWindowObject).fFileRefNum = myRefNum; |
(**myWindowObject).fIsDirty = false; |
// make sure the movie uses the window GWorld in all situations |
SetMovieGWorld(myNewMovie, (CGrafPtr)QTFrame_GetPortFromWindowReference((**myWindowObject).fWindow), NULL); |
// set the window title |
QTFrame_SetWindowTitleFromFSSpec(theWindow, &myFile, true); |
} else { |
myErr = userCanceledErr; |
} |
bail: |
free(myPrompt); |
free(myFileName); |
return(myErr); |
} |
////////// |
// |
// QTFrame_UpdateMovieFile |
// Update the file (if any) attached to the movie. |
// |
////////// |
Boolean QTFrame_UpdateMovieFile (WindowReference theWindow) |
{ |
WindowObject myWindowObject = NULL; |
Movie myMovie = NULL; |
OSErr myErr = noErr; |
// get the window object associated with the specified window |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
if (myWindowObject == NULL) |
return(false); |
myMovie = (**myWindowObject).fMovie; |
if (myMovie == NULL) |
return(false); |
// update the current volume setting |
QTUtils_UpdateMovieVolumeSetting(myMovie); |
if ((**myWindowObject).fFileRefNum == kInvalidFileRefNum) // brand new movie, so no file attached to it |
myErr = QTFrame_SaveAsMovieFile(theWindow); |
else // we have an existing file; just update the movie resource |
myErr = UpdateMovieResource(myMovie, (**myWindowObject).fFileRefNum, (**myWindowObject).fFileResID, NULL); |
// TO DO: use QTInfo_MakeFilePreview here, which doesn't always create a resource fork |
//MakeFilePreview((**myWindowObject).fFileRefNum, (ICMProgressProcRecordPtr)-1); |
(**myWindowObject).fIsDirty = false; |
return(myErr == noErr); |
} |
////////// |
// |
// QTFrame_IdleMovieWindows |
// Do idle-time processing on all open movie windows. |
// |
////////// |
void QTFrame_IdleMovieWindows (void) |
{ |
WindowReference myWindow = NULL; |
MovieController myMC = NULL; |
myWindow = QTFrame_GetFrontMovieWindow(); |
while (myWindow != NULL) { |
myMC = QTFrame_GetMCFromWindow(myWindow); |
if (myMC != NULL) |
MCIdle(myMC); |
QTApp_Idle(myWindow); |
myWindow = QTFrame_GetNextMovieWindow(myWindow); |
} |
} |
////////// |
// |
// QTFrame_CloseMovieWindows |
// Close all open movie windows. |
// |
////////// |
void QTFrame_CloseMovieWindows (void) |
{ |
#if TARGET_OS_MAC |
WindowReference myWindow = NULL; |
WindowReference myNextWindow = NULL; |
myWindow = QTFrame_GetFrontMovieWindow(); |
while (myWindow != NULL) { |
myNextWindow = QTFrame_GetNextMovieWindow(myWindow); |
QTFrame_DestroyMovieWindow(myWindow); |
myWindow = myNextWindow; |
} |
#endif |
#if TARGET_OS_WIN32 |
SendMessage(ghWnd, WM_COMMAND, (WPARAM)IDM_WINDOWCLOSEALL, 0L); |
#endif |
} |
////////// |
// |
// QTFrame_CreateWindowObject |
// Create a new window object associated with the specified window. |
// |
////////// |
void QTFrame_CreateWindowObject (WindowReference theWindow) |
{ |
WindowObject myWindowObject = NULL; |
if (theWindow == NULL) |
return; |
// allocate space for a window object record and fill in some of its fields |
myWindowObject = (WindowObject)NewHandleClear(sizeof(WindowObjectRecord)); |
if (myWindowObject != NULL) { |
(**myWindowObject).fWindow = theWindow; |
(**myWindowObject).fController = NULL; |
(**myWindowObject).fObjectType = kApplicationSignature; |
(**myWindowObject).fCanResizeWindow = true; |
(**myWindowObject).fInstance = NULL; |
(**myWindowObject).fIsDirty = false; |
(**myWindowObject).fAppData = NULL; |
} |
// associate myWindowObject (which may be NULL) with the window |
#if TARGET_OS_MAC |
SetWRefCon(theWindow, (long)myWindowObject); |
#endif |
#if TARGET_OS_WIN32 |
SetWindowLong(theWindow, GWL_USERDATA, (LPARAM)myWindowObject); |
// associate a GrafPort with this window |
CreatePortAssociation(theWindow, NULL, 0L); |
#endif |
// set the current port to the new window |
MacSetPort(QTFrame_GetPortFromWindowReference(theWindow)); |
} |
////////// |
// |
// QTFrame_CloseWindowObject |
// Close a window object and any associated data. |
// |
////////// |
void QTFrame_CloseWindowObject (WindowObject theWindowObject) |
{ |
if (theWindowObject == NULL) |
return; |
// close the movie file |
if ((**theWindowObject).fFileRefNum != kInvalidFileRefNum) { |
CloseMovieFile((**theWindowObject).fFileRefNum); |
(**theWindowObject).fFileRefNum = kInvalidFileRefNum; |
} |
// dispose movie controller and movie |
if ((**theWindowObject).fController != NULL) { |
MCSetActionFilterWithRefCon((**theWindowObject).fController, NULL, 0L); |
DisposeMovieController((**theWindowObject).fController); |
(**theWindowObject).fController = NULL; |
} |
if ((**theWindowObject).fMovie != NULL) { |
DisposeMovie((**theWindowObject).fMovie); |
(**theWindowObject).fMovie = NULL; |
} |
// close the graphics importer, if any |
if ((**theWindowObject).fGraphicsImporter != NULL) { |
CloseComponent((**theWindowObject).fGraphicsImporter); |
(**theWindowObject).fGraphicsImporter = NULL; |
} |
// do any application-specific window clean-up |
QTApp_RemoveWindowObject(theWindowObject); |
DisposeHandle((Handle)theWindowObject); |
} |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
// |
// Window-walking utilities. |
// |
// Use these functions to iterate through all windows or movie windows belonging to the application. |
// |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
////////// |
// |
// QTFrame_GetFrontAppWindow |
// Return a reference to the frontmost application window (whether or not it's a movie window). |
// |
////////// |
WindowReference QTFrame_GetFrontAppWindow (void) |
{ |
#if TARGET_OS_MAC |
return(FrontWindow()); |
#endif |
#if TARGET_OS_WIN32 |
return(GetWindow(ghWnd, GW_HWNDFIRST)); |
#endif |
} |
////////// |
// |
// QTFrame_GetNextAppWindow |
// Return a reference to the next application window (whether or not it's a movie window). |
// |
////////// |
WindowReference QTFrame_GetNextAppWindow (WindowReference theWindow) |
{ |
#if TARGET_OS_MAC |
return(theWindow == NULL ? NULL : GetNextWindow(theWindow)); |
#endif |
#if TARGET_OS_WIN32 |
return(GetWindow(theWindow, GW_HWNDNEXT)); |
#endif |
} |
////////// |
// |
// QTFrame_GetFrontMovieWindow |
// Return a reference to the frontmost movie window. |
// |
////////// |
WindowReference QTFrame_GetFrontMovieWindow (void) |
{ |
WindowReference myWindow; |
#if TARGET_OS_MAC |
myWindow = QTFrame_GetFrontAppWindow(); |
while ((myWindow != NULL) && (QTFrame_GetWindowObjectFromWindow(myWindow) == NULL)) |
myWindow = QTFrame_GetNextAppWindow(myWindow); |
#endif |
#if TARGET_OS_WIN32 |
myWindow = (HWND)SendMessage(ghWndMDIClient, WM_MDIGETACTIVE, 0, 0L); |
#endif |
return(myWindow); |
} |
////////// |
// |
// QTFrame_GetNextMovieWindow |
// Return a reference to the next movie window. |
// |
////////// |
WindowReference QTFrame_GetNextMovieWindow (WindowReference theWindow) |
{ |
WindowReference myWindow; |
#if TARGET_OS_MAC |
myWindow = QTFrame_GetNextAppWindow(theWindow); |
while ((myWindow != NULL) && (QTFrame_GetWindowObjectFromWindow(myWindow) == NULL)) |
myWindow = QTFrame_GetNextAppWindow(myWindow); |
#endif |
#if TARGET_OS_WIN32 |
myWindow = GetWindow(theWindow, GW_HWNDNEXT); |
#endif |
return(myWindow); |
} |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
// |
// Data-retrieval utilities. |
// |
// Use the following functions to retrieve the window object, the application-specific data, or the movie |
// controller that is associated with a window. |
// |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
////////// |
// |
// QTFrame_GetWindowObjectFromFrontWindow |
// Get the window object (if any) associated with the front window. |
// |
////////// |
WindowObject QTFrame_GetWindowObjectFromFrontWindow (void) |
{ |
return(QTFrame_GetWindowObjectFromWindow(QTFrame_GetFrontMovieWindow())); |
} |
////////// |
// |
// QTFrame_GetWindowObjectFromWindow |
// Get the window object (if any) associated with the specified window. |
// |
////////// |
WindowObject QTFrame_GetWindowObjectFromWindow (WindowReference theWindow) |
{ |
WindowObject myWindowObject = NULL; |
if (!QTFrame_IsAppWindow(theWindow)) |
return(NULL); |
#if TARGET_OS_MAC |
myWindowObject = (WindowObject)GetWRefCon(theWindow); |
#endif |
#if TARGET_OS_WIN32 |
myWindowObject = (WindowObject)GetWindowLong(theWindow, GWL_USERDATA); |
#endif |
// make sure this is a window object |
if (!QTFrame_IsWindowObjectOurs(myWindowObject)) |
return(NULL); |
return(myWindowObject); |
} |
////////// |
// |
// QTFrame_GetMCFromFrontWindow |
// Get the movie controller (if any) associated with the front window. |
// |
////////// |
MovieController QTFrame_GetMCFromFrontWindow (void) |
{ |
return(QTFrame_GetMCFromWindow(QTFrame_GetFrontMovieWindow())); |
} |
////////// |
// |
// QTFrame_GetMCFromWindow |
// Get the movie controller (if any) associated with the specified window. |
// |
////////// |
MovieController QTFrame_GetMCFromWindow (WindowReference theWindow) |
{ |
MovieController myMC = NULL; |
WindowObject myWindowObject = NULL; |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
if (myWindowObject != NULL) |
myMC = (**myWindowObject).fController; |
return(myMC); |
} |
////////// |
// |
// QTFrame_GetQTVRInstanceFromFrontWindow |
// Get the QTVRInstance (if any) associated with the front window. |
// |
////////// |
QTVRInstance QTFrame_GetQTVRInstanceFromFrontWindow (void) |
{ |
return(QTFrame_GetQTVRInstanceFromWindow(QTFrame_GetFrontMovieWindow())); |
} |
////////// |
// |
// QTFrame_GetQTVRInstanceFromWindow |
// Get the QTVRInstance (if any) associated with the specified window. |
// |
////////// |
QTVRInstance QTFrame_GetQTVRInstanceFromWindow (WindowReference theWindow) |
{ |
QTVRInstance myInstance = NULL; |
WindowObject myWindowObject = NULL; |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
if (myWindowObject != NULL) |
myInstance = (**myWindowObject).fInstance; |
return(myInstance); |
} |
////////// |
// |
// QTFrame_GetAppDataFromFrontWindow |
// Get the application-specific data associated with the front window. |
// |
////////// |
Handle QTFrame_GetAppDataFromFrontWindow (void) |
{ |
return(QTFrame_GetAppDataFromWindow(QTFrame_GetFrontMovieWindow())); |
} |
////////// |
// |
// QTFrame_GetAppDataFromWindow |
// Get the application-specific data associated with the specified window. |
// |
////////// |
Handle QTFrame_GetAppDataFromWindow (WindowReference theWindow) |
{ |
WindowObject myWindowObject = NULL; |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
if (myWindowObject == NULL) |
return(NULL); |
return(QTFrame_GetAppDataFromWindowObject(myWindowObject)); |
} |
////////// |
// |
// QTFrame_GetAppDataFromWindowObject |
// Get the application-specific data associated with the specified window object. |
// |
////////// |
Handle QTFrame_GetAppDataFromWindowObject (WindowObject theWindowObject) |
{ |
// make sure this is a window object belonging to our application |
if (!QTFrame_IsWindowObjectOurs(theWindowObject)) |
return(NULL); |
return((**theWindowObject).fAppData); |
} |
////////// |
// |
// QTFrame_IsWindowObjectOurs |
// Does the specified window object belong to our application? |
// |
////////// |
Boolean QTFrame_IsWindowObjectOurs (WindowObject theWindowObject) |
{ |
OSType myType = 0L; |
if ((theWindowObject == NULL) || (*theWindowObject == NULL)) |
return(false); |
myType = (**theWindowObject).fObjectType; |
return(myType == kApplicationSignature); |
} |
////////// |
// |
// QTFrame_IsAppWindow |
// Does the specified window belong to our application? |
// |
////////// |
Boolean QTFrame_IsAppWindow (WindowReference theWindow) |
{ |
if (theWindow == NULL) |
return(false); |
#if TARGET_OS_MAC |
return(GetWindowKind(theWindow) >= kApplicationWindowKind); |
#endif |
#if TARGET_OS_WIN32 |
return(true); |
#endif |
} |
////////// |
// |
// QTFrame_IsMovieWindow |
// Does the specified window contain a movie? |
// |
////////// |
Boolean QTFrame_IsMovieWindow (WindowReference theWindow) |
{ |
WindowObject myWindowObject = NULL; |
if (!QTFrame_IsAppWindow(theWindow)) |
return(false); |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
if (myWindowObject != NULL) |
return((**myWindowObject).fController != NULL); |
return(false); |
} |
////////// |
// |
// QTFrame_IsImageWindow |
// Does the specified window contain an image? |
// |
////////// |
Boolean QTFrame_IsImageWindow (WindowReference theWindow) |
{ |
WindowObject myWindowObject = NULL; |
if (!QTFrame_IsAppWindow(theWindow)) |
return(false); |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
if (myWindowObject != NULL) |
return((**myWindowObject).fGraphicsImporter != NULL); |
return(false); |
} |
////////// |
// |
// QTFrame_ActivateController |
// Activate or deactivate the movie controller in the specified window. |
// |
////////// |
void QTFrame_ActivateController (WindowReference theWindow, Boolean IsActive) |
{ |
WindowObject myWindowObject = NULL; |
MovieController myMC = NULL; |
GrafPtr mySavedPort = NULL; |
if (theWindow == NULL) |
return; |
GetPort(&mySavedPort); |
MacSetPort(QTFrame_GetPortFromWindowReference(theWindow)); |
// get the window object associated with the specified window |
myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow); |
if (myWindowObject != NULL) { |
myMC = (**myWindowObject).fController; |
if (myMC != NULL) |
MCActivate(myMC, QTFrame_GetWindowFromWindowReference(theWindow), IsActive); |
} |
MacSetPort(mySavedPort); |
} |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
// |
// Miscellaneous utilities. |
// |
// Use the following functions to play beeps, manipulate menus, and do other miscellaneous things. |
// |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
////////// |
// |
// QTFrame_Beep |
// Beep. |
// |
////////// |
void QTFrame_Beep (void) |
{ |
#if TARGET_OS_MAC |
SysBeep(30); |
#endif |
#if TARGET_OS_WIN32 |
MessageBeep(MB_OK); |
#endif |
} |
////////// |
// |
// QTFrame_SetMenuState |
// Set the enabled/disabled state of a menu. |
// |
// On Windows, the theMenuItem parameter must be the (0-based) index in the menu bar of the |
// desired pull-down menu. |
// |
////////// |
void QTFrame_SetMenuState (MenuReference theMenu, UInt16 theMenuItem, short theState) |
{ |
#if TARGET_OS_MAC |
#pragma unused(theMenuItem) |
QTFrame_SetMenuItemState(theMenu, 0, theState); // menu item == 0 means the entire menu |
#endif |
#if TARGET_OS_WIN32 |
QTFrame_SetMenuItemState(theMenu, theMenuItem, theState | MF_BYPOSITION); |
#endif |
} |
////////// |
// |
// QTFrame_SetMenuItemState |
// Set the enabled/disabled state of a menu item. |
// |
// When running under MacOS 8.5.1, EnableMenuItem and DisableMenuItem seem to do nasty things |
// to the keyboard equivalents associated with a menu; so we'll work around that problem here. |
// |
////////// |
void QTFrame_SetMenuItemState (MenuReference theMenu, UInt16 theMenuItem, short theState) |
{ |
#if TARGET_OS_MAC |
UInt8 myModifiers; |
// get the existing menu item modifiers |
GetMenuItemModifiers(theMenu, MENU_ITEM(theMenuItem), &myModifiers); |
if (theState == kEnableMenuItem) |
EnableMenuItem(theMenu, MENU_ITEM(theMenuItem)); |
else |
DisableMenuItem(theMenu, MENU_ITEM(theMenuItem)); |
// restore the previous menu item modifiers |
SetMenuItemModifiers(theMenu, MENU_ITEM(theMenuItem), myModifiers); |
#endif |
#if TARGET_OS_WIN32 |
EnableMenuItem(theMenu, (UINT)theMenuItem, (UINT)theState); |
#endif |
} |
////////// |
// |
// QTFrame_SetMenuItemLabel |
// Set the label (that is, the text) of a menu item. |
// |
////////// |
void QTFrame_SetMenuItemLabel (MenuReference theMenu, UInt16 theMenuItem, char *theText) |
{ |
#if TARGET_OS_MAC |
Str255 myString; |
short mySIndex, myTIndex; |
// we need to remove the '&' character while converting to a Pascal string |
mySIndex = 1; |
for (myTIndex = 0; myTIndex < strlen(theText); myTIndex++) { |
if (theText[myTIndex] != '&') { |
myString[mySIndex] = theText[myTIndex]; |
mySIndex++; |
} |
} |
myString[0] = mySIndex - 1; |
SetMenuItemText(theMenu, MENU_ITEM(theMenuItem), myString); |
#endif |
#if TARGET_OS_WIN32 |
UINT myState; |
// make sure that we preserve the current menu state |
myState = GetMenuState(theMenu, (UINT)theMenuItem, MF_BYCOMMAND); |
ModifyMenu(theMenu, (UINT)theMenuItem, MF_BYCOMMAND | MF_STRING | myState, (UINT)theMenuItem, (LPSTR)theText); |
#endif |
} |
////////// |
// |
// QTFrame_SetMenuItemCheck |
// Set the check mark state state of a menu item. |
// |
////////// |
void QTFrame_SetMenuItemCheck (MenuReference theMenu, UInt16 theMenuItem, Boolean theState) |
{ |
#if TARGET_OS_MAC |
MacCheckMenuItem(theMenu, MENU_ITEM(theMenuItem), theState); |
#endif |
#if TARGET_OS_WIN32 |
CheckMenuItem(theMenu, (UINT)theMenuItem, theState ? MF_CHECKED : MF_UNCHECKED); |
#endif |
} |
////////// |
// |
// QTFrame_GetPortFromWindowReference |
// Return the graphics port associated with a window reference. |
// |
////////// |
GrafPtr QTFrame_GetPortFromWindowReference (WindowReference theWindow) |
{ |
#if TARGET_OS_MAC |
return((GrafPtr)GetWindowPort(theWindow)); |
#endif |
#if TARGET_OS_WIN32 |
return(GetNativeWindowPort(theWindow)); |
#endif |
} |
////////// |
// |
// QTFrame_GetWindowReferenceFromPort |
// Return the window reference associated with a graphics port. |
// |
////////// |
WindowReference QTFrame_GetWindowReferenceFromPort (GrafPtr thePort) |
{ |
#if TARGET_OS_MAC |
return((WindowReference)GetWindowFromPort((CGrafPtr)thePort)); |
#endif |
#if TARGET_OS_WIN32 |
return((WindowReference)GetPortNativeWindow(thePort)); |
#endif |
} |
////////// |
// |
// QTFrame_GetWindowFromWindowReference |
// Return the Macintosh window associated with a window reference. |
// |
////////// |
WindowPtr QTFrame_GetWindowFromWindowReference (WindowReference theWindow) |
{ |
#if TARGET_OS_MAC |
return((WindowPtr)theWindow); |
#endif |
#if TARGET_OS_WIN32 |
return((WindowPtr)GetNativeWindowPort(theWindow)); |
#endif |
} |
////////// |
// |
// QTFrame_GetWindowReferenceFromWindow |
// Return the window reference associated with a Macintosh window. |
// |
////////// |
WindowReference QTFrame_GetWindowReferenceFromWindow (WindowPtr theWindow) |
{ |
#if TARGET_OS_MAC |
return((WindowReference)theWindow); |
#endif |
#if TARGET_OS_WIN32 |
return((WindowReference)GetPortNativeWindow((GrafPtr)theWindow)); |
#endif |
} |
///////// |
// |
// QTFrame_GetWindowWidth |
// Return the width of the specified window. |
// |
////////// |
short QTFrame_GetWindowWidth (WindowReference theWindow) |
{ |
#if TARGET_OS_MAC |
Rect myRect = {0, 0, 0, 0}; |
if (theWindow != NULL) |
GetWindowPortBounds(theWindow, &myRect); |
#endif |
#if TARGET_OS_WIN32 |
RECT myRect = {0L, 0L, 0L, 0L}; |
if (theWindow != NULL) |
GetWindowRect(theWindow, &myRect); |
#endif |
return((short)(myRect.right - myRect.left)); |
} |
////////// |
// |
// QTFrame_SetWindowTitleFromFSSpec |
// Set the title of the specified window, using the name contained in the specified FSSpec. |
// |
////////// |
void QTFrame_SetWindowTitleFromFSSpec (WindowReference theWindow, FSSpecPtr theFSSpecPtr, Boolean theAddToRecentDocs) |
{ |
#if TARGET_OS_MAC |
#pragma unused(theAddToRecentDocs) |
SetWTitle(theWindow, theFSSpecPtr->name); |
#endif |
#if TARGET_OS_WIN32 |
char *myTempName; |
char myWindName[MAX_PATH]; |
// get the full pathname contained in the FSSpec (which is a Str255) |
myTempName = QTUtils_ConvertPascalToCString(theFSSpecPtr->name); |
// get the movie file name from the full pathname |
QTFrame_GetDisplayName(myTempName, myWindName); |
// set the window title |
SetWindowText(theWindow, myWindName); |
// add this document to the Documents list, if so instructed |
if (theAddToRecentDocs) |
SHAddToRecentDocs(SHARD_PATH, myTempName); |
free(myTempName); |
#endif |
} |
////////// |
// |
// QTFrame_SizeWindowToMovie |
// Set the window size to exactly fit the movie and controller (if visible) or the image. |
// |
////////// |
void QTFrame_SizeWindowToMovie (WindowObject theWindowObject) |
{ |
Rect myRect; |
#if TARGET_OS_WIN32 |
gWeAreSizingWindow = true; |
#endif |
if (theWindowObject == NULL) |
goto bail; |
if (QTFrame_IsImageWindow((**theWindowObject).fWindow)) { |
// it's an image window |
GraphicsImportGetBoundsRect((**theWindowObject).fGraphicsImporter, &myRect); |
} else if (QTFrame_IsMovieWindow((**theWindowObject).fWindow)) { |
// it's a movie window |
GetMovieBox((**theWindowObject).fMovie, &myRect); |
if ((**theWindowObject).fController != NULL) |
if (MCGetVisible((**theWindowObject).fController)) |
MCGetControllerBoundsRect((**theWindowObject).fController, &myRect); |
// make sure that the movie has a non-zero width; |
// a zero height is okay (for example, with a music movie with no controller bar) |
if (myRect.right - myRect.left == 0) { |
myRect.left = 0; |
myRect.right = QTFrame_GetWindowWidth((**theWindowObject).fWindow); |
} |
} else { |
// it's neither an image window nor a movie window; punt |
goto bail; |
} |
SizeWindow(QTFrame_GetWindowFromWindowReference((**theWindowObject).fWindow), |
myRect.right - myRect.left, |
myRect.bottom - myRect.top, |
true); |
bail: |
#if TARGET_OS_WIN32 |
gWeAreSizingWindow = false; |
#endif |
return; |
} |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
// |
// File-opening and -saving utilities. |
// |
// The functions are meant to provide replacements for StandardGetFilePreview and StandardPutFile, which |
// are not supported under Carbon. However, Navigation Services is not (yet, at any rate) supported under |
// Windows, so we still need to call through to the Standard File Package. |
// |
// The Navigation Services portion of this code is based selectively on the file NavigationServicesSupport.c |
// by Yan Arrouye and on the developer documentation "Programming With Navigation Services 1.1". The code that |
// determines which files can be opened by QuickTime is based on code by Sam Bushell in CarbonMovieEditor.c. |
// |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
////////// |
// |
// QTFrame_PutFile |
// Save a file under the specified name. Return Boolean values indicating whether the user selected a file |
// and whether the selected file is replacing an existing file. |
// |
////////// |
OSErr QTFrame_PutFile (ConstStr255Param thePrompt, ConstStr255Param theFileName, FSSpecPtr theFSSpecPtr, Boolean *theIsSelected, Boolean *theIsReplacing) |
{ |
#if TARGET_OS_WIN32 |
StandardFileReply myReply; |
#endif |
#if TARGET_OS_MAC |
NavReplyRecord myReply; |
NavDialogOptions myDialogOptions; |
NavEventUPP myEventUPP = NewNavEventUPP(QTFrame_HandleNavEvent); |
#endif |
OSErr myErr = noErr; |
if ((theFSSpecPtr == NULL) || (theIsSelected == NULL) || (theIsReplacing == NULL)) |
return(paramErr); |
// deactivate any frontmost movie window |
QTFrame_ActivateController(QTFrame_GetFrontMovieWindow(), false); |
// assume we are not replacing an existing file |
*theIsReplacing = false; |
#if TARGET_OS_WIN32 |
StandardPutFile(thePrompt, theFileName, &myReply); |
*theFSSpecPtr = myReply.sfFile; |
*theIsSelected = myReply.sfGood; |
if (myReply.sfGood) |
*theIsReplacing = myReply.sfReplacing; |
#endif |
#if TARGET_OS_MAC |
// specify the options for the dialog box |
NavGetDefaultDialogOptions(&myDialogOptions); |
myDialogOptions.dialogOptionFlags += kNavNoTypePopup; |
myDialogOptions.dialogOptionFlags += kNavDontAutoTranslate; |
BlockMoveData(theFileName, myDialogOptions.savedFileName, theFileName[0] + 1); |
BlockMoveData(gAppName, myDialogOptions.clientName, gAppName[0] + 1); |
BlockMoveData(thePrompt, myDialogOptions.message, thePrompt[0] + 1); |
// prompt the user for a file |
myErr = NavPutFile(NULL, &myReply, &myDialogOptions, myEventUPP, MovieFileType, sigMoviePlayer, NULL); |
if ((myErr == noErr) && myReply.validRecord) { |
AEKeyword myKeyword; |
DescType myActualType; |
Size myActualSize = 0; |
// get the FSSpec for the selected file |
if (theFSSpecPtr != NULL) |
myErr = AEGetNthPtr(&(myReply.selection), 1, typeFSS, &myKeyword, &myActualType, theFSSpecPtr, sizeof(FSSpec), &myActualSize); |
} |
*theIsSelected = myReply.validRecord; |
if (myReply.validRecord) |
*theIsReplacing = myReply.replacing; |
NavDisposeReply(&myReply); |
DisposeNavEventUPP(myEventUPP); |
#endif |
return(myErr); |
} |
////////// |
// |
// QTFrame_GetOneFileWithPreview |
// Display the appropriate file-opening dialog box, with an optional QuickTime preview pane. If the user |
// selects a file, return information about it using the theFSSpecPtr parameter. |
// |
// Note that both StandardGetFilePreview and NavGetFile use the function specified by theFilterProc as a |
// file filter. This framework always passes NULL in the theFilterProc parameter. If you use this function |
// in your own code, keep in mind that on Windows the function specifier must be of type FileFilterUPP and |
// on Macintosh it must be of type NavObjectFilterUPP. (You can use the QTFrame_GetFileFilterUPP to create |
// a function specifier of the appropriate type.) Also keep in mind that Navigation Services expects a file |
// filter function to return true if a file is to be displayed, while the Standard File Package expects the |
// filter to return false if a file is to be displayed. |
// |
////////// |
OSErr QTFrame_GetOneFileWithPreview (short theNumTypes, QTFrameTypeListPtr theTypeList, FSSpecPtr theFSSpecPtr, void *theFilterProc) |
{ |
#if TARGET_OS_WIN32 |
StandardFileReply myReply; |
#endif |
#if TARGET_OS_MAC |
NavReplyRecord myReply; |
NavDialogOptions myDialogOptions; |
NavTypeListHandle myOpenList = NULL; |
NavEventUPP myEventUPP = NewNavEventUPP(QTFrame_HandleNavEvent); |
#endif |
OSErr myErr = noErr; |
if (theFSSpecPtr == NULL) |
return(paramErr); |
// deactivate any frontmost movie window |
QTFrame_ActivateController(QTFrame_GetFrontMovieWindow(), false); |
#if TARGET_OS_WIN32 |
// prompt the user for a file |
StandardGetFilePreview((FileFilterUPP)theFilterProc, theNumTypes, (ConstSFTypeListPtr)theTypeList, &myReply); |
if (!myReply.sfGood) |
return(userCanceledErr); |
// make an FSSpec record |
myErr = FSMakeFSSpec(myReply.sfFile.vRefNum, myReply.sfFile.parID, myReply.sfFile.name, theFSSpecPtr); |
#endif |
#if TARGET_OS_MAC |
// specify the options for the dialog box |
NavGetDefaultDialogOptions(&myDialogOptions); |
myDialogOptions.dialogOptionFlags -= kNavNoTypePopup; |
myDialogOptions.dialogOptionFlags -= kNavAllowMultipleFiles; |
BlockMoveData(gAppName, myDialogOptions.clientName, gAppName[0] + 1); |
// create a handle to an 'open' resource |
myOpenList = (NavTypeListHandle)QTFrame_CreateOpenHandle(kApplicationSignature, theNumTypes, theTypeList); |
if (myOpenList != NULL) |
HLock((Handle)myOpenList); |
// prompt the user for a file |
myErr = NavGetFile(NULL, &myReply, &myDialogOptions, myEventUPP, NULL, (NavObjectFilterUPP)theFilterProc, myOpenList, NULL); |
if ((myErr == noErr) && myReply.validRecord) { |
AEKeyword myKeyword; |
DescType myActualType; |
Size myActualSize = 0; |
// get the FSSpec for the selected file |
if (theFSSpecPtr != NULL) |
myErr = AEGetNthPtr(&(myReply.selection), 1, typeFSS, &myKeyword, &myActualType, theFSSpecPtr, sizeof(FSSpec), &myActualSize); |
NavDisposeReply(&myReply); |
} |
if (myOpenList != NULL) { |
HUnlock((Handle)myOpenList); |
DisposeHandle((Handle)myOpenList); |
} |
DisposeNavEventUPP(myEventUPP); |
#endif |
return(myErr); |
} |
////////// |
// |
// QTFrame_HandleNavEvent |
// A callback procedure that handles events while a Navigation Service dialog box is displayed. |
// |
////////// |
PASCAL_RTN void QTFrame_HandleNavEvent (NavEventCallbackMessage theCallBackSelector, NavCBRecPtr theCallBackParms, void *theCallBackUD) |
{ |
#pragma unused(theCallBackUD) |
if (theCallBackParms == NULL) |
return; |
if (theCallBackParms->eventData.eventDataParms.event == NULL) |
return; |
if (theCallBackSelector == kNavCBEvent) { |
switch (theCallBackParms->eventData.eventDataParms.event->what) { |
case updateEvt: |
case activateEvt: |
#if TARGET_OS_MAC |
QTFrame_HandleEvent(theCallBackParms->eventData.eventDataParms.event); |
#endif |
break; |
case nullEvent: |
QTFrame_IdleMovieWindows(); |
break; |
} |
} |
} |
////////// |
// |
// QTFrame_CreateOpenHandle |
// Return a handle to a dynamically-created 'open' resource. |
// |
////////// |
Handle QTFrame_CreateOpenHandle (OSType theApplicationSignature, short theNumTypes, QTFrameTypeListPtr theTypeList) |
{ |
Handle myHandle = NULL; |
if (theTypeList == NULL) |
return(myHandle); |
if (theNumTypes > 0) { |
myHandle = NewHandle(sizeof(NavTypeList) + (theNumTypes * sizeof(OSType))); |
if (myHandle != NULL) { |
NavTypeListHandle myOpenResHandle = (NavTypeListHandle)myHandle; |
(*myOpenResHandle)->componentSignature = theApplicationSignature; |
(*myOpenResHandle)->osTypeCount = theNumTypes; |
BlockMoveData(theTypeList, (*myOpenResHandle)->osType, theNumTypes * sizeof(OSType)); |
} |
} |
return(myHandle); |
} |
////////// |
// |
// QTFrame_GetFileFilterUPP |
// Return a UPP for the specified file-selection filter function. |
// |
// The caller is responsible for disposing of the UPP returned by this function (by calling DisposeNavObjectFilterUPP). |
// |
////////// |
QTFrameFileFilterUPP QTFrame_GetFileFilterUPP (ProcPtr theFileFilterProc) |
{ |
#if TARGET_OS_MAC |
return(NewNavObjectFilterUPP((NavObjectFilterProcPtr)theFileFilterProc)); |
#endif |
#if TARGET_OS_WIN32 |
return(NewFileFilterProc(theFileFilterProc)); |
#endif |
} |
////////// |
// |
// QTFrame_FilterFiles |
// Filter files for a file-opening dialog box. |
// |
// The default behavior here is to accept all files that can be opened by QuickTime, whether directly |
// or using a movie importer or a graphics importer. |
// |
////////// |
#if TARGET_OS_MAC |
PASCAL_RTN Boolean QTFrame_FilterFiles (AEDesc *theItem, void *theInfo, void *theCallBackUD, NavFilterModes theFilterMode) |
{ |
#pragma unused(theCallBackUD, theFilterMode) |
NavFileOrFolderInfo *myInfo = (NavFileOrFolderInfo *)theInfo; |
if (gValidFileTypes == NULL) |
QTFrame_BuildFileTypeList(); |
if (theItem->descriptorType == typeFSS) { |
if (!myInfo->isFolder) { |
OSType myType = myInfo->fileAndFolder.fileInfo.finderInfo.fdType; |
OSType *myTypes = (OSType *)*gValidFileTypes; |
short myCount; |
short myIndex; |
// see whether the file type is in the list of file types that our application can open |
myCount = GetHandleSize(gValidFileTypes) / sizeof(OSType); |
for (myIndex = 0; myIndex < myCount; myIndex++) |
if (myType == myTypes[myIndex]) |
return(true); |
// if we got to here, it's a file we cannot open |
return(false); |
} |
} |
// if we got to here, it's a folder or non-HFS object |
return(true); |
} |
#endif |
#if TARGET_OS_WIN32 |
PASCAL_RTN Boolean QTFrame_FilterFiles (CInfoPBPtr thePBPtr) |
{ |
#pragma unused(thePBPtr) |
return(false); |
} |
#endif |
////////// |
// |
// QTFrame_BuildFileTypeList |
// Build a list of file types that QuickTime can open. |
// |
////////// |
OSErr QTFrame_BuildFileTypeList (void) |
{ |
long myIndex = 0; |
OSType *myTypes; |
// if we've already built the list, just return |
if (gValidFileTypes != NULL) |
return(noErr); |
// allocate a block of memory to hold a preset number of file types; we'll resize this block |
// while building the list if we need more room; we always resize it after building the list, |
// to truncate it to the exact size required |
gValidFileTypes = NewHandleClear(sizeof(OSType) * kDefaultFileTypeCount); |
if (gValidFileTypes == NULL) |
return(memFullErr); |
myTypes = (OSType *)*gValidFileTypes; |
// we can open any files of type kQTFileTypeMovie |
myTypes[myIndex++] = kQTFileTypeMovie; |
// we can open any files for which QuickTime supplies a movie importer component |
QTFrame_AddComponentFileTypes(MovieImportType, &myIndex); |
// we can open any files for which QuickTime supplies a graphics importer component |
gFirstGITypeIndex = myIndex; |
QTFrame_AddComponentFileTypes(GraphicsImporterComponentType, &myIndex); |
// resize the pointer to hold the exact number of valid file types |
SetHandleSize(gValidFileTypes, myIndex * sizeof(OSType)); |
return(MemError()); |
} |
////////// |
// |
// QTFrame_AddComponentFileTypes |
// Add all subtypes of the specified component type to the global list of file types. |
// |
////////// |
static void QTFrame_AddComponentFileTypes (OSType theComponentType, long *theNextIndex) |
{ |
ComponentDescription myFindCompDesc = {0, 0, 0, 0, 0}; |
ComponentDescription myInfoCompDesc = {0, 0, 0, 0, 0}; |
Component myComponent = NULL; |
OSType *myTypes = NULL; |
myFindCompDesc.componentType = theComponentType; |
myFindCompDesc.componentFlags = 0; |
myFindCompDesc.componentFlagsMask = movieImportSubTypeIsFileExtension; |
myComponent = FindNextComponent(myComponent, &myFindCompDesc); |
while (myComponent != NULL) { |
GetComponentInfo(myComponent, &myInfoCompDesc, NULL, NULL, NULL); |
if (gValidFileTypes == NULL) |
return; |
myTypes = (OSType *)*gValidFileTypes; |
myTypes[*theNextIndex] = myInfoCompDesc.componentSubType; |
*theNextIndex += 1; |
// resize the block of file types, if we are about to reach the limit |
if (*theNextIndex == GetHandleSize(gValidFileTypes) / (long)sizeof(OSType)) { |
SetHandleSize(gValidFileTypes, GetHandleSize(gValidFileTypes) + (kDefaultFileTypeCount * sizeof(OSType))); |
if (MemError() != noErr) |
return; |
} |
myComponent = FindNextComponent(myComponent, &myFindCompDesc); |
} |
} |
#if TARGET_OS_WIN32 |
////////// |
// |
// QTFrame_ConvertMacToWinRect |
// Convert a Macintosh Rect structure into a Windows RECT structure. |
// |
////////// |
void QTFrame_ConvertMacToWinRect (Rect *theMacRect, RECT *theWinRect) |
{ |
theWinRect->top = (long)theMacRect->top; |
theWinRect->left = (long)theMacRect->left; |
theWinRect->bottom = (long)theMacRect->bottom; |
theWinRect->right = (long)theMacRect->right; |
} |
////////// |
// |
// QTFrame_ConvertWinToMacRect |
// Convert a Windows RECT structure into a Macintosh Rect structure. |
// |
////////// |
void QTFrame_ConvertWinToMacRect (RECT *theWinRect, Rect *theMacRect) |
{ |
theMacRect->top = (short)theWinRect->top; |
theMacRect->left = (short)theWinRect->left; |
theMacRect->bottom = (short)theWinRect->bottom; |
theMacRect->right = (short)theWinRect->right; |
} |
////////// |
// |
// QTFrame_ConvertMacToWinMenuItemLabel |
// Convert a Mac menu item label into its Windows equivalent. |
// |
////////// |
void QTFrame_ConvertMacToWinMenuItemLabel (MovieController theMC, MenuReference theWinMenu, long theModifiers, UInt16 theMenuItem) |
{ |
Str255 myString; |
char *myLabelText = NULL; |
char *myBeginText = NULL; |
char *myFinalText = NULL; |
short myLabelSize = 0; |
// get the appropriate label for the specified item and keyboard modifiers |
MCGetMenuString(theMC, theModifiers, MENU_ITEM(theMenuItem), myString); |
switch (theMenuItem) { |
case IDM_EDITUNDO: |
myBeginText = kAmpersandText; |
myFinalText = kWinUndoAccelerator; |
break; |
case IDM_EDITPASTE: |
myBeginText = ""; |
myFinalText = kWinPasteAccelerator; |
// note that we are not inserting any ampersand anywhere in this label, |
// so the Alt-key search will use the first letter of the label (which |
// may conflict with some other Alt-key letter); fixing this is left as |
// an exercise for the reader |
break; |
case IDM_EDITCLEAR: |
myBeginText = kAmpersandText; |
myFinalText = kWinClearAccelerator; |
break; |
default: |
// currently, only the Undo, Paste, and Clear items are modified by MCSetUpEditMenu, |
// so that's all we'll handle here; by returning, we leave the existing label intact |
return; |
} |
myLabelSize = strlen(myBeginText) + myString[0] + strlen(myFinalText) + 1; |
myLabelText = malloc(myLabelSize); |
if (myLabelText == NULL) |
return; |
BlockMove(myBeginText, myLabelText, strlen(myBeginText)); |
BlockMove(&myString[1], myLabelText + strlen(myBeginText), myString[0]); |
BlockMove(myFinalText, myLabelText + strlen(myBeginText) + myString[0], strlen(myFinalText)); |
myLabelText[myLabelSize - 1] = '\0'; |
QTFrame_SetMenuItemLabel(theWinMenu, theMenuItem, myLabelText); |
free(myLabelText); |
} |
#endif // TARGET_OS_WIN32 |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14