Article View: comp.sys.mac.programmer.codewarrior
Article #1060Re: REQ: Carbonized "DropUnix" lib or source code. Need to fill in argc, argv from drag&drop
From: David Phillip Oster
Date: Sat, 02 Feb 2002 15:53
Date: Sat, 02 Feb 2002 15:53
428 lines
12558 bytes
12558 bytes
In article <280120020050500931%NotMe@really.org>,
NotMe Really <NotMe@really.org> wrote:
> I'm trying to carbonize my old support applications. All I need to do
> is to replace DropUnix. DropUnix was a pre-carbon library that replaced
> "main()" and filled in argc, argv with the full pathnames of items that
> were dropped into the application the library was linked with.
>
> Does anyone have something similar or any pointers to some example C
> code please.
Here is the source code for a Rot13 droplet. Note that this is
pre-carbon, so it still uses FSSpecs instead of FSRefs (there is a new
technote on Apple's web site on the death of FSSpec (doesn't handle
filenames longer than 31 characters, doesn't support the Unicode file
names of HFS+.) Note that FSSpecs still work under OS X, they just have
a mangled string in the name field the the O.S. will interpret
correctly, it will just look funny if it needs to be shown to the user.
To turn FSSpecs into fullPaths, look at the More Files subroutine
library (with source code) on Apple's web site.
This took about ten minutes to carbonize. The trickiest bit was
replacing the call to StandardGetFile() with a call to NavGetFile().
/* main.c - Zero the resource fork of any file dropped on the
application.
if you drop files on this, it does its job and quits.
if you double click on it, you get an "open" dialog.
by David Phillip Oster <mailto:oster@ieee.org>
notes:
written to strip a gif before e-mailing it to a Windows programmer.
enhanced to allow you to drop files on the application.
Example of an "applet"
Carbonized.
� registering ODOC and QUIT apple event handlers. allowing anything
to be droppped on it.
� adding as bundle to allow anything to be droppped on it.
� provide a menu bar interface if the user just clicks on the app.
could be improved by:
� adding an about box explaining the functionality.
נclearing the Custom Icon bit if it is set.
?�progress meter (no. this whole process is too close to
instaneous.)
*/
#include <Sound.h>
enum {
menu_Apple = 128,
menu_File
};
static OSErr DoOpenDocList(const AEDescList docList);
static Boolean isDone = false;
/* ZeroResourceFork - remove the resource fork of a file.
Note: this is the meat of the program. the rest is just boilerplate.
*/
static OSErr ZeroResourceFork(FSSpec* fsp){
short ref;
OSErr errCode;
ref = -1;
errCode = noErr;
if(noErr == errCode){ errCode = FSpOpenRF(fsp, fsRdWrPerm, &ref); }
if(noErr == errCode){ errCode = SetEOF(ref, 0); }
if(-1 != ref){ FSClose(ref); }
if(noErr != errCode){
SysBeep(1);
}
return errCode;
}
static void DoOpen(void){
#if CALL_NOT_IN_CARBON
StandardFileReply reply;
StandardGetFile(nil, 0, nil, &reply);
if(reply.sfGood){
ZeroResourceFork(&reply.sfFile);
}
#else
NavReplyRecord reply;
NavDialogOptions options;
OSErr errCode;
errCode = noErr;
BlockZero(&reply, sizeof reply);
reply.version = kNavReplyRecordVersion;
if(noErr == errCode){ errCode = NavLoad(); }
if(noErr == errCode){ errCode = NavGetDefaultDialogOptions(&options);
}
if(noErr == errCode){
errCode = NavGetFile(NULL, &reply, &options, NULL, NULL, NULL,
NULL, NULL);
if(reply.validRecord){
errCode = DoOpenDocList(reply.selection);
}
NavDisposeReply(&reply);
}
#endif
}
/* MissedAEParameters -
*/
static OSErr MissedAEParameters(const AppleEvent *message){
DescType typeCode;
Size actualSize;
OSErr err;
if(errAEDescNotFound == (err = AEGetAttributePtr(message,
keyMissedKeywordAttr, typeWildCard,
&typeCode, NULL, 0L, &actualSize))){
return noErr;
}
return (noErr == err ? errAEEventNotHandled : err);
}
typedef SInt32 RefConType;
/* DoOpenApp - nothing to do on application start
*/
static pascal OSErr DoOpenApp(const AppleEvent *message, AppleEvent *
/*reply*/, RefConType /*refCon*/){
OSErr err;
if ((err = MissedAEParameters(message)) != noErr){
return err;
}
// create menu bar.
SetMenuBar(GetNewMBar(128));
AppendResMenu(GetMenuHandle(menu_Apple), 'DRVR');
DrawMenuBar();
return noErr;
}
static OSErr DoOpenDocList(const AEDescList docList){
long index, itemsInList;
OSErr err;
Size actualSize;
AEKeyword keywd;
DescType typeCode;
FSSpec fss;
if(noErr != (err = AECountItems(&docList, &itemsInList))){
return err;
}
for(index = 1; index <= itemsInList; index++){
if(noErr != (err = AEGetNthPtr(&docList, index, typeFSS, &keywd,
&typeCode,
(Ptr)&fss, sizeof(FSSpec), &actualSize))){
break;
}
if(noErr != (err = ZeroResourceFork(&fss))){
break;
}
}
return err;
}
/* DoOpenDoc - we get called with a list of file specs as the direct
object.
for each file spec, run ZeroResourceFork on it.
then quit.
*/
static pascal OSErr DoOpenDoc(const AppleEvent *message, AppleEvent *
/*reply*/, RefConType /*refCon*/){
AEDescList docList;
OSErr err;
if((err = AEGetParamDesc(message, keyDirectObject, typeAEList,
&docList)) != noErr ||
(err = MissedAEParameters(message)) != noErr){
return err;
}
err = DoOpenDocList(docList);
AEDisposeDesc(&docList);
isDone = true;
return err;
}
/* DoPrintDoc - printing not supported
*/
static pascal OSErr DoPrintDoc(const AppleEvent *message, AppleEvent *
/*reply*/, RefConType /*refCon*/){
OSErr err;
if ((err = MissedAEParameters(message)) != noErr){
return err;
}
return noErr;
}
/* DoQuitApp - set the quit flag.
*/
static pascal OSErr DoQuitApp(const AppleEvent *message, AppleEvent *
/*reply*/, RefConType /*refCon*/){
OSErr err;
if ((err = MissedAEParameters(message)) != noErr){
return err;
}
isDone = true;
return noErr;
}
#if ! CALL_NOT_IN_CARBON
#define NewAEEventHandlerProc NewAEEventHandlerUPP
#endif
static void InitAppleEventHandlers(void){
long response;
if(noErr == Gestalt(gestaltAppleEventsAttr, &response) &&
(response & (1L << gestaltAppleEventsPresent))){
AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
NewAEEventHandlerProc(DoOpenApp), 0, false);
AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
NewAEEventHandlerProc(DoOpenDoc), 0, false);
AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
NewAEEventHandlerProc(DoPrintDoc), 0, false);
AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
NewAEEventHandlerProc(DoQuitApp), 0, false);
}
}
static void Init(){
#if CALL_NOT_IN_CARBON
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(nil);
#endif
InitCursor();
InitAppleEventHandlers();
}
static void DoApppleMenu(short item){
Str255 s;
switch(item){
case 1:
/* About box here */
break;
default:
GetMenuItemText(GetMenuHandle(menu_Apple), item, s);
#if CALL_NOT_IN_CARBON
OpenDeskAcc(s);
#endif
break;
}
}
enum {
kOpenI = 1,
kQuitI = 3
};
static void DoFileMenu(short item){
switch(item){
case kOpenI: DoOpen(); break;
case kQuitI: ExitToShell(); break;
}
}
static void GoMenu(long command){
short item;
unsigned long now, then;
unsigned long dontCare;
now = TickCount();
item = LoWord(command);
switch(HiWord(command)){
case menu_Apple: DoApppleMenu(item); break;
case menu_File: DoFileMenu(item); break;
}
then = TickCount();
if(then < now + 2){
Delay((now + 2) - then, &dontCare);
}
HiliteMenu(0);
}
/* GoMenuBar -
*/
static void GoMenuBar(EventRecord *event){
GoMenu(MenuSelect(event->where));
}
/* GoMouseDown - the mouse down tracker
*/
static void GoMouseDown(EventRecord *event){
short sel;
WindowPtr win;
sel = FindWindow(event->where, &win);
switch(sel){
case inMenuBar: GoMenuBar(event); break;
#if CALL_NOT_IN_CARBON
case inSysWindow: SystemClick(event, win); break;
#endif
}
}
/* GoEvent - main event dispatcher.
*/
static void GoEvent(EventRecord *e){
switch(e->what){
case mouseDown: GoMouseDown(e); break;
case kHighLevelEvent: AEProcessAppleEvent(e); break;
}
}
void main(){
EventRecord e;
Init();
while( ! isDone){
WaitNextEvent(everyEvent, &e, 10, nil);
GoEvent(&e);
}
}
-------------------------
Here is the matching .r file:
#include <Types.r>
enum {
menu_apple = 128,
menu_file,
menu_edit
};
#define kCreator '0Res' // <- use YOUR creator type
resource 'BNDL' (128, purgeable) {
kCreator, 0, {
'ICN#', {
0, 128,
1, 129,
},
'FREF', {
0, 128,
1, 129,
}
}};
type kCreator as 'STR ';
resource kCreator (0, purgeable) {
"by David Phillip Oster, 1994-2002"
};
resource 'FREF' (128, purgeable) { 'APPL', 0, ""};
resource 'FREF' (129, purgeable) { '****', 0, ""};
#define kAllItems 0x7FFFFFFF
#define kItem1 (1 << (1 - 1))
#define kItem2 (1 << (2 - 1))
#define kItem3 (1 << (3 - 1))
#define kItem4 (1 << (4 - 1))
#define kItem5 (1 << (5 - 1))
#define kItem6 (1 << (6 - 1))
#define kItem7 (1 << (7 - 1))
#define kItem8 (1 << (8 - 1))
#define kItem9 (1 << (9 - 1))
#define kItem10 (1 << (10- 1))
#define kItem11 (1 << (11- 1))
#define kItem12 (1 << (12- 1))
resource 'MBAR' (128){{
menu_apple,
menu_file,
menu_edit
}};
resource 'MENU' (menu_apple, "Apple") {
menu_apple,
textMenuProc,
0x7FFFFFFD,
enabled,
apple,
{
"About 0Res�", noIcon, noKey, noMark, plain,
"-", noIcon, noKey, noMark, plain
}};
resource 'MENU' (menu_file, "File") {
menu_file,
textMenuProc,
kAllItems - (kItem2),
enabled,
"File",
{
"Open�", noIcon, "O", noMark, plain,
"-", noIcon, noKey, noMark, plain,
"Quit", noIcon, "Q", noMark, plain
}};
resource 'MENU' (menu_edit, "Edit") {
menu_edit,
textMenuProc,
kAllItems - (kItem2),
disabled,
"Edit",
{ /* array: 6 elements */
"Undo", noIcon, "Z", noMark, plain,
"-", noIcon, noKey, noMark, plain,
"Cut", noIcon, "X", noMark, plain,
"Copy", noIcon, "C", noMark, plain,
"Paste", noIcon, "V", noMark, plain,
"Clear", noIcon, noKey, noMark, plain,
}
};
Technical Details
Message-ID:
<oster-893CC9.07534802022002@newssvr14-ext.news.prodigy.com>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!newsfeed.cwix.com!newscon01.news.prodigy.com!newsmst01.news.prodigy.com!prodigy.com!postmaster.news.prodigy.com!newssvr14.news.prodigy.com.POSTED!not-for-mailReferences:
<280120020050500931%NotMe@really.org>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII
X-Google-Thread: 10bcce,a0f22049898d59c5
X-Google-Attributes: gid10bcce,public
X-Google-Thread: f635e,a0f22049898d59c5
X-Google-Attributes: gidf635e,public
X-Google-ArrivalTime: 2002-02-02 07:54:06 PST
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!newsfeed.cwix.com!newscon01.news.prodigy.com!newsmst01.news.prodigy.com!prodigy.com!postmaster.news.prodigy.com!newssvr14.news.prodigy.com.POSTED!not-for-mail
From: David Phillip Oster <oster@ieee.org>
Newsgroups: comp.sys.mac.programmer.codewarrior,codewarrior.mac
Subject: Re: REQ: Carbonized "DropUnix" lib or source code. Need to fill in argc, argv from drag&drop
Organization: http://www.TurboZen.com
References: <280120020050500931%NotMe@really.org>
User-Agent: MT-NewsWatcher/3.1 (PPC)
X-Face: iR>C6?LNAcg&!xxr{}\7y$W@~UW,\:5'<H=KmFr^OY!`48#Nqao]VO#+oxocr ="e"*!AxDM1my!y7uoK4<&hQ-9c\KxG_b3eD{JlM2+r0BYXAo<~N|g'3p<tXe37b[79@ ?46JFrQ?^D479N=<Au~;,ax]LOils0QyP.qY!Mw5o'2$<qA{V)<J-<2Y8K
Message-ID: <oster-893CC9.07534802022002@newssvr14-ext.news.prodigy.com>
Lines: 428
NNTP-Posting-Host: 64.167.142.226
X-Complaints-To: abuse@prodigy.net
X-Trace: newssvr14.news.prodigy.com 1012665229 ST000 64.167.142.226 (Sat, 02 Feb 2002 10:53:49 EST)
NNTP-Posting-Date: Sat, 02 Feb 2002 10:53:49 EST
X-UserInfo1: Q[OMRWWGPRR_RV\XNCOF_W\@PJ_^PBQLGPQRJVMHQAVTUZ]CLNTCPFK[WDXDHV[K^FCGJCJLPF_D_NCC@FUG^Q\DINVAXSLIFXYJSSCCALP@PB@\OS@BITWAH\CQZKJMMD^SJA^NXA\GVLSRBD^M_NW_F[YLVTWIGAXAQBOATKBBQRXECDFDMQ\DZFUE@\JM
Date: Sat, 02 Feb 2002 15:53:49 GMT