Re: Communicating With Browser
Re: Communicating With Browser
- Subject: Re: Communicating With Browser
- From: Zack Morris <email@hidden>
- Date: Tue, 9 Nov 2004 04:45:13 -0700
On Nov 8, 2004, at 7:59 AM, Quinn wrote:
At 20:21 -0700 6/11/04, Zack Morris wrote:
But the problem is, if they have the URL already open in a window,
this causes it to reload, at least in Safari. This is unacceptible,
because they lose whatever info the have entered on the page. Is
there any way to tell the browser not to reload the page if it is
already open?
There's no facility for this in the IC/GURL world. You'll have to add
browser-specific code (probably based around the browser's scripting
support), which is a royal pain. You can make your life easier by
writing the Apple event code in AppleScript, and calling that
AppleScript code from your app.
<http://developer.apple.com/qa/qa2001/qa1111.html>
Oh man, I just spent several hours researching new routines to send
raw apple events, and then I saw that you put a link to interpret
applescript right in your response! That is definitely a much better
method. Anyway, I included the routines I wrote so far in the bottom
of this email, in case anyone goes down this path in the future. 2
links helped me immensely:
http://lists.helixcommunity.org/pipermail/common-cvs/2003-January/
000413.html
http://linux.imp.mx/cvs-tmp/rpms/SOURCES/mozilla/xpcom/io/
nsLocalFileMac.cpp
Anyway, the only errata with these routines is for some reason,
MakeOpenURLEvent() doesn't seem to work when I use
GetSenderAddressDesc(), and I don't know why. I was trying to get the
source of the apple event that came to me from Safari, and it didn't
work. I think it has something to do with the typeSessionID enum,
which was deprecated in Carbon.
Also, FindApplicationByCreator() doesn't work for packages! I am able
to launch Resorcerer with the creator 'Doug', but I can't launch
Safari, which is 'sfri'. Does anyone know why? I need the code that
finds a package on the volume that has that signature, and I can add it
to FindApplicationByCreator(), to try upon failure. Here is a little
code snippet to get you started:
//-----
// messagein in the apple event that came to me in my apple event
handler
AEDesc newEvent;
AEDesc outAEReply;
AEAddressDesc desc;
GetSenderAddressDesc( messagein, &desc ); // I can't tell if this
fails, or if trying to create the open-url-event fails
if( MakeOpenURLEvent( "http://www.apple.com", &newEvent, 'sfri',
nil/*&desc*/, false ) != noErr )
ErrorDialog( "\pCreate open URL failed" );
myErr = AESend( &newEvent, &outAEReply, kAEWaitReply+kAEDontRecord,
kAEHighPriority, kNoTimeOut, nil, nil );
//LaunchApplicationByCreator( 'sfri' ); // doesn't work, can't find
Safari's package!
LaunchApplicationByCreator( 'Doug' ); // launches resorcerer
//QuitApplicationByCreator( 'MSIE' ); // works, quits internet explorer
if( myErr )
ErrorDialog( "\pOpen URL failed", StrNum( myErr ) );
else
{
AEDisposeDesc( &newEvent );
AEDisposeDesc( &outAEReply );
}
//-----
Thanx to anyone with an answer to the source of an apple event and
finding safari's package by the creator 'sfri' :)
------------------------------------------------------------------------
Zack Morris Z Sculpt Entertainment This Space
email@hidden http://www.zsculpt.com For Rent
------------------------------------------------------------------------
If the doors of perception were cleansed, everything would appear to man
as it is, infinite. -William Blake, The Marriage of Heaven and Hell
//---------- code -----------------------
#include <EPPC.h>
#include <AEDataModel.h>
enum {
typeSessionID = FOUR_CHAR_CODE('ssid'),
typeTargetID = FOUR_CHAR_CODE('targ'),
typeDispatcherID = FOUR_CHAR_CODE('dspt')
};
const DescType kWebBrowserSuite = 'WWW!';
const DescType kOpenUrlEventID = 'OURL';
const DescType kOpenUrlWindowID = 'WIND';
const DescType kCloseAllWindowsEventID = 'CLSA';
const OSType MSIE_CREATOR = 'MSIE';
const OSType NETSCAPE_CREATOR = 'MOSS';
const OSType MOZILLA_CREATOR = 'MOZZ';
const OSType AOL_CREATOR = 'AOp3';
const OSType OMNIWEB_CREATOR = 'OWEB';
const OSType ICAB_CREATOR = 'iCAB';
const OSType CHIMERA_CREATOR = 'CHIM';
const OSType OPERA_CREATOR = 'OPRA';
const OSType SAFARI_CREATOR = 'sfri';
const OSType MOSAIC_CREATOR = 'MOS!';
const OSType MOSAIC_BrowserSuite = 'mos!';
const OSType MOSAIC_OpenUrlEventID = 'ourl';
// create an open url event, using either an address desc if desc is
not nil, or appSig if desc is nil.
OSErr MakeOpenURLEvent( const char* url, AEDesc *theAppleEventPtr,
OSType appSignature, AEAddressDesc *desc = nil, Boolean newWindow =
true )
{
AEDesc target;
OSErr err;
AEEventClass eventClass;
AEEventID eventID;
if( MOSAIC_CREATOR == appSignature )
{
eventClass = MOSAIC_BrowserSuite;
eventID = MOSAIC_OpenUrlEventID;
}
else
{
eventClass = kWebBrowserSuite;
eventID = kOpenUrlEventID;
}
if( desc == nil ) // Create an application signature address
{
err = AECreateDesc( typeApplSignature, &appSignature, sizeof( OSType
), &target );
if( err ) return( err );
}
else // use the given address
target = *desc;
// Create the Apple event
err = AECreateAppleEvent( eventClass, eventID, &target,
kAutoGenerateReturnID, kAnyTransactionID, theAppleEventPtr );
if( err ) goto MakeOpenURLEvent_DisposeTarget;
// Add the URL as the direct object
err = AEPutParamPtr( theAppleEventPtr, keyDirectObject, typeChar, url,
strlen(url) );
if( err ) goto MakeOpenURLEvent_DisposeTargetAndEvent;
// Add the targetted window parameter
long window = newWindow ? 0 : -1; // kNewWindow = 0, kSameWindow = -1
err = AEPutParamPtr( theAppleEventPtr, kOpenUrlWindowID,
typeLongInteger, &window, sizeof( window ) );
if( err ) goto MakeOpenURLEvent_DisposeTargetAndEvent;
AEDisposeDesc( &target );
return( noErr );
// error handling: reverse-order cleanup
MakeOpenURLEvent_DisposeTargetAndEvent:
AEDisposeDesc( theAppleEventPtr );
MakeOpenURLEvent_DisposeTarget:
if( desc == nil ) AEDisposeDesc( &target ); // only destroy target if
we created it
return( err );
}
// return the sender of the apple event in desc. Remember to throw the
description away with AEDisposeDesc()
OSErr GetSenderAddressDesc( const AppleEvent *inAppleEvent,
AEAddressDesc *desc )
{
TargetID theTarget;
DescType theType;
Size theSize;
OSErr err = AEGetAttributePtr( inAppleEvent, keyAddressAttr,
typeTargetID, &theType, &theTarget, sizeof( TargetID ), &theSize );
if( err == errAECoercionFail )
err = AEGetAttributePtr( inAppleEvent, keyAddressAttr, typeSessionID,
&theType, &theTarget.sessionID, sizeof( PPCSessRefNum ), &theSize );
if( err ) return( err );
err = AECreateDesc( typeSessionID, &theTarget.sessionID, sizeof(
PPCSessRefNum ), desc );
return( err );
}
#include "MoreFilesExtras.h"
OSErr LaunchApp( FSSpec *theFile, ProcessSerialNumber
*launchSerialNumber )
{
LaunchParamBlockRec launchParms;
OSErr err;
launchParms.launchBlockID = extendedBlock;
launchParms.launchEPBLength = extendedBlockLen;
launchParms.launchFileFlags = 0;
launchParms.launchControlFlags = launchContinue + launchNoFileFlags;
launchParms.launchAppSpec = (FSSpec*) &(theFile->vRefNum);
launchParms.launchAppParameters = nil;
err = LaunchApplication(&launchParms);
if( err != noErr )
return err;
if( launchSerialNumber )
*launchSerialNumber = launchParms.launchProcessSN;
// make sure app is brought to front
SetFrontProcess( &launchParms.launchProcessSN );
return( err );
}
OSErr FindInFolderByCreator( short vRefNum, long dirID, OSType creator,
OSType fileType, FSSpec *foundSpec )
{
OSErr err;
HFileParam pb;
short idx = 1;
do {
pb.ioVRefNum = vRefNum;
pb.ioDirID = dirID;
pb.ioFDirIndex = idx++;
pb.ioNamePtr = foundSpec->name;
pb.ioFVersNum = 0;
err = PBHGetFInfoSync ((HParmBlkPtr)&pb);
if (!err) {
if (pb.ioFlFndrInfo.fdCreator == creator && (fileType == 0 ||
pb.ioFlFndrInfo.fdType == fileType)) {
foundSpec->vRefNum = vRefNum;
foundSpec->parID = dirID;
return noErr;
}
}
} while (!err);
return err;
}
OSErr LaunchAppByCreator( short vRefNum, long dirID, OSType creator,
OSType fileType )
{
FSSpec file;
OSErr theErr;
theErr = FindInFolderByCreator( vRefNum, dirID, creator, fileType,
&file );
if( !theErr ) theErr = LaunchApp( &file, nil );
return( theErr );
}
OSErr GetProcessSerialNumber( OSType signature, ProcessSerialNumber
*process = nil ) // if nil is passed, just check if the process is
running
{
int i = 0;
OSErr err;
ProcessInfoRec info;
ProcessSerialNumber psn;
Boolean result;
Str255 name;
psn.highLongOfPSN = 0;
psn.lowLongOfPSN = kNoProcess;
do
{
err = GetNextProcess( &psn );
if( !err )
{
info.processInfoLength = sizeof (info);
info.processName = name;
info.processAppSpec = nil;
err = GetProcessInformation( &psn, &info );
if( !err )
{
if( info.processSignature == signature && info.processType ==
'APPL' )
{
if( process ) *process = psn;
return( noErr );
}
}
}
}
while( !err );
return( procNotFound );
}
OSErr FindApplicationByCreator( OSType signature, FSSpec *spec = nil )
// if nil is passed, just check if the app exists on this computer
{
int i = 1;
HParamBlockRec HPBlock;
DTPBRec pbdt;
OSErr err = noErr;
StrFileName name;
while( !err )
{
//u long freeBytes;
//u long totalBytes;
//spec->vRefNum = 0;
//err = GetVolInfo( name, spec->vRefNum, i, crdate );
//HGetVInfo( i, name, &spec->vRefNum, &freeBytes, &totalBytes );
HPBlock.volumeParam.ioCompletion = nil;
HPBlock.volumeParam.ioNamePtr = name;
HPBlock.volumeParam.ioVRefNum = 0; // output will be vRefNum of
drive
HPBlock.volumeParam.ioVolIndex = i;
err = PBHGetVInfo( &HPBlock, false );
i++;
if( !err )
{
name[0] = 0; // clear the name string
pbdt.ioNamePtr = name;
pbdt.ioVRefNum = HPBlock.volumeParam.ioVRefNum;
err = PBDTGetPath( &pbdt );
if( !err )
{
pbdt.ioIndex = 0;
pbdt.ioFileCreator = signature;
err = PBDTGetAPPLSync( &pbdt );
if( !err ) // found the app
{
if( spec )
{
CopyString( name, spec->name );
spec->vRefNum = HPBlock.volumeParam.ioVRefNum;
spec->parID = pbdt.ioAPPLParID;
}
return( noErr );
}
}
err = noErr;
}
}
return( afpItemNotFound );
}
OSErr LaunchApplicationByCreator( OSType signature, OSType fileType =
'APPL' )
{
FSSpec spec;
OSErr err = FindApplicationByCreator( signature, &spec );
if( err ) return( err );
return( LaunchAppByCreator( spec.vRefNum, spec.parID, signature,
fileType ) );
}
OSErr QuitApplicationByCreator( OSType signature )
{
ProcessSerialNumber psn;
ProcessInfoRec info;
AEAddressDesc address;
AEDesc event, reply;
FSSpec spec;
OSErr err = GetProcessSerialNumber( signature, &psn );
if( !err ) // the process is running
{
err = AECreateDesc( typeProcessSerialNumber, &psn, sizeof( psn ),
&address );
if( err ) return( err );
err = AECreateAppleEvent( kCoreEventClass, kAEQuitApplication,
&address, kAutoGenerateReturnID, kAnyTransactionID, &event );
if( err ) goto QuitApplicationByCreator_DisposeAddress;
err = AESend( &event, &reply, kAENoReply, kAEHighPriority,
kAEDefaultTimeout, nil, nil );
if( err ) goto QuitApplicationByCreator_DisposeAddressAndEvent;
}
else
return( err );
AEDisposeDesc( &reply );
QuitApplicationByCreator_DisposeAddressAndEvent:
AEDisposeDesc( &event );
QuitApplicationByCreator_DisposeAddress:
AEDisposeDesc( &address );
return( err );
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden