• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Communicating With Browser
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Re: Communicating With Browser
      • From: Zack Morris <email@hidden>
References: 
 >Re: testing for firewall and modifying ports (From: Ryan McGann <email@hidden>)
 >Communicating With Browser (From: Zack Morris <email@hidden>)
 >Re: Communicating With Browser (From: Quinn <email@hidden>)

  • Prev by Date: Re: System Configuration Framework and PPTP (VPN) Connections
  • Next by Date: Connecting a client to a tcp server?
  • Previous by thread: Re: Communicating With Browser
  • Next by thread: Re: Communicating With Browser
  • Index(es):
    • Date
    • Thread