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.
SettingUpStdFile.c
/* |
File: SettingUpStdFile.c |
Contains: This snippet demonstrates how to make Standard File |
select an initial file under both System 6 and System 7. |
(In this example, the System file will be selected.) |
"An exhilirating snippet" |
- Nitin Ganatra |
Written by: Greg Robbins |
Copyright: Copyright © 1993-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/1/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
sfScript is reset in the System 7 DialogHook (below) to work |
around a gotcha in Standard File that's incorrectly documented in |
a New Inside Macintosh: Files sample. See the DialogHook() function |
for details. |
2/94 Nitin Ganatra Compatible with the Universal Interfaces. |
*/ |
#include <QuickDraw.h> |
#include <StandardFile.h> |
#include <Fonts.h> |
#include <Menus.h> |
#include <Dialogs.h> |
#include <Events.h> |
#include <GestaltEqu.h> |
#include <TextEdit.h> |
#include <Errors.h> |
#include <OSEvents.h> |
#include <Folders.h> |
#include <Memory.h> |
#include <Script.h> |
#include <LowMem.h> |
// prototypes |
pascal short DialogHook(short, DialogPtr , void *); |
pascal short OldDlgHook(short, DialogPtr); |
OSErr GetSystemFileSpec(FSSpecPtr); |
// global struct for System 7 Std File dialog hook |
typedef struct { |
StandardFileReply *theSFR; |
FSSpec *itemSpec; |
} HookRecord, *HookRecordPtr; |
// globals for System 6 Std File stuff |
StringPtr gSelectFileName; |
short gSelectFileCounter; |
void main(void) |
{ |
Point dialogPt; |
SFTypeList mySFTypeList; |
StandardFileReply mySFR; |
SFReply oldSFR; |
long procID; |
FSSpec systemSpec; |
HookRecord hookRec; |
Boolean hasNewStdFileCallsFlag; |
long gestResponse; |
OSErr retCode; |
DlgHookYDUPP myDlgHookUPP; |
// initialize the toolbox |
InitGraf(&qd.thePort); InitFonts(); InitWindows(); InitMenus(); |
TEInit(); InitDialogs(nil); InitCursor(); FlushEvents(everyEvent,0); |
// determine if the System 7 std file calls are available |
retCode = Gestalt(gestaltStandardFileAttr, &gestResponse); |
if (retCode == noErr && ((gestResponse >> gestaltStandardFile58) & 1) != 0) |
hasNewStdFileCallsFlag = true; |
else |
hasNewStdFileCallsFlag = false; |
SetPt(&dialogPt, -1, -1); |
// get the FSSpec of the system file |
retCode = GetSystemFileSpec(&systemSpec); |
if (retCode != noErr) DebugStr((StringPtr)"\p GetSystemFileSpec failed"); |
if (hasNewStdFileCallsFlag) { |
// System 7 method |
// point my hook data record at the reply record and at |
// the file spec for the system file |
hookRec.itemSpec = &systemSpec; |
hookRec.theSFR = &mySFR; |
// Set up the universal proc pointer to your hook routine with this |
// macro defined in StandardFile.h. **NOTE** This is different |
// from the macro used for System 6 dialog hooks, and you should get |
// a compiler error if you try to use the wrong UPP with the wrong call. |
myDlgHookUPP = NewDlgHookYDProc(DialogHook); |
// call Std File |
CustomGetFile(nil, -1, mySFTypeList, &mySFR, 0, dialogPt, myDlgHookUPP, |
nil, nil, nil, &hookRec); |
// Dispose of the routine descriptor, since they do allocate memory.. |
DisposeRoutineDescriptor(myDlgHookUPP); |
} |
else { |
// System 6 method |
// stuff low memory to display the proper initial directory; |
// see Inside Mac:Files 3-31 |
DlgHookUPP myOldDlgHookUPP; |
// Throw out your SysEqu.h file and start using the low memory |
// accessor functions provided in LowMem.h. |
LMSetSFSaveDisk(-systemSpec.vRefNum); |
LMSetCurDirStore(systemSpec.parID); |
// set up the string for the system file name |
gSelectFileName = systemSpec.name; |
// Set up the universal proc pointer to your hook routine with this |
// macro defined in StandardFile.h. **NOTE** This is different |
// from the macro used for System 7 dialog hooks, and you should get |
// a compiler error if you try to use the wrong UPP with the wrong call. |
myOldDlgHookUPP = NewDlgHookProc(OldDlgHook); |
// call Std File |
SFGetFile(dialogPt, nil, nil, -1, mySFTypeList, myOldDlgHookUPP, &oldSFR); |
// Dispose of the routine descriptor, since they do allocate memory.. |
DisposeRoutineDescriptor(myOldDlgHookUPP); |
// store the result in a new reply record |
mySFR.sfGood = oldSFR.good; |
if (oldSFR.good) { |
// convert the WDRefNum and copy the name string |
retCode = GetWDInfo(oldSFR.vRefNum, |
&mySFR.sfFile.vRefNum, &mySFR.sfFile.parID, &procID); |
BlockMove(oldSFR.fName, mySFR.sfFile.name, 1 + oldSFR.fName[0]); |
} |
} |
} |
// this dialog hook for System 7 std file selects |
// the file specified by the hookRecord supplied as userData |
pascal short DialogHook(short item, DialogPtr theDialog, |
void *userData) |
{ |
HookRecordPtr hookRecPtr; |
hookRecPtr = (HookRecordPtr) userData; |
// hookRecPtr->itemSpec points to the FSSpec of the item to be selected |
// hookRecPtr->theSFR points to the standard file reply record |
// make sure we're dealing with the proper dialog |
if (GetWRefCon(theDialog) == sfMainDialogRefCon) { |
// just when opening the dialog... |
if (item == sfHookFirstCall) { |
// make the reply record hold the spec of the specified item |
hookRecPtr->theSFR->sfFile = *hookRecPtr->itemSpec; |
// ThereÕs a gotcha in Standard File when using sfHookChangeSelection. |
// Even though New Inside Macintosh: Files has a sample that doesn't set |
// the sfScript field, it should be set, or the last object in the |
// selected directory will always be selected. |
hookRecPtr->theSFR->sfScript = smSystemScript; |
// tell std file to change the selection to that item |
item = sfHookChangeSelection; |
} |
} |
return item; |
} |
// this std file dialog hook for System 6 selects the file |
// name in the global gSelectFileName |
pascal short OldDlgHook(short item, DialogPtr theDialog) |
{ |
#pragma unused (theDialog) |
// the idea here is to post keydown events, one per |
// null hook-event, until the entire file name |
// has been "typed" in (remember that the event queue |
// is shorter than the maximum file name so we only post |
// one key per null event) |
// reset the character counter initially |
if (item == sfHookFirstCall) |
gSelectFileCounter = 0; |
// post one keyDown per null event until the string is exhausted |
// This may not be a good idea for international software since |
// different input methods may be used. |
// Instead, you may want to check the System version and temporarily |
// set the KeyScript to zero before doing these PostEvents. |
// Afterwards, set KeyScript back to its original mode. |
else if (item == sfHookNullEvent) { |
if (gSelectFileCounter < *gSelectFileName) { |
gSelectFileCounter++; |
PostEvent(keyDown, *(gSelectFileName+gSelectFileCounter)); |
} |
} |
return item; |
} |
OSErr GetSystemFileSpec(FSSpecPtr systemSpec) |
{ |
// the System folder location is returned by FindFolder (or under |
// System 6 by the compiler's FindFolder glue) |
// |
// the System file name is available in low-memory |
OSErr retCode; |
StringPtr systemName; |
systemName = LMGetSysResName(); // Get the name of the System resource file |
retCode = FindFolder(kOnSystemDisk, kSystemFolderType, kCreateFolder, |
&systemSpec->vRefNum, &systemSpec->parID); |
if (retCode == noErr) |
BlockMove((Ptr)systemName, systemSpec->name, systemName[0] + 1); |
return retCode; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-03-13