Scripting REALbasic through AppleEvents

October 31st, 2007 by Jonathan Johnson

Here is a Halloween treat for our REALbasic-using readers:

At some point you may need to write a tool to script builds in REALbasic. For us, we have something coming down the pipeline in a few weeks that needs to do just this (let the speculations begin!), and I recalled an undocumented feature of the REALbasic IDE that makes things easier for us:

There exists an AppleEvent command of class ‘RBae’ and type ’scpt’. The direct object parameter is a string, which is the IDE Script source code to execute.

Of course, as an undocumented feature, I must stress that this could be removed at any time. The included IDE scripting command line utility is often enough to get the job done. The method described here requires less overhead, but has the downside of being harder to communicate with. (If you must communicate, you can always write a file out by using DoShellCommand. However, if you’re needing to anything beyond something simple, documented ways of doing this are much better.)

I’ll leave you with some sample code. This is all there is to it, enjoy!

Sub RunIDEScript(script as String)
  dim ae as AppleEvent
  ae = NewAppleEvent( "RBae", "scpt", "RBv2" )
  ae.StringParam("----") = "call BuildApp(8)"
  if not ae.Send then
    MsgBox "Error"
  end if
End Sub

Darwin 9 Source Code Available

October 31st, 2007 by Joe Ranieri

The source code for Darwin 9 (Leopard’s core) was made available this morning. Note that not all packages are up yet, including the Objective-C runtime and CoreFoundation.

Darwin 9 source code


iCal’s Abominable Stripes

October 29th, 2007 by Jonathan Johnson

For the most part, I like Leopard’s new look. Once upgraded to the GM release, the new dock style shocked me, but now it looks and feels great.

One bug report I filed with Apple didn’t get changed for the final release. iCal uses vertical stripes. Check it out:

It just looks awkward and out of place. I expect that one of these days the report will be closed as “Behaves as Designed.”

It’s sad: that’s how my report about the abominable PDF pop-down push-button in the print dialogs was treated. UI Inconsistencies annoy me :)


Hidden Archive Settings in OS X

October 29th, 2007 by Ryan Govostes

If you were to run find / -iname *.prefPane on your freshly installed copy of Leopard, you might notice this show up in the results:

/System/Library/CoreServices/Archive Utility.app/Contents/Resources/Archives.prefPane

Installing this preference pane allows you to change settings relating to archive creation and expansion handled by Archive Utility (formerly BOMArchiveHelper).

This joins the other known hidden prefPane introduced in 10.4, DiskImages.prefPane (hat tip to Mac OS X Hints for beating me to the punch by a year and a half).


Leopard and You

October 26th, 2007 by Joe Ranieri

Finally, Leopard’s been released and we can talk about the various things that are new. Leopard adds a bunch of fun new things for developers:

  • FSEvents: All file system events are now logged. You can monitor events in real time, or get a list of changes for a certain period of time after the fact. In order to have a minimal overhead, only the directory in which the change occurred is logged.
  • Core Animation: Animating Cocoa views can’t get much easier. Simply send the message to the view’s animator and it’ll handle all the animation for you. Here’s an example that’ll fade the view out:
    [[myView animator] setHidden:YES];
  • Objective-C 2.0: Finally Objective-C plays a bit of catch up. New are properties (handier than you’d think), garbage collection, and for each loops.
  • QuickLook: Now your application can display previews in Finder too.
  • Scripting Bridge: Use Cocoa objects to control scriptable apps, with the native Objective-C syntax.
  • CoreText: No more messing with ancient APIs to draw text at a lower level. I’m looking at you ATSUI.
  • Cocoa Bridges: Use $language to write native Mac OS X apps. Ruby and Python are supported for now (through enhanced versions PyObjC and RubyCocoa) but there may be more in the future.
  • Calendar Store: You can now access iCal’s to-dos, calendars, events and more.
  • Instruments: Find out what your application is really doing. Instruments is built around DTrace and allows you to monitor many things (network use, disk activity, spins, object leakages, etc) at once and compare them between multiple runs.

The list could go on a lot more, but that’s most of the major things, excluding private frameworks. We’ll be blogging about some of them in the following weeks :-).


Mac Control Sizes in REALbasic

October 23rd, 2007 by Jonathan Johnson

For a long time REALbasic I thought REALbasic had the ability to create both regular size controls and small controls. For some controls such as PushButton, you can simply set the height, and the control will automatically resize. However, this may not work in future OS versions, *cough cough*. Even today, many controls have a fixed height that can’t be changed, such as PopupMenus, UpDownArrows, CheckBoxes, RadioButtons, Listbox Headers, and ComboBoxes

There is a trick to making REALbasic use the Small variant for PopupMenus and ListBoxes: set the control font to SmallSystem and it will automatically adjust its size. What I didn’t realize until preparing this post was that this is just a side effect of the controls automatically sizing to fit their fonts, and none of the other above controls behave that way.

So with yet another post failing to be interesting enough to write about, I set out to make it work. The Carbon Control Manager call is SetControlData with the tag of kControlSizeTag. The code is relatively simple:

Module MacControlSizes
  Private Const kControlSizeTag = 'size'
  Enum MacControlSize
    Normal
    Small
    Large
    Mini
  End Enum 
 
 
  Sub MacControlSize(extends c as Control, assigns newSize as MacControlSize)
    if c.Handle = 0 then return
 
    declare function SetControlData lib "Carbon" (ctl as Integer, part as Integer,_
        tagName as Integer, size as Integer, byref data as MacControlSize) as Integer
 
    dim err as Integer
    err = SetControlData( c.Handle, 0, kControlSizeTag, 2, newSize )
  End Sub
End Module

For any controls this extension method doesn’t work on, it will just silently fail. The only built-in control that this method does not work on is the ComboBox, because it is a custom control on Mac OS X.

You can download the project here.


Countdown to Leopard

October 22nd, 2007 by Joe Ranieri

Currently 4 days until Leopard is released! We’ve been working on a bunch of fun projects and blog posts and can’t wait to show everything off.

We’re going to be posting about two posts a week, starting with an overview of Leopard from a developer’s point of view. Stay tuned!


Windows Users: The most useful shortcut you never knew about…

October 15th, 2007 by Jonathan Johnson

I finally had it yesterday, I just knew there had to be a way to do it. I had previously asked two other Windows gurus, and they didn’t have the answer. I searched high and low, and couldn’t find the answer.

But yesterday, I finally found it. Press the Windows key and E together. Go ahead, try it, I’ll wait.

And there you have it. There is a way to open a new Explorer window without touching your mouse.


Tweaks for APE Module Loading

October 6th, 2007 by Joe Ranieri

The Application Enhancer framework supports a number of Info.plist keys to change the behavior of APE modules, most of which are undocumented. Here are a handful:

  • APEVersionRequired (string)
    The minimum Application Enhancer framework required to run the APE.
  • APEHasIncludeList (bool)
    Does this APE module use an include list?
  • APEHasExcludeList (bool)
    Does this APE module use an exclude list?
  • APEMatchInfo (array)
    An APE module can also specify which applications it can be loaded into.

    • CFBundleIdentifier (array or string)
      The bundle IDs of specific applications that the APE module can load into.
    • APEMatchFlavor (string)
      The type of application the APE module can load into. Possible values are Carbon and Cocoa.
    • APEToolsID (string)
      A string in one of the following formats that lets you match by application name, creator/type, or path.

      • com.unknown.by-name.<name>
      • com.unknown.by-creator.<type in hex>.<creator in hex>
      • com.unknown.by-path.<path>

So, for some examples. Loading only into Safari, and disabling the include and exclude lists:

	&lt;key&gt;APEHasIncludeList&lt;/key&gt;
	&lt;false /&gt;
	&lt;key&gt;APEHasExcludeList&lt;/key&gt;
	&lt;false /&gt;
	&lt;key&gt;APEMatchInfo&lt;/key&gt;
	&lt;array&gt;
		&lt;key&gt;CFBundleIdentifier&lt;/key&gt;
		&lt;string&gt;com.apple.Safari&lt;/string&gt;
	&lt;/array&gt;

And loading into the Finder by creator (MACS) and type (FNDR), until Apple replaces it with a Cocoa application:

	&lt;key&gt;APEMatchInfo&lt;/key&gt;
	&lt;array&gt;
		&lt;key&gt;APEMatchFlavor&lt;/key&gt;
		&lt;string&gt;Carbon&lt;/string&gt;
		&lt;key&gt;APEToolsID&lt;/key&gt;
		&lt;string&gt;com.unknown.by-creator.0x464E4452.0x4D414353&lt;/string&gt;
	&lt;/array&gt;

Obviously, the creator/type matching method isn’t a good way of doing this, but in some cases it may be the only way.

Disclaimer: As several of these are undocumented, Unsanity might remove them or change their functionality in the future. It would not be wise to depend on them too much.

Ryan contributed to this post.