CodeWarrior Pro 3で、PPCでToolBox使用のC言語の環境を指定して、新規プロジェクトを作った。このとき、「フォルダを作る」をチェックしておいて、babel-1.6フォルダの下に、babelという名前でプロジェクトを作った。実行ファイルの名前は同じだと、リンク後書き込むときにエラーになるから、PPCターゲットのファイル名をbabel-1.6にした。追加するソースはコンソール版を作ったときのものをそのまま使ったので、__POWERPC__で条件コンパイルしたところはそのままである。
console版の時と同様に、プロジェクトのソースのところに、babelのソースのうちfilesrch.c以外のすべての.cファイルを追加した。ToolBox版のプロジェクトでは、debugバージョンとそうでないバージョンの2種類のプロジェクトがあって、ファイルを追加すると両方に追加するかどうか訊いてくるので、両方に追加した。
Macライクなアプリケーションでは、main()に入った直後に自分でToolBox周りの初期化を行う必要がある。実行時に引数をとることができないから、引数に相当する情報を入力できるようにしておかなければならない。まず、convert.cのmain()を、convert_start()と名前を変えた。元のプログラムの処理をできるだけそのまま使いたいので、インターフェースをかぶせて、必要な情報が入力されたら*argv[]、argcを適切に設定してconvert_start()を呼ぶという方針でいく。
もうコンソールは使わないから、convert.cの、
/* #undef MAC */
#define MAC
#undef MAC
ToolBoxの初期化をするための、mac_main.cを作った。単なる変換プログラムなので、PowerPlantを使う程でもないので直接コードを書くことにした。プログラムの性質から、まずメニューとしてはAbout,Fileは必要だがEdit(何を?)はいらない。Fileメニューの項目として、openは必要だがsaveは必要ない。自動でsaveの画面を出すべきだろう。あと、コマンドラインで指定できるオプションとかキーワードを入力するためのoptionメニューは必要で、最後にquitをつけておけばよい。また、ドラッグ&ドロップによる複数ファイル一括変換を可能にしたいので、無駄が多くなるが、アップルイベントハンドラを一通り定義しておく。
MENUリソースは以下のように決めた。メニューID アップルメニュー 128 about 1 ファイルメニュー 129 open 1 option 3 quit 5
D&Dへの対応のため、AEHandleOpenDocumentからSelectFileType();およびConvertAll(odoc_fss, odoc_count);を呼ぶようにする。 ダブルクリックで始めたときは、メニューが出て、openを選ぶとDoClientOpen();を呼ぶ。オプションの指定でDoOptionInput();quitはDoClientQuit();がそれぞれ呼ばれる。ただしこれらの関数の中身はとりあえず空だったり、呼び出しのところはまだコメントにしたりしておく。
警告メッセージ表示のためのalertを定義する。alertのIDは、900とする。関連するDITLも900。mac_specific.c書いておく。メッセージを文字列で与えて呼び出すだけにする。当然、printfなどで表示していた部分を置き換えるつもりである。
ファイルの変換ではデータフォークしか見ないし、元のプログラムを生かすにはfopenしてfprintfなどを使いたい。Fsp_fopenの利用も考えたが、これで利用できるのは標準のダイアログであり、今回はOpenとSaveの時にファイル形式が選べるようになっていなければならないので、CustomOpenとCustomSaveAsを使うことにする。ファイルを選んだあと、フルパスを作って、パスをに渡すことにした。あまりMac的ではないが。(フルパスの部分は、K仲川さんのプログラムを使わせていただいた)
ファイル形式指定のopen/saveダイアログのIDはそれぞれ1100,1101とした。OpenDialog.r SaveAsDialog.rに、DLOGとCNTLを定義した。ファイル形式については、MENU ID が1100,1101のメニューに登録しておくことにする。(後の変更を考えると、構造体にファイル対応するファイル拡張子とファイル情報を定義しておいて、initializeの時に、そこからメニューを生成するのがよいと思ったのだが、これは私の知識不足で失敗した。見事にバスエラーを出した。方法についてはどっかで教えてもらってはっきりしたら書き換えることにする)また、選ばれたメニュー項目と対応する表を作った(FileTypes.h)。項目の番号を添字にしてこの表を見れば、引数として渡すべき文字列(そのまま拡張子にもなる)が引けるようにした。
DoClientOpen()では、ファイル形式指定でopenし、その直後にSaveAsを出して変換形式もろともファイル名を得ることになる。普通ならここでAppleEventを発行するはずだが、あえてはぶいて変換処理を直接書いておく。ファイルを開くときのファイルタイプは、何でも受け付けるようにしておく。他の環境から持ってきたファイルだと、TEXTとは限らないからである。新しいファイル名には元のファイル名の最後に_をつけることにする。SaveAsダイアログではこれがデフォルトで表示されるので、適宜書き換えることにする。拡張子をつけるのはあとから考える。
DoConvert()では、argc. argvを作ってconvert_start()(元のmain())に渡す。オプションが増えることを考えて、argvは7つにしておく。
ここまででとりあえずコンパイルして、typoの修正などをする。 しばらくぶりだったので、CustomOpenなどを作るときに、DLOG、MENUは作ったけどCNTLを作り忘れて、ファイルタイプが選べなくてちょっと悩んだ。
ここまでで、以下に、今回追加した部分を示す。私の書き方が必ずしも良いとは限らないので、もしもっといい方法を思いついたり私の間違いを見つけたりしたら、どうかメールで教えてください。
#ifndef MAC_MAIN_H_INCLUDED
#define MAC_MAIN_H_INCLUDED
#ifdef MAC_MAIN_SRC
#define SCOPE
#else
#define SCOPE extern
#endif
#define MenuBarID 128
#define AppleMenuID 128
#define AboutItem 1
#define FileMenuID 129
#define OenItem 1
#define OptionItem 3
#define QuitItem 5
#define ALERT_ID 900
#define OpenFileTypeMenu 1101
#define SaveFileTypeMenu 1100
/* menu */
SCOPE MenuHandle OpenTypeMenuH;
SCOPE MenuHandle SaveTypeMenuH;
#undef SCOPE
#endif /* MAC_MAIN_H_INCLUDED */
/* top routine for babel */
#define MAC_MAIN_SRC
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Strings.h>
#include <AppleEvents.h>
#include <AEObjects.h>
#include <AEPackObject.h>
#include "CustomFileDialog.h"
#include "mac_main.h"
#include "mac_specific.h"
#include "FileTypes.h"
// common data area
AEAddressDesc gSELF;
int done;
/* Prototypes */
extern void AEError(OSErr aError);
pascal OSErr AEHandleOpenApplication(AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
pascal OSErr AEHandleOpenDocument(AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
pascal OSErr AEHandlePrintDocument(AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
pascal OSErr AEHandleQuitApplication(AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
pascal OSErr AEHandleStartApplication(AppleEvent *theAppleEvent, AppleEvent *reply, long HandlerRefcon);
pascal OSErr AEHandleCloseDocument(AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
void InitToolBox(void);
void InitApplication(void);
void died (char desc[255], int code, int ref);
void DoClientNew(void);
void DoServerNew(void);
void DoServerOpen(void);
void DoClientOpen(void);
void DoClientPrint(void);
void DoServerPrint(SFReply *sfr);
void DoClientQuit(void);
void DoServerQuit(void);
void DoClientCloseDocument(void);
void DoServerCloseDocument(void);
void DoSave(void);
void DoAdjustMenu(void);
void DoAbout(void);
void main(void);
void DoMenu(long sel);
void DoFileMenu(short mitem);
pascal OSErr AEHandleOpenApplication(AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon)
{
DoServerNew();
return noErr;
}
// open document
pascal OSErr AEHandleOpenDocument(AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon)
{
AEDescList docList;
AEKeyword keywd;
DescType rtype;
Size acsize;
OSErr err;
FSSpec fss, *odoc_fss;
short i;
long odoc_count;
odoc_count = 0;
/* open document apple event */
err = AEGetParamDesc (theAppleEvent, keyDirectObject, typeAEList, &docList);
if (err) died ("Error Processing Apple Event", err, 14);
/* count number of document to be opened */
err = AECountItems (&docList, &odoc_count);
if (err) died ("Error Processing Apple Event", err, 15);
if (odoc_count < 1) died ("No File for OpenDoc Apple Event", 0, 16);
/* allocate memory for odoc_fss(FSSpec *) */
odoc_fss = (FSSpec *)malloc(sizeof(FSSpec) * odoc_count);
if(odoc_fss == NULL){
showmsgs("\pCan't allocate memory for so many files", NULL, NULL, NULL);
ExitToShell();
}
/* get FSS record of all document */
for(i = 0 ; i < odoc_count ; i++){
err = AEGetNthPtr (&docList, i+1, typeFSS, &keywd, &rtype,
(Ptr)&fss, sizeof(FSSpec), &acsize);
if (err) died ("Error Processing Apple Event", err, 17);
BlockMove(&fss, odoc_fss+i, acsize);
}
/* get rid of storage */
err = AEDisposeDesc (&docList);
if (err) died ("Error Processing Apple Event", err, 18);
/* open the passed file and do processing */
// SelectFileType();
// ConvertAll(odoc_fss, odoc_count);
return noErr;
}
// print contents of file
pascal OSErr AEHandlePrintDocument(AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon)
{
SFReply sfr;
Size actualSize;
AEDescList docList;
long itemsInList;
long index;
AEKeyword returnedKeywd;
DescType returnedType;
AEError(AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList));
AEError(AECountItems(&docList, &itemsInList));
AEError(AEGetNthPtr(&docList, index, typeFSS, &returnedKeywd, &returnedType,
(Ptr)&sfr, sizeof(SFReply), &actualSize));
DoServerPrint(&sfr);
AEError(AEDisposeDesc(&docList));
return noErr;
}
pascal OSErr AEHandleQuitApplication(AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon)
{
/* quit apple event - set the done flag */
/* Don't make the mistake of calling ExitToSHell() from */
/* inside the Quit Application Handler. If you do so, */
/* your handler will never return to the Apple Event */
/* Manager. */
done = true;
return noErr;
}
pascal OSErr AEHandleCloseDocument(AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon)
{
AEDesc aObject;
AEDesc aToken;
AEError(AEGetParamDesc(theAppleEvent, keyDirectObject, typeObjectSpecifier, &aObject));
AEError(AEResolve(&aObject, kAEIDoMinimum, &aToken));
DoServerCloseDocument();
return noErr; /* apj */
}
pascal OSErr AEHandleStartApplication(AppleEvent *theAppleEvent, AppleEvent *reply, long HandlerRefcon)
{
/* startup apple event - ask for an input file */
return noErr;
}
void InitToolBox(void)
{
WindowPtr mainPtr;
OSErr error;
SysEnvRec theWorld;
EventRecord tempEvent;
MenuHandle applemenu, filemenu;
error = SysEnvirons(1, &theWorld);
if (theWorld.hasColorQD == false) {
SysBeep(50);
ExitToShell(); /* If no color QD, we must leave. */
}
/* Initialize Managers */
InitGraf (&qd.thePort);
InitFonts ();
FlushEvents(everyEvent - osMask - diskMask, 0);
InitWindows ();
InitMenus ();
TEInit ();
InitDialogs (nil);
InitCursor ();
MaxApplZone();
MoreMasters();
EventAvail(everyEvent, &tempEvent);
EventAvail(everyEvent, &tempEvent);
EventAvail(everyEvent, &tempEvent);
/* setup menu */
applemenu = GetMenu(AppleMenuID);
if (applemenu == NULL) died ("Can't find Apple Menu Resource", 0, 001);
AppendResMenu(applemenu, 'DRVR');
filemenu = GetMenu(FileMenuID);
InsertMenu(applemenu, 0);
InsertMenu(filemenu, 0);
DrawMenuBar();
}
void InitApplication(void)
{
long aGestaltResponse;
Handle aMenuBar;
ProcessSerialNumber aProcessSerialNumber;
AEEventHandlerUPP OPENAPae, OPENae, QUITae, STARTae, PRINTae, CLOSEae;
if(Gestalt(gestaltAppleEventsAttr, &aGestaltResponse) != noErr)
ExitToShell();
AEError(AEObjectInit());
aMenuBar = GetNewMBar(MenuBarID);
SetMenuBar(aMenuBar);
DisposeHandle(aMenuBar);
DrawMenuBar();
AEError(GetCurrentProcess(&aProcessSerialNumber));
AEError(AECreateDesc(typeProcessSerialNumber, (Ptr)&aProcessSerialNumber,
sizeof(ProcessSerialNumber), (AEDesc *)&gSELF));
/* must use these for PPC proc pointers */
OPENAPae = NewAEEventHandlerProc ((ProcPtr) &AEHandleOpenApplication);
OPENae = NewAEEventHandlerProc ((ProcPtr) &AEHandleOpenDocument);
QUITae = NewAEEventHandlerProc ((ProcPtr) &AEHandleQuitApplication);
STARTae = NewAEEventHandlerProc ((ProcPtr) &AEHandleStartApplication);
PRINTae = NewAEEventHandlerProc ((ProcPtr) &AEHandlePrintDocument);
CLOSEae = NewAEEventHandlerProc ((ProcPtr) &AEHandleCloseDocument);
AEError(AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
OPENAPae, 0, false));
AEError(AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
OPENae, 0, false));
AEError(AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
PRINTae, 0, false));
AEError(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
QUITae, 0, false));
AEError(AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
STARTae, 0, false));
AEError(AEInstallEventHandler('core', 'clos',
CLOSEae, 0, false));
}
void died (char desc[255], int code, int ref)
{
/* nasty error has occurred - report it and quit */
int go;
char a[50], b[50];
CtoPstr (desc);
NumToString (code, (StringPtr)a);
NumToString (ref, (StringPtr)b);
ParamText ((StringPtr)desc, (StringPtr)a, (StringPtr)b, NULL);
go = Alert(ALERT_ID, NULL);
ExitToShell();
}
/**************************** Client & Server *******************************/
void DoClientNew(void)
{
AppleEvent aAppleEvent;
AppleEvent aReply;
AEError(AECreateAppleEvent(kCoreEventClass, kAEOpenApplication, &gSELF,
kAutoGenerateReturnID, kAnyTransactionID, &aAppleEvent));
AEError(AESend(&aAppleEvent, &aReply, kAENoReply, kAENormalPriority, 0,
nil, nil));
}
void DoServerNew(void)
{
// void
}
void DoServerOpen(void)
{
// void
}
void DoClientOpen(void)
{
StandardFileReply open_sfr, save_sfr;
SFTypeList typelist;
AppleEvent aAppleEvent;
AppleEvent aReply;
AEDescList aDocList;
AEDesc aDocDesc;
Point where;
short open_format, save_format;
char *ptr;
char fname_open[64];
char fname_save[256];
/* file types */
CustomOpen(NULL, -1, typelist, &open_sfr, &open_format);
if(open_sfr.sfGood){
ptr = (char *)open_sfr.sfFile.name;
strncpy(fname_save, ptr, 64);
ptr = fname_save;
PtoCstr((unsigned char *)ptr);
strcat(fname_save, "_");
CustomSaveAs("\pOutput file name", CtoPstr(fname_save), &save_sfr, &save_format);
if(save_sfr.sfGood){
DoConvert(&(open_sfr.sfFile), open_format, &(save_sfr.sfFile), save_format);
}
}
}
void DoClientPrint(void)
{
// void
}
void DoServerPrint(SFReply *sfr)
{
// void
}
void DoClientQuit(void)
{
AppleEvent aAppleEvent;
AppleEvent aReply;
AEError(AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &gSELF,
kAutoGenerateReturnID, kAnyTransactionID, &aAppleEvent));
AEError(AESend(&aAppleEvent, &aReply, kAENoReply, kAENormalPriority, 0,
nil, nil));
}
void DoServerQuit(void)
{
// メモリ共通領域の解放
DisposeMenu(OpenTypeMenuH);
DisposeMenu(SaveTypeMenuH);
ExitToShell();
}
void DoClientCloseDocument(void)
{
AEDesc dNull;
AEDesc dDocument;
AEDesc dDocumentKeyForm;
long aDocumentAbsolutePosition;
AppleEvent aAppleEvent;
AppleEvent aReply;
AEError(AECreateDesc(typeNull, nil, 0, &dNull));
aDocumentAbsolutePosition = 1;
AEError(AECreateDesc(typeLongInteger, (Ptr)&aDocumentAbsolutePosition, sizeof(long),
&dDocumentKeyForm));
AEError(CreateObjSpecifier('docu', &dNull, formAbsolutePosition,
&dDocumentKeyForm, true, &dDocument));
AEError(AECreateAppleEvent('core', 'clos', &gSELF, kAutoGenerateReturnID,
kAnyTransactionID, &aAppleEvent));
AEError(AEPutParamDesc(&aAppleEvent, keyDirectObject, &dDocument));
AEError(AESend(&aAppleEvent, &aReply, kAENoReply, kAENormalPriority, 0,
nil, nil));
}
void DoServerCloseDocument(void)
{
// void
}
/******************************************************************************/
/* Save is not AppleEvent in this case */
void DoSave(void)
{
// void
}
/********************* another menu ***************************/
void DoAdjustMenu(void)
{
// void
}
void DoAbout(void)
{
// TDR_About();
}
/*****************************************************************/
void main(void)
{
EventRecord aEvent;
WindowPtr aWhichWindow;
short wincode;
InitToolBox();
InitApplication();
done = false;
while( !done ){
if(WaitNextEvent(everyEvent, &aEvent, 20, 0) == true){
wincode = FindWindow(aEvent.where, &aWhichWindow);
switch(aEvent.what){
case nullEvent:
break;
case mouseDown:
switch(wincode){
case inMenuBar:
DoMenu(MenuSelect(aEvent.where));
break;
}
break;
case keyDown:
if(aEvent.modifiers & cmdKey){
DoMenu(MenuKey(aEvent.message & charCodeMask));
}
break;
case kHighLevelEvent:
AEError(AEProcessAppleEvent(&aEvent));
break;
}
}
}
DoServerQuit();
}
void DoMenu(long sel)
{
unsigned short aMenuID;
unsigned short aMenuItem;
int DAstat;
Str255 DAname;
aMenuID = HiWord(sel);
aMenuItem = LoWord(sel);
switch(aMenuID){
case AppleMenuID:
switch(aMenuItem){
case AboutItem:
// DoAbout();
break;
default:
GetMenuItemText(GetMenuHandle(AppleMenuID), aMenuID, DAname);
DAstat = OpenDeskAcc(DAname);
break;
}
break;
case FileMenuID:
DoFileMenu(aMenuItem);
break;
}
HiliteMenu(0);
DoAdjustMenu();
}
void DoFileMenu(short mitem)
{
CursHandle curh;
switch(mitem){
case OenItem:
DoClientOpen();
break;
case OptionItem:
// DoOptionInput();
break;
case QuitItem:
DoClientQuit();
ExitToShell();
break;
}
}
/* mac_specific.h */
#ifndef MAC_SPECIFIC_H_INCLUDEC
#define MAC_SPECIFIC_H_INCLUDEC
#ifdef MAC_SPECIFIC_SRC
#define SCOPE
#else
#define SCOPE extern
#endif
SCOPE char *strdup(const char *str);
SCOPE void showmsgs(unsigned char *str0, unsigned char *str1, unsigned char *str2, unsigned char *str3);
SCOPE void showstop(unsigned char *str0, unsigned char *str1, unsigned char *str2, unsigned char *str3);
SCOPE void shownote(unsigned char *str0, unsigned char *str1, unsigned char *str2, unsigned char *str3);
SCOPE void showcaution(unsigned char *str0, unsigned char *str1, unsigned char *str2, unsigned char *str3);
SCOPE void DoConvert(FSSpec *open_fss, short open_format, FSSpec *save_fss, short save_format);
#undef SCOPE
#endif /* MAC_SPECIFIC_H_INCLUDEC */
/* mac_specific.c */
#define MAC_SPECIFIC_SRC
#include <stdlib.h>
#include <stdio.h>
#include <string.h<
#include "mac_main.h"
#include "mac_specific.h"
#include "FileTypes.h"
char *strdup(const char *str)
{
char *tmpstr;
tmpstr = (char *)malloc(sizeof(char)*(strlen(str) + 1));
if(tmpstr == NULL) return tmpstr;
strcpy(tmpstr, str);
return tmpstr;
}
/******************** alert ***********************************************/
/* each argument is a pascal string */
void showmsgs(unsigned char *str0, unsigned char *str1, unsigned char *str2, unsigned char *str3)
{
ParamText((unsigned char *)str0,
(unsigned char *)str1,
(unsigned char *)str2,
(unsigned char *)str3);
Alert(900, NULL);
}
void showstop(unsigned char *str0, unsigned char *str1, unsigned char *str2, unsigned char *str3)
{
ParamText((unsigned char *)str0,
(unsigned char *)str1,
(unsigned char *)str2,
(unsigned char *)str3);
StopAlert(900, NULL);
}
void shownote(unsigned char *str0, unsigned char *str1, unsigned char *str2, unsigned char *str3)
{
ParamText((unsigned char *)str0,
(unsigned char *)str1,
(unsigned char *)str2,
(unsigned char *)str3);
NoteAlert(900, NULL);
}
void showcaution(unsigned char *str0, unsigned char *str1, unsigned char *str2, unsigned char *str3)
{
ParamText((unsigned char *)str0,
(unsigned char *)str1,
(unsigned char *)str2,
(unsigned char *)str3);
CautionAlert(900, NULL);
}
/******************************************************************************/
void DoConvert(FSSpec *open_fss, short open_format, FSSpec *save_fss, short save_format)
{
extern int ConvertFSSpecToFullPath(FSSpec *,char *);
extern int convert_top(int argc, char *argv[]);
char *argv[7];
int argc;
char openFileName[256], saveFileName[256];
char readOption[16], writeOption[16];
ConvertFSSpecToFullPath(open_fss, openFileName);
ConvertFSSpecToFullPath(save_fss, saveFileName);
sprintf(readOption, "-i%s", InputTypes[open_format].ext);
sprintf(writeOption, "-o%s", OutputTypes[save_format].ext);
argv[0] = "babel";
argv[1] = readOption;
argv[2] = openFileName;
argv[3] = writeOption;
argv[4] = saveFileName;
argc = 5;
convert_top(argc, argv);
}
#ifndef CUSTOMFILEDIALOG_H_INCLUDED
#define CUSTOMFILEDIALOG_H_INCLUDED
#ifdef CUSTOMFILEDIALOG_SRC
#define SCOPE
#else
#define SCOPE extern
#endif
// OpenDialog.r, SaveAsDialog.rに定義された値と一致すること
#define mySaveAsDialogID 1100
#define myOpenDialogID 1101
#define sfItemOpenFileType 10
#define sfItemSaveFileType 13
typedef struct{
short selType;
}SFData, *SFDataPtr;
SCOPE Boolean CustomSaveAs(Str255 prompt, Str255 defaultName, StandardFileReply *sfReply, short *fType);
SCOPE Boolean CustomOpen(UniversalProcPtr fileFilter, int numTypes, SFTypeList typeList,
StandardFileReply *sfReply, short *fType);
SCOPE pascal Boolean FilterInvisFiles(CInfoPBPtr pb, Ptr myDataPtr);
SCOPE pascal short CustomSaveDlgHook(short item,DialogPtr theDlg,Ptr userData);
SCOPE pascal short CustomOpenDlgHook(short item,DialogPtr theDlg,Ptr userData);
#undef SCOPE
#endif /* CUSTOMFILEDIALOG_H_INCLUDED */
// CustomFileDialog.cp
#define CUSTOMFILEDIALOG_SRC
#include "checksys.h"
#include "CustomFileDialog.h"
// fSpec ダイアログで指定したファイルを返す
// fType 保存するファイルの種類を返す。OSTypeにしていないのは、TEXTでも
// フォーマットの異なるものが存在しうるからである。具体的にはアプリケーションごと
// に設定するべきである。
Boolean CustomSaveAs(Str255 prompt, Str255 defaultName, StandardFileReply *sfReply, short *fType)
{
Point where = {-1,-1};
SFData sfUserData;
UniversalProcPtr dlgHookUPP;
sfUserData.selType = *fType;
if(isStandardFile()) {
dlgHookUPP = NewDlgHookYDProc(CustomSaveDlgHook);
CustomPutFile(prompt, defaultName, sfReply, mySaveAsDialogID,
where,
dlgHookUPP,0,
0,0,&sfUserData);
if (sfReply->sfGood) {
*fType = sfUserData.selType;
}
}
return sfReply->sfGood;
}
// fTypeにOpenするファイルの型を返す。
Boolean CustomOpen(UniversalProcPtr fileFilter, int numTypes, SFTypeList typeList,
StandardFileReply *sfReply, short *fType)
{
Point where = {-1,-1};
SFData sfUserData;
UniversalProcPtr dlgHookUPP;
short activelist[2];
sfUserData.selType = *fType;
activelist[0] = 0;
if(isStandardFile()) {
dlgHookUPP = NewDlgHookYDProc(CustomOpenDlgHook);
CustomGetFile(fileFilter, numTypes, typeList, sfReply, myOpenDialogID,
where,
dlgHookUPP,0,
0,0,
&sfUserData);
if (sfReply->sfGood) {
*fType = sfUserData.selType;
}
}
return sfReply->sfGood;
}
pascal Boolean FilterInvisFiles(CInfoPBPtr pb, Ptr myDataPtr)
{
if((pb->hFileInfo.ioFlFndrInfo.fdFlags) & fInvisible)
return true;
else
return false;
}
pascal short CustomSaveDlgHook(short item,DialogPtr theDlg,Ptr userData)
{
SFDataPtr sfUserData;
short itemType;
Rect box;
Handle popupCntlH;
if (GetWRefCon(theDlg) != sfMainDialogRefCon)
return item;
sfUserData = (SFDataPtr)userData;
switch(item) {
case sfItemOpenButton: // get file type
GetDialogItem(theDlg, sfItemSaveFileType, &itemType, &popupCntlH, &box);
sfUserData->selType = GetControlValue((ControlHandle)popupCntlH);
break;
case sfItemCancelButton: break;
case sfItemBalloonHelp: break;
case sfItemVolumeUser: break;
case sfItemEjectButton: break;
case sfItemDesktopButton: break;
case sfItemFileListUser: break;
case sfItemPopUpMenuUser: break;
case sfItemFileNameTextEdit: break;
case sfItemNewFolderUser: break;
case sfHookFirstCall: break;
case sfHookNullEvent: break;
case sfHookRebuildList: break;
case sfHookFolderPopUp: break;
case sfHookOpenFolder: break;
case sfHookOpenAlias: break;
case sfHookGoToDesktop: break;
case sfHookGoToAliasTarget: break;
case sfHookGoToParent: break;
case sfHookGoToNextDrive: break;
case sfHookGoToPrevDrive: break;
case sfHookChangeSelection: break;
}
return item;
}
pascal short CustomOpenDlgHook(short item,DialogPtr theDlg,Ptr userData)
{
SFDataPtr sfUserData;
short itemType;
Rect box;
Handle popupCntlH;
if (GetWRefCon(theDlg) != sfMainDialogRefCon)
return item;
sfUserData = (SFDataPtr)userData;
switch(item) {
case sfItemOpenButton: // get file type
GetDialogItem(theDlg, sfItemOpenFileType, &itemType, &popupCntlH, &box);
sfUserData->selType = GetControlValue((ControlHandle)popupCntlH);
break;
case sfItemCancelButton: break;
case sfItemBalloonHelp: break;
case sfItemVolumeUser: break;
case sfItemEjectButton: break;
case sfItemDesktopButton: break;
case sfItemFileListUser: break;
case sfItemPopUpMenuUser: break;
case sfItemFileNameTextEdit: break;
case sfItemNewFolderUser: break;
case sfHookFirstCall: break;
case sfHookNullEvent: break;
case sfHookRebuildList: break;
case sfHookFolderPopUp: break;
case sfHookOpenFolder: break;
case sfHookOpenAlias: break;
case sfHookGoToDesktop: break;
case sfHookGoToAliasTarget: break;
case sfHookGoToParent: break;
case sfHookGoToNextDrive: break;
case sfHookGoToPrevDrive: break;
case sfHookChangeSelection: break;
}
return item;
}
/* FileTypes.h */
#ifndef FILETYPES_H_INCLUDED
#define FILETYPES_H_INCLUDED
typedef struct{
char *format;
char *ext;
}FileTypes;
#ifdef MAC_MAIN_SRC
FileTypes InputTypes[] = {
{"Unkown", ""}, /* offset */
{"Alchemy file", "alc"},
{"AMBER PREP file", "prep"},
{"Ball and Stick file", "bs"},
{"MSI BGF file", "bgf"},
{"Biosym .CAR file", "car"},
{"Boogie file", "boog"},
{"Cacao Cartesian file", "caccrt"},
{"Cambridge CADPAC file", "cadpac"},
{"CHARMm file", "charmm"},
{"Chem3D Cartesian 1 file", "c3d1"},
{"Chem3D Cartesian 2 file", "c3d2"},
{"CSD CSSR file", "cssr"},
{"CSD FDAT file", "fdat"},
{"CSD GSTAT file", "gstat"},
{"Dock Database file", "dock"},
{"Dock PDB file", "dpdb"},
{"Feature file", "feat"},
{"Free Form Fractional file", "fract"},
{"GAMESS Output file", "gamout"},
{"Gaussian Z-Matrix file", "gzmat"},
{"Gaussian 92 Output file", "gauout"},
{"Gaussian 94 Output file", "g94"},
{"GROMOS96 (A) file", "gr96A"},
{"GROMOS96 (nm) file", "gr96N"},
{"Hyperchem HIN file", "hin"},
{"MDL Isis SDF file", "sdf"},
{"M3D file", "m3d"},
{"Mac Molecule file", "macmol"},
{"Macromodel file", "macmod"},
{"Micro World file", "micro"},
{"MM2 Input file", "mm2in"},
{"MM2 Output file", "mm2out"},
{"MM3 file", "mm3"},
{"MMADS file", "mmads"},
{"MDL MOLfile file", "mdl"},
{"MOLIN file", "molen"},
{"Mopac Cartesian file", "mopcrt"},
{"Mopac Internal file", "mopint"},
{"Mopac Output file", "mopout"},
{"PC Model file", "pcmod"},
{"PDB file", "pdb"},
{"PS-GVB Input file", "psin"},
{"PS-GVB Output file", "psout"},
{"Quanta MSF file", "msf"},
{"Schakal file", "schakal"},
{"ShelX file", "shelx"},
{"SMILES file", "smiles"},
{"Spartan file", "spar"},
{"Spartan Semi-Empirical file", "semi"},
{"Spartan Mol. Mechanics file", "spmm"},
{"Sybyl Mol file", "mol"},
{"Sybyl Mol2 file", "mol2"},
{"Conjure file", "wiz"},
{"UniChem XYZ file", "unixyz"},
{"XYZ file", "xyz"},
{"XED file", "xed"},
{NULL, NULL},
};
FileTypes OutputTypes[] = {
{"Unknown", ""}, /* offset */
{"DIAGNOTICS file", "diag"},
{"Alchemy file", "t"},
{"Ball and Stick file", "bs"},
{"Batchmin Command file", "bmin"},
{"Cacao Cartesian file", "caccrt"},
{"Cacao Internal file", "cacint"},
{"CAChe MolStruct file", "cache"},
{"Chem3D Cartesian 1 file", "c3d1"},
{"Chem3D Cartesian 2 file", "c3d2"},
{"ChemDraw Conn. Table file", "d"},
{"Conjure file", "con"},
{"Conjure Template file", "contmp"},
{"CSD CSSR file", "cssr"},
{"Feature file", "feat"},
{"Fenske-Hall ZMatrix file", "fhz"},
{"Gamess Input file", "gamin"},
{"Gaussian Cartesian file", "gcart"},
{"Gaussian Z-matrix file", "g"},
{"Gaussian Z-matrix tmplt file", "gotmp"},
{"Hyperchem HIN file", "hin"},
{"Icon 8 file", "icon"},
{"IDATM file", "i"},
{"Mac Molecule file", "macmol"},
{"Macromodel file", "k"},
{"Micro World file", "micro"},
{"MM2 Input file", "mi"},
{"MM2 Ouput file", "mo"},
{"MM3 file", "mm3"},
{"MMADS file", "mmads"},
{"MDL Molfile file", "mdl"},
{"Mopac Cartesian file", "ac"},
{"Mopac Internal file", "ai"},
{"PC Model file", "pc"},
{"PDB file", "pdb"},
{"Report file", "report"},
{"Spartan file", "spar"},
{"Sybyl Mol file", "mol"},
{"Sybyl Mol2 file", "mol2"},
{"MDL Maccs file", "maccs"},
{"XED file", "xed"},
{"UniChem XYZ file", "unixyz"},
{"XYZ file", "x"},
{NULL, NULL},
};
#else
extern FileTypes InputTypes[];
extern FileTypes OutputTypes[];
#endif
#endif /* FILETYPES_H_INCLUDED */
#define SystemSevenOrLater true
#include <Types.r>
#include <BalloonTypes.r>
#define mySaveAsDialogID 1100
resource 'DLOG' (mySaveAsDialogID, purgeable)
{
{0, 0, 228, 344}, dBoxProc, invisible, noGoAway, 0,
mySaveAsDialogID, "", noAutoCenter
};
resource 'DITL' (mySaveAsDialogID)
{ {
{161, 252, 181, 332}, Button { enabled, "Save" },
{130, 252, 150, 332}, Button { enabled, "Cancel" },
{0, 0, 0, 0}, HelpItem { disabled , HMScanhdlg {-6043} },
{8, 235, 24, 337}, UserItem { enabled },
{32, 252, 52, 332}, Button { enabled, "Eject" },
{60, 252, 80, 332}, Button { enabled, "Desktop" },
{29, 12, 127, 230}, UserItem { enabled },
{6, 12, 25, 230}, UserItem { enabled },
{119, 250, 120, 334}, Picture { disabled, 11 },
{157, 15, 173, 227}, EditText { enabled, "" },
{136, 15, 152, 227}, StaticText { disabled, "Save as:" },
{88, 252, 108, 332}, UserItem { enabled },
{190, 20, 209, 260}, Control {disabled, mySaveAsDialogID},
} };
#define SystemSevenOrLater true
#include <Types.r>
#include <BalloonTypes.r>
#define myOpenDialogID 1101
resource 'DLOG' (myOpenDialogID, purgeable)
{
{0, 0, 226, 344}, dBoxProc, invisible, noGoAway, 0,
myOpenDialogID, "", noAutoCenter
};
resource 'DITL' (myOpenDialogID)
{ {
{135, 252, 155, 332}, Button { enabled, "Open" },
{104, 252, 124, 332}, Button { enabled, "Cancel" },
{0, 0, 0, 0}, HelpItem { disabled , HMScanhdlg {-6042} },
{8, 235, 24, 337}, UserItem { enabled },
{32, 252, 52, 332}, Button { enabled, "Eject" },
{60, 252, 80, 332}, Button { enabled, "Desktop" },
{29, 12, 159, 230}, UserItem { enabled },
{6, 12, 25, 230}, UserItem { enabled },
{91, 251, 92, 333}, Picture { disabled, 11 },
{190, 20, 209, 260}, Control {disabled, myOpenDialogID},
} };
/* aeerror.c */
/* ALERT ID must be 900 */
void AEError(OSErr aError);
void AEError(OSErr aError)
{
if(aError != noErr){
SysBeep(1);
switch(aError){
/* Error messages in response to reading and writing event contents */
case errAECoercionFail:
ParamText("\perrAECoercionFail.", "\p","\p","\p");
break;
case errAEDescNotFound:
ParamText("\perrAEDescNotFound.", "\p","\p","\p");
break;
case errAECorruptData:
ParamText("\perrAECorruptData.", "\p","\p","\p");
break;
case errAEWrongDataType:
ParamText("\perrAEWrongDataType.", "\p","\p","\p");
break;
case errAENotAEDesc:
ParamText("\perrAENotAEDesc.", "\p","\p","\p");
break;
case errAEBadListItem:
ParamText("\pSpecified list item does not exist.", "\p","\p","\p");
break;
case errAENewerVersion:
ParamText("\pNeed newer version of AppleEvent Manager .", "\p","\p","\p");
break;
case errAENotAppleEvent:
ParamText("\phe event is not in AppleEvent format.", "\p","\p","\p");
break;
/* Error messages in response to sending/receiving a message */
case errAEEventNotHandled:
ParamText("\pThe AppleEvent was not handled by any handler.", "\p","\p","\p");
break;
case errAEReplyNotValid:
ParamText("\pAEResetTimer was passed an invalid reply parameter.", "\p","\p","\p");
break;
case errAEUnknownSendMode:
ParamText("\pMode wasn't NoReply, WaitReply, or QueueReply; or Interaction level is unknown.", "\p","\p","\p");
break;
case errAEWaitCanceled:
ParamText("\pIn AESend, User cancelled out of wait loop for reply or receipt.", "\p","\p","\p");
break;
case errAETimeout:
ParamText("\pAppleEvent timed out.", "\p","\p","\p");
break;
case errAENoUserInteraction:
ParamText("\pno user interaction allowed.", "\p","\p","\p");
break;
case errAENotASpecialFunction:
ParamText("\pthere is no special function with this keyword.", "\p","\p","\p");
break;
case errAEParamMissed:
ParamText("\pa required parameter was not accessed .", "\p","\p","\p");
break;
case errAEUnknownAddressType:
ParamText("\pThe target address type is not known.", "\p","\p","\p");
break;
case errAEHandlerNotFound:
ParamText("\pNo handler in the dispatch tables fits the parameters to AEGetEventHandler or AEGetCoercionHandler.", "\p","\p","\p");
break;
case errAEReplyNotArrived:
ParamText("\phe contents of the reply you are accessing have not arrived yet.", "\p","\p","\p");
break;
case errAEIllegalIndex:
ParamText("\pIndex is out of range in a put operation.", "\p","\p","\p");
break;
/* from inside macnhintosh */
case -50:
ParamText("\pParameter Error(for example, value of handler pointer is NIL or odd.", "\p","\p","\p");
break;
case -92:
ParamText("\pBuffer too bog to send.", "\p","\p","\p");
break;
case -108:
ParamText("\pNot enough room for heap zone.", "\p","\p","\p");
break;
case -128:
ParamText("\pUser canceled an operation", "\p","\p","\p");
break;
case -600:
ParamText("\pNo eligible process with specified process serial number", "\p","\p","\p");
break;
case -607:
ParamText("\pBuffer is too small", "\p","\p","\p");
break;
case -608:
ParamText("\pNo outstanding high level event", "\p","\p","\p");
break;
case -609:
ParamText("\pNonexistent signature or session ID", "\p","\p","\p");
break;
case -610:
ParamText("\pBackground application sends event requiring authentication", "\p","\p","\p");
break;
case -903:
ParamText("\pClient has't set 'SIZE' resource to indicate awareness of high level events", "\p","\p","\p");
break;
case -906:
ParamText("\pServer hasn't set 'SIZE' resource to indicate awareness of high-level events or else is not present.", "\p","\p","\p");
break;
case -917:
ParamText("\pthe kAEDontReconnect flag in the sendMode parameter was set and the werver quit then restarted.", "\p","\p","\p");
break;
case -1720:
ParamText("\pThe range is not valid because it is impossible for a range to include the first and last objects that were specified.", "\p", "\p", "\p");
break;
case -1721:
ParamText("\pThe number of operands provided for kAENot logical operator is not 1.", "\p", "\p", "\p");
break;
case -1723:
ParamText("\pThere is no object accessor function for the specified object class and token descriptor type.", "\p", "\p", "\p");
break;
case -1725:
ParamText("\pThe logical operator in a logical descriptor record is not kAEAnd, kAEOr, or kAENot.", "\p", "\p", "\p");
break;
case -1726:
ParamText("\pThe descroptor record in a test key is neither a comparison descriptor record nor a logical descriptor record.", "\p", "\p", "\p");
break;
case -1727:
ParamText("\pThe ObjectSpecifiler parameter of AEResolve is not an object specifier record.", "\p", "\p", "\p");
break;
case -1728:
ParamText("\pA run time resolution error, for example:object specifier record asked for the third element, but there are only two.", "\p", "\p", "\p");
break;
case -1729:
ParamText("\pObject-counting function returned negative value.", "\p", "\p", "\p");
break;
case -1730:
ParamText("\pThe container for an Apple event object is specified by a empty list.", "\p", "\p", "\p");
break;
case -1731:
ParamText("\pDescriptor type of token returned by AEResolve is not known to server application.", "\p", "\p", "\p");
break;
case -1732:
ParamText("\pAttempt to turn recording on when it is already on.", "\p", "\p", "\p");
break;
default:
ParamText("\pNot Apple event error!", "\p","\p","\p");
break;
}
Alert(900, NULL);
}
}
/* fullpath.c */
/* written by K.Nakagawa. Thaks */
#include <stdio.h>
#include <string.h>
#define ROOT_DIR_ID 2 /* ルートディレクトリのディレクトリID番号 */
int ConvertFSSpecToFullPath(FSSpec *,char *);
OSErr GetParentDirFSSpec(FSSpec *);
char *PText2CText(StringPtr);
/*
FSSpec構造体からフルパス名をえる
戻り値は 0:OK,-1:エラー
*/
int ConvertFSSpecToFullPath(FSSpec *pFSSpec,char *pFileName)
{
/* 変数定義 */
Boolean aLoop;
FSSpec aFSSpec;
char aStr[256];
/* 手続き */
strcpy(pFileName,PText2CText(pFSSpec->name));
aFSSpec = *pFSSpec;
/* 親ディレクトリの名前をどんどん追加していく */
for(aLoop = TRUE; aLoop; )
{
/* ルートディレクトリであるなら追加はこれで終わり */
if(aFSSpec.parID == ROOT_DIR_ID)
aLoop = FALSE;
/* 親ディレクトリをたどる */
if(noErr != GetParentDirFSSpec(&aFSSpec))
return -1;
/* 名前を追加する */
strcpy(aStr,pFileName);
strcpy(pFileName,PText2CText(aFSSpec.name));
strcat(pFileName,":");
strcat(pFileName,aStr);
}
return 0;
}
/*
pSpecで指定のファイルの所属ディレクトリの情報をpSpecにえる
戻り値は、この関数が呼ぶPBGetCatInfoの戻り値
*/
OSErr GetParentDirFSSpec(FSSpec *pSpec)
{
/* 変数定義 */
OSErr aOSErr;
CInfoPBRec aCInfoPBRec;
/* 手続き */
aCInfoPBRec.dirInfo.ioNamePtr = pSpec->name;
aCInfoPBRec.dirInfo.ioVRefNum = pSpec->vRefNum;
aCInfoPBRec.dirInfo.ioFDirIndex = -1;
aCInfoPBRec.dirInfo.ioDrDirID = pSpec->parID;
aOSErr = PBGetCatInfo(&aCInfoPBRec,FALSE);
pSpec->parID = aCInfoPBRec.dirInfo.ioDrParID;
return aOSErr;
}
/*
パスカル文字列をC文字列に変換して内部で確保しておく
戻り値は確保している文字列へのポインタ
*/
char *PText2CText(StringPtr pText)
{
static char aRes[256];
unsigned short aCnt;
char *aDp;
aCnt = (unsigned short)(*pText++);
aDp = aRes;
while(aCnt-- != 0)
*aDp++ = (char)(*pText++);
*aDp = '\0';
return aRes;
}
// checksys.h
#ifndef CHECKSYS_H_INCLUDED
#define CHECKSYS_H_INCLUDED
#ifdef CHECKSYS_SRC
#define SCOPE
#else
#define SCOPE extern
#endif
SCOPE Boolean availGWorld(void);
SCOPE Boolean isSFSpec(void);
SCOPE Boolean isStandardFile(void);
SCOPE Boolean isSystem7(void);
SCOPE long CheckEnvLang(void);
SCOPE int NumToolboxTraps(void);
SCOPE TrapType GetTrapType(int theTrap);
SCOPE Boolean TrapAvailable(int theTrap);
SCOPE Boolean GestaltAvailable(void);
#undef SCOPE
#endif /* CHECKSYS_H_INCLUDED */
// checksys.cp
// Original Program : THINK C, Masayuki NII, BNN(1994)
// customized by apj.
#define CHECKSYS_SRC
#include "checksys.h"
Boolean availGWorld(void)
{
OSErr er;
long myF;
if(!GestaltAvailable())
return(false);
er = Gestalt(gestaltQuickdrawVersion, &myF);
if(er!=noErr) {}
if(myF < gestalt32BitQD)
return(false);
else
return(true);
}
Boolean isSFSpec(void)
{
OSErr er;
long myF;
if(!GestaltAvailable())
return(false);
er = Gestalt(gestaltFSAttr, &myF);
if(er!=noErr) {}
if(!BitTst(&myF,31-gestaltHasFSSpecCalls))
return(false);
else
return(true);
}
Boolean isStandardFile(void)
{
OSErr er;
long myF;
if(!GestaltAvailable())
return(false);
er = Gestalt(gestaltStandardFileAttr, &myF);
if(er!=noErr) {}
if(!BitTst(&myF,31-gestaltStandardFile58))
return(false);
else
return(true);
}
Boolean isSystem7(void)
{
OSErr er;
long myF;
if(!GestaltAvailable())
return(false);
er = Gestalt(gestaltSystemVersion, &myF);
if(er!=noErr) {}
if(myF>0x0700)
return(false);
else
return(true);
}
long CheckEnvLang(void)
{
long vb;
vb = GetScriptManagerVariable(smSysScript);
if(vb == smJapanese)
return(vb);
else
return(smRoman);
}
#define _InitGraf 0xa86e
#define _Gestalt 0xa1ad
#define TrapMask 0x0800
#define _Unimplemented 0xaa6e
int NumToolboxTraps(void)
{
if(NGetTrapAddress(_InitGraf, ToolTrap)
== NGetTrapAddress(0xaa6e, ToolTrap))
return(0x200);
else
return(0x400);
}
TrapType GetTrapType(int theTrap)
{
if((theTrap&TrapMask) > 0)
return(ToolTrap);
else
return(OSTrap);
}
Boolean TrapAvailable(int theTrap)
{
TrapType tType;
tType = GetTrapType(theTrap);
if(tType == ToolTrap) {
theTrap &= 0x07ff;
if(theTrap >= NumToolboxTraps())
theTrap = _Unimplemented;
}
return(NGetTrapAddress(theTrap, tType)
!= NGetTrapAddress(_Unimplemented, ToolTrap));
}
Boolean GestaltAvailable(void)
{
return(TrapAvailable(_Gestalt));
}
#undef _InitGraf
#undef _Gestalt
#undef TrapMask
#undef _Unimplemented