c++: how to get all open safari windows

Discussion in 'Mac Programming' started by habi, Oct 13, 2007.

  1. habi macrumors newbie

    Joined:
    Oct 13, 2007
    #1
    Hi all,

    can anybody help me and tell me how i can check if there are any open Safari-Windows with C++? Or to iterate over them to get the window names or even better to get the titles of all open tabs?

    Any help would be highly appreciated.

    thanks in advance

    Habi
     
  2. italiano40 macrumors 65816

    italiano40

    Joined:
    Oct 7, 2007
    Location:
    NY
    #2
    i would search online for a method that can iterate the open programs on mac OSX which is hard because it don't have that feature build into C++ unlike windows, but keep searching online
     
  3. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
  4. italiano40 macrumors 65816

    italiano40

    Joined:
    Oct 7, 2007
    Location:
    NY
    #4
    yea make a helper file in apple script then in C++ you run it thru the terminal window and get the output from the program that can be read by C++ that should work
     
  5. larkost macrumors 6502a

    Joined:
    Oct 13, 2007
    #5
    What you are really looking for is to send AppleEvents, the language that AppleScript uses to talk to Applications. You can make these calls through Carbon. Here is the reference for it:

    http://developer.apple.com/document...doc/uid/TP40001449-CH201-DontLinkElementID_65

    This is not really easy (and quite annoying to parse out the results) in 10.4 (it is possible), without being able to say much, there are good things coming.
     
  6. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #6
    Actually the scripting bridge is public info now (Apple mentioned it in a developer.apple.com article). Such an awesome technology. I'm really looking forward to seeing what people build with it.
     
  7. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #7
    Easy with AppleScript, doable by sending AppleEvents directly from C or C++ code. Have fun.
     
  8. cblackburn macrumors regular

    Joined:
    Jul 5, 2005
    Location:
    London, UK
    #8
    Any chance of a link to that article. So far my googling has turned up nothing.

    Chris
     
  9. habi thread starter macrumors newbie

    Joined:
    Oct 13, 2007
    #9
    Ok thanks for the information for now. Can anybody give me some information on how to get this informatiopn via AppleScript?? I'm a total newby on MAC, so i have problems to get a start with all that new technologies...

    Habi
     
  10. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #10
    www.developer.com, then type in "running programs", and one of the links is a rather nice bit of Apple sample code that will quit every running application.
     
  11. hhas macrumors regular

    Joined:
    Oct 15, 2007
    #11
    Doing Apple events from C/C++ is fairly tedious, even using the AEBuild* functions. The following code will give you the window names:

    Code:
    #include <Carbon/Carbon.h>
    
    int main (int argc, const char * argv[]) {
    	char *bundleID = "com.apple.textedit";
    	AppleEvent event, reply;
    	AEDesc listDesc, nameDesc;
    	Size nameSize;
    	char *name;
    	long listLen, i;
    	OSStatus err;
    	
    	// build Apple event
    	err = AEBuildAppleEvent(kAECoreSuite,
    									 kAEGetData,
    									 typeApplicationBundleID,
    									 bundleID,
    									 strlen(bundleID),
    									 kAutoGenerateReturnID,
    									 kAnyTransactionID,
    									 &event,
    									 NULL,
    									 "'----':'obj '{form:prop, want:type(prop), seld:type(pnam), from:"
    											"'obj '{form:indx, want:type(cwin), seld:abso('all '), from:()}}");
    	if (err) return err;
    	
    	// send Apple event
    	err = AESendMessage(&event, &reply, kAEWaitReply, kAEDefaultTimeout);
    	AEDisposeDesc(&event);
    	if (err) return err;
    	
    	// get return value from reply event
    	err = AEGetParamDesc(&reply,
    						 keyAEResult,
    						 typeAEList,
    						 &listDesc);
    	AEDisposeDesc(&reply);
    	if (err) return err;
    	
    	// get each descriptor from list
    	err = AECountItems(&listDesc, &listLen);
    	if (err) goto cleanup;
    	
    	for (i=0; i<listLen; i++) {
    		AEKeyword key;
    		err = AEGetNthDesc(&listDesc,
    						   i + 1,
    						   typeUTF8Text,
    						   &key,
    						   &nameDesc);
    		if (err) goto cleanup;
    		
    		// get UTF8 text from descriptor
    		nameSize = AEGetDescDataSize(&nameDesc);
    		name = malloc(nameSize);
    		err = AEGetDescData(&nameDesc,
    							name,
    							nameSize);
    		AEDisposeDesc(&nameDesc);
    		if (err) goto cleanup;
    		
    		// do stuff with it...
    		printf("%.*s\n", nameSize, name);
    		free(name);
    	}
    	
    cleanup:
    	AEDisposeDesc(&listDesc);	
    	return err;
    }
    If you've got Safari 3 then you should be able to get tab names as well, though the code's a bit more complex for that and you may find it easier to write the bulk of it in AppleScript and call it via the OSA API. In theory you should be able to say 'tell app "Safari" to get name of every tab of every window', but the implementation seems a bit glitchy at the moment, so you'll have to fiddle with it to see what works (and file bugs on what doesn't).

    If you're on Safari 2, the only way you'll get tab names is by hacking about with GUI Scripting.

    HTH
     
  12. jstad macrumors regular

    jstad

    Joined:
    Jun 13, 2007
    #12
    side question, any good tutorials for applescript besides the ones on apple's website? I do not really like scouring apple's doc site (always get lost in the maze of documents hyperlinks lol)
     
  13. hhas macrumors regular

    Joined:
    Oct 15, 2007
    #13
    FWIW, you don't need to wait for Leopard to experience the joys of scripting applications without AppleScript: there are already several very good, mature high-level bridges for Perl, Python, Ruby and ObjC; see Mac::Glue and appscript. (Obligatory disclaimer: I wrote the latter.)

    (Late Night Software also do a JavaScriptOSA component and don't forget Frontier/UserTalk (the granddaddy of them all), although they're both a bit hokey and somewhat neglected these days, and I wouldn't recommend trying them except perhaps as items of historical interest.)


    Scripting Bridge is very briefly mentioned here. Basically it's an ObjC code/class generator that creates ObjC classes based on an application's AppleScript dictionary, either statically (for use in ObjC-based programs) or on the fly (to be used from scripting languages that have ObjC bridges).

    From what I've heard about it (and given Apple's previous two-steps-forward-one-step-backwards record on other AppleScript-related technologies) I'm not expecting it to be good as AppleScript (or appscript, for that matter), although I'll have to get me some proper hands-on time with a shiny new Leopard box before passing definite judgement.

    HTH
     
  14. hhas macrumors regular

    Joined:
    Oct 15, 2007
    #14
    If you already know how to program, get Matt Neuburg's AppleScript: The Definitive Guide (2nd edition), which does the best job of cutting through the brain-damaged mess that is AppleScript that I'm aware of.

    If you want deeper insights into the technology, there's a couple of PDF papers by the original AppleScript designers that are well worth reading. I've got links to them on the appscript website's links page; see my sig.

    HTH
     

Share This Page