TweetFollow Us on Twitter

Modifying Objects At Runtime

Volume Number: 15 (1999)
Issue Number: 3
Column Tag: PowerPlant Workshop

Modifying Objects at Runtime in PowerPlant

By John C. Daub, Austin, Texas USA

A look at PowerPlant's Attachments mechanism

Welcome!

One of the things that makes the Mac so great and so much fun to use is the ability to customize your Mac just the way you like it. There are all sorts of cool functional utilities like Monaco Tuner/ProFont and FinderPop, and many cosmetic enhancers like the ubiquitous Kaleidoscope. Just how do these cool tools do the voodoo that they do so well? Through the magic of trap patching! Patching traps is a neat way to change the runtime behavior of an application and/or the OS itself without having to actually change the application or OS. Think of it like subclassing to implement new functionality for an object, but you didn't have to subclass to actually gain the new functionality - something else came in at runtime and modified the object's behavior.

If that explanation only served to further confuse you, I apologize. However, by the end of this article you will have a better understanding of the statement. You see, PowerPlant has a mechanism akin to patching called Attachments. Attachments are a way to modify the runtime behavior of PowerPlant objects, so in a sense it can be viewed as patching. By using PowerPlant's Attachments mechanism you can extend, limit, or otherwise change the behavior of a PowerPlant object at runtime, and all through a mechanism that's simple yet very powerful; in fact the theory of the Attachments mechanism will play a larger role throughout PowerPlant in future versions of the framework.

By the way, if you're curious about trap patching, check out a book like Dave Mark's Ultimate Mac Programming. Dave recruited Jorg Brown to write the chapter on trap patching, so you'll definitely be in good hands.

Overview

PowerPlant's Attachment mechanism is comprised of two parts: the Attachment's host and the Attachment itself.

Attachables

An object that can host Attachments is called an Attachable. The LAttachable class defines an Attachable object, and any class that inherits from LAttachable can have Attachments attached to it (you cannot attach Attachments to objects that are not Attachables). Within PowerPlant, LAttachable is used as a virtual base class for some key base objects: LCommander, LEventDispatcher, and LPane (see my introduction to PowerPlant article in the December 1998 MacTech or refer to the PowerPlant Book, Metrowerks' official documentation on PowerPlant, for an explanation of these classes)


Figure 1. LAttachable class hierarchy.

Although Figure 1 does not look like much, do not forget the great number of classes that inherit from LCommander and LEventDispatcher, and especially the multitude of classes that inherit from LPane (there was just no way to print such a large hierarchy within the constraints of this article). Since these key objects are Attachables, you can begin to see that many of PowerPlant's key behaviors can be modified through the use of Attachments.

The LAttachable class provides all the functionality a host needs to manage Attachments. One can AddAttachment() or RemoveAttachment() to add or remove Attachments from the Attachable's internal list of Attachments. If you're in a hurry, you can call RemoveAllAttachments() to remove all of an Attachable's Attachments. Accessors are provided to GetDefaultAttachable() and SetDefaultAttachable() (the default Attachable is the object to which an Attachment will be attached when it is created from a PPob DataStream). Finally LAttachable provides ExecuteAttachments() as the ever-important means to allow Attachments to carry out their task. Most of your interactions with LAttachable will be through AddAttachment() (and possibly RemoveAttachment()), as the rest is handled for you within PowerPlant itself. Of course the other part of the equation here are the Attachments themselves, so let's take a look at them.

Attachments

An Attachment is an object that can modify the runtime behavior of another object without having to modify that object itself. Through the use of Attachments, you can modify how an object: handles events, draws or prints, handles clicks and keypresses, adjusts the cursor, responds to commands and actions, and even how it finishes creating itself. Figure 2 presents the Attachment classes provided by PowerPlant.


Figure 2. LAttachment class hierarchy.

The points at which the Attachments are given the opportunity to modify the runtime behavior of its host object (i.e. the places within PowerPlant where LAttachable::ExecuteAttachments() is called) are well defined by the PowerPlant API. Since the intent of an Attachment is to modify the "normal" behavior of an object, this Attachment execution point occurs immediately before the host object executes its normal course of action. So just before that mouse click is given to the Pane object for processing, the Pane's Attachments are given first crack at the click. Listing 1 illustrates how this looks in code.

Listing 1: Attachment execution point

LPane::Click()
void
LPane::Click(
   SMouseDownEvent&      inMouseDown)
{
   if (!inMouseDown.delaySelect) {
   
      PortToLocalPoint(inMouseDown.whereLocal);
      
      UpdateClickCount(inMouseDown);
      
      if (ExecuteAttachments(msg_Click, &inMouseDown)) {
         ClickSelf(inMouseDown);
      }
   }
}

When Click() is called, a little housekeeping is performed, then just before the actual handling of the click is to occur (ClickSelf()), the Pane's Attachments execute and could veto the execution of the Pane's normal click functionality. We'll look at how all of this works in the next section.

Like the LAttachable class, the LAttachment class is also quite simple. It contains constructors and a destructor, as one would expect of a C++ class. One item to note is LAttachment has an LStream constructor, which means that Attachment objects, like Pane objects, can be constructed from a PPob DataStream. You can edit Attachments in Constructor, they have class_ID's, and must be registered (see URegistrar) if you create your Attachments in this manner. If you've worked with Panes in PPob's, this procedure should be familiar to you. If you're not familiar with this procedure, it is covered in the PowerPlant Book.

There are three data members in LAttachment: mOwnerHost, mMessage, and mExecuteHost (and all three have associated Get/Set accessor methods). The first data member, mOwnerHost, is a pointer to the Attachment's host object for easy reference. The mMessage data member stores the particular message that the Attachment is to respond to. Finally, the mExecuteHost member is a Boolean value which specifies if the host should continue to execute its normal course of action or not. In the next section you'll see how these data members come into play.

The remaining two methods in LAttachment are Execute() and ExecuteSelf(). This is where all of the action happens, so to better explain them let's take a look at just how the Attachment mechanism actually works.

How Does It Work?

As you saw in the previous sections, the LAttachable and LAttachment classes are fairly simple, and the mechanisms by which they are implemented and execute are fairly simple as well. As mentioned previously, an Attachable iterates its list of Attachments at a well-defined point asking them to execute and passing them any relevant information the Attachment may need in order to properly execute in the given context. Figure 3 summarizes those points within PowerPlant.


Figure 3. Attachment execution points.

When in the course of an application's events it becomes necessary to execute an Attachment (the Where Called column in Figure 3), the host iterates its list of Attachments asking each if it cares to do something relevant to the given situation; this is done by calling the Attachment's Execute() method. Within Execute() the Attachment checks the message given to it by its host; if that message is the same as the Attachment's mMessage (or is the special msg_AnyMessage), then Attachment then calls its ExecuteSelf() to do its voodoo. Within ExecuteSelf() the Attachment of course does whatever it does (respond to the click, handle the event, modify the host's cosmetics, etc.), but also must specify if upon returning the host should continue to execute its normal action or not by calling SetExecuteHost(). If the Attachment wishes to completely override the host's behavior, the Attachment should SetExecuteHost(false). If the Attachment wishes to merely augment the behavior, SetExecuteHost(true). Note this only affects the execution of the host action; if the host has other Attachments that have not yet executed, they will still execute.

That's all there is to how the Attachment mechanism works! It is such a simple mechanism, but so much can be accomplished through it. If you still don't believe me, there is an example application on the CodeWarrior Reference CD (the Attacher demo, part of the PP Mini Demos) and I've written a sampler to accompany this article as well (which should be on the MacTech web/ftp site). The Attacher demo shows how the mechanics of Attachments work, and my demo can show you all of the things you can do with Attachments.

Working With Attachments

Now that you understand how Attachments work, I'm sure you want to start to actually work with Attachments. Just as the mechanism itself is fairly simple, working with Attachments isn't very difficult either. The two primary areas in which you will work with Attachments is how to add/use them within your own projects, and how to create your own Attachments.

Adding Attachments

There are two ways to add an Attachment to an Attachable: on the fly or through a PPob. To add an Attachment on the fly you first create the Attachment via its "parameterized" constructor, then add it to a host by calling the host's AddAttachment() method. Listing 2 illustrates adding an LClipboard Attachment to your Application object (CApplication represents your Application object subclass, and remember that LApplication inherits from LCommander, which inherits from LAttachable).

Listing 2: Adding an Attachment on the fly

CApplication::Initialize()
void
CApplication::Initialize()
{
      // Create the LClipboard Attachment
   LClipboard*   theClipAttachment = new LClipboard;

      // Attach it to our Application object
   AddAttachment(theClipAttachment);
}

Although some Attachments, like LClipboard must be created and added on the fly as above, other Attachments can be created from a PPob DataStream (many Attachments support both creation mechanisms). Just like you can edit the Panes in your PPob's within Constructor for that wonderful WYSIWYG experience, you can add and edit some Attachments in Constructor as well.


Figure 4. Editing Attachments in Constructor.

As mentioned previously, to create your Attachment via the PPob DataStream, the Attachment must have an LStream constructor and a class_ID, just like Panes that you create from the PPob DataStream. As well, you must register your Attachment with URegistrar so the reanimation process will work correctly (again, for more information on PowerPlant's reanimation and registration mechanisms, consult the PowerPlant Book). If you create your Attachments in your PPob's, the Attachment is attached to whatever object it is hierarchically beneath. In Figure 4, the LWindowThemeAttachment will be attached to the LWindow; the LBeepAttachment is attached to the LStaticText. This is where the default attachable comes into play. Take a look at LAttachment's LStream constructor and the routines in UReanimator to see exactly how the default attachable is used.

In addition to editing Attachments in PPob's, you can also edit the CTYP information for the Attachment's themselves. By creating your own CTYP's for your Constructor objects, they'll appear in the Catalog window and can facilitate working in Constructor. Figure 5 shows the Constructor CTYP editor. Of course you can find more information on creating CTYP's and using Constructor in the Constructor Manual, Metrowerks documentation for Constructor.


Figure 5. Editing Attachment CTYP's in Constructor.

Creating your own Attachments

With what I've shown you so far, I hope you've been able to see just how simple it is to work with Attachments. But if there is anything difficult about Attachments it might be writing your own Attachment classes. The process itself isn't difficult - it's the first step of finding the behavior to implement that might throw you off a bit. Before you begin to write the Attachment you must design it well. You must decide what behavior you wish to implement, and then how it will fit into the Attachment mechanism: what message(s) to respond to; if the host should execute or not, and then under what circumstances to execute or not; if the Attachment can be created from a PPob DataStream; etc.

As soon as you have your design and goal(s) for the Attachment set, the implementation process is fairly short and simple. You need to have at least one constructor that allows the Attachment to be created on the fly. If the Attachment can be created from a PPob DataStream you must provide an LStream constructor and class_ID. Then implement your ExecuteSelf() to do the Attachment's magic, and you're done! In the implementation of ExecuteSelf(), be aware to SetExecuteHost() as needed. And if you wish to add that finishing touch, create a CTYP file for your Attachment so it can be easily edited within Constructor.

Take a look at the Attachments that PowerPlant provides, such as those in UAttachments.cp. There isn't much to their implementation, but as you use Attachments more and more you'll find yourself appreciating that simplicity. Conversely, if you look at my HCmdButtonAttachment (which is part of the demo application that accompanies this article), you'll see that Attachments aren't always lightweight, but the power they can bring makes them a great tool to have in your toolchest.

Why Use Attachments?

If you've made it this far, I hope that you've been able to gain an understanding of what Attachments are and just how they work within PowerPlant. You've seen the LAttachable and LAttachment classes, how the Attachments mechanism works, and how to build your own Attachments. But there is one question that remains: why would you use Attachments?

Remember that Attachments modify the runtime state and/or behavior of their host object. By being able to add to, remove from, or otherwise modify how an object behaves, you can do some nifty stuff and have a lot of code to reuse to boot. For example, a common feature in Mac applications today is the ability to simulate a mouse click on a button in a dialog with a keystroke; for instance, cmd-D could simulate a click on the "Don't Save" button in a "Save Changes" dialog. If you wanted to implement this behavior in a button class, you would subclass your main button class and implement the functionality to support the keystroke-as-click behavior. You did this for your PushButton class, but now you want the same functionality in your BevelButton class, so you have to reimplement the same code all over again. Then you want to have it in your CheckBox class, then your RadioButton class, and then you realize you want it in so many of your classes that it would be better to place it into a common parent class, but then this would break PowerPlant's existing inheritance chains so you would have to reimplement every single button widget you used... and you give up because this is getting ridiculous.

Consider the Attachment. You are implementing a behavior: handle a keystroke as if it was a click on a button (or any control for that matter). You create an Attachment that can intercept msg_KeyPress's, and whose ExecuteSelf(), upon receiving the correct keystroke calls SimulateHotSpotClick(), and you've now clicked the button without ever putting your hands on your mouse. Furthermore you've factored this behavior into stand-alone and reusable code. You can easily add this Attachment to your PushButtons, your BevelButtons, your RadioButtons, CheckBoxes, and any other Control you might desire. All the same code, no need to repeat nor reimplement the code, and no need to subclass anything - you can use stock objects. This is essentially what all Attachments do, and slightly more specific to this example, what the HCmdButtonAttachment Attachment does.

Attachments are also good for implementing new behaviors for legacy code. PowerPlant's Debugging Classes are centered around a menu that is added to your application's menubar and provides functionality to help debug and stress-test your application (see the Factory Floor column in the November, 1998 issue of MacTech for an overview of the Debugging Classes). Because the menu is implemented as an Attachment (LDebugMenuAttachment) it makes it quite simple to add and remove this functionality from an existing application. Furthermore, it enables you to have the Debug menu only in the debug builds of your application and not in your release builds. The modularity and "drop-in" capabilities of Attachments is another strength.

Conclusion

I hope you've been able to see what Attachments have to offer you as you continue you work with PowerPlant. If you have not used Attachments, do try the two demo applications and read over the various Attachment classes' source code; give them a try in your own applications. Most of the PowerPlant code that I've written recently has been Attachment based (e.g. LCMAttachment, LDebugMenuAttachment, HURLAttachment), and I find it to be one of the niftier and more flexible mechanisms that PowerPlant has to offer. After you're more familiar with Attachments, I'm sure you'll also find a place for them in your toolbox. What you can do with Attachments is pretty limitless, and after you write your first Attachment class I'm sure you'll agree with me.

Until next time... Happy programming!

Bibliography

  • Mark, Dave. Ultimate Mac Programming. Programmers Press, A Division of IDG Books Worldwide, Inc., Foster City, California. 1994.
  • Metrowerks Corporation. Constructor Manual. 1998.
  • Metrowerks Corporation. PowerPlant Book. 1998.
  • Metrowerks Corporation. PowerPlant Reference. 1998.
  • Monaco Tuner and ProFont: ftp://members.aol.com/squeegee/.
  • FinderPop: http://www.finderpop.com/.
  • Kaleidoscope: http://www.kaleidoscope.net/.

John C. Daub is one of Metrowerks Corporation's PowerPlant engineers. John wonders if you really care to know quirky biographical information about him, and if so, why? If you really want to know strange things about John or wish to ask him any questions (about PowerPlant or otherwise), you can reach John via email at hsoi@metrowerks.com.

 
AAPL
$467.36
Apple Inc.
+0.00
MSFT
$32.87
Microsoft Corpora
+0.00
GOOG
$885.51
Google Inc.
+0.00

MacTech Search:
Community Search:

Software Updates via MacUpdate

VueScan 9.2.23 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
Acorn 4.1 - Bitmap image editor. (Demo)
Acorn is a new image editor built with one goal in mind - simplicity. Fast, easy, and fluid, Acorn provides the options you'll need without any overhead. Acorn feels right, and won't drain your bank... Read more
Mellel 3.2.3 - Powerful word processor w...
Mellel is the leading word processor for OS X, and has been widely considered the industry standard since its inception. Mellel focuses on writers and scholars for technical writing and multilingual... Read more
Iridient Developer 2.2 - Powerful image...
Iridient Developer (was RAW Developer) is a powerful image conversion application designed specifically for OS X. Iridient Developer gives advanced photographers total control over every aspect of... Read more
Delicious Library 3.1.2 - Import, browse...
Delicious Library allows you to import, browse, and share all your books, movies, music, and video games with Delicious Library. Run your very own library from your home or office using our... Read more
Epson Printer Drivers for OS X 2.15 - Fo...
Epson Printer Drivers includes the latest printing and scanning software for OS X 10.6, 10.7, and 10.8. Click here for a list of supported Epson printers and scanners.OS X 10.6 or laterDownload Now Read more
Freeway Pro 6.1.0 - Drag-and-drop Web de...
Freeway Pro lets you build websites with speed and precision... without writing a line of code! With it's user-oriented drag-and-drop interface, Freeway Pro helps you piece together the website of... Read more
Transmission 2.82 - Popular BitTorrent c...
Transmission is a fast, easy and free multi-platform BitTorrent client. Transmission sets initial preferences so things "Just Work", while advanced features like watch directories, bad peer blocking... Read more
Google Earth Web Plug-in 7.1.1.1888 - Em...
Google Earth Plug-in and its JavaScript API let you embed Google Earth, a true 3D digital globe, into your Web pages. Using the API you can draw markers and lines, drape images over the terrain, add... Read more
Google Earth 7.1.1.1888 - View and contr...
Google Earth gives you a wealth of imagery and geographic information. Explore destinations like Maui and Paris, or browse content from Wikipedia, National Geographic, and more. Google Earth... Read more

Strategy & Tactics: World War II Upd...
Strategy & Tactics: World War II Update Adds Two New Scenarios Posted by Andrew Stevens on August 12th, 2013 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Expenses Planner Review
Expenses Planner Review By Angela LaFollette on August 12th, 2013 Our Rating: :: PLAIN AND SIMPLEUniversal App - Designed for iPhone and iPad Expenses Planner keeps track of future bills through due date reminders, and it also... | Read more »
Kinesis: Strategy in Motion Brings An Ad...
Kinesis: Strategy in Motion Brings An Adaptation Of The Classic Strategic Board Game To iOS Posted by Andrew Stevens on August 12th, 2013 [ | Read more »
Z-Man Games Creates New Studio, Will Bri...
Z-Man Games Creates New Studio, Will Bring A Digital Version of Pandemic! | Read more »
Minutely Review
Minutely Review By Jennifer Allen on August 12th, 2013 Our Rating: :: CROWDSOURCING WEATHERiPhone App - Designed for the iPhone, compatible with the iPad Work together to track proper weather conditions no matter what area of the... | Read more »
10tons Discuss Publishing Fantasy Hack n...
Recently announced, Trouserheart looks like quite the quirky, DeathSpank-style fantasy action game. Notably, it’s a game that is being published by established Finnish games studio, 10tons and developed by similarly established and Finnish firm,... | Read more »
Boat Watch Lets You Track Ships From Por...
Boat Watch Lets You Track Ships From Port To Port Posted by Andrew Stevens on August 12th, 2013 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Expenses Review
Expenses Review By Ruairi O'Gallchoir on August 12th, 2013 Our Rating: :: STUNNINGiPhone App - Designed for the iPhone, compatible with the iPad Although focussing primarily on expenses, Expenses still manages to make tracking... | Read more »
teggle is Gameplay Made Simple, has Play...
teggle is Gameplay Made Simple, has Players Swiping for High Scores Posted by Andrew Stevens on August 12th, 2013 [ permalink ] | Read more »
How To: Manage iCloud Settings
iCloud, much like life, is a scary and often unknowable thing that doesn’t always work the way it should. But much like life, if you know the little things and tweaks, you can make it work much better for you. I think that’s how life works, anyway.... | Read more »

Price Scanner via MacPrices.net

13″ 2.5GHz MacBook Pro on sale for $150 off M...
B&H Photo has the 13″ 2.5GHz MacBook Pro on sale for $1049.95 including free shipping. Their price is $150 off MSRP plus NY sales tax only. B&H will include free copies of Parallels Desktop... Read more
iPod touch (refurbished) available for up to...
The Apple Store is now offering a full line of Apple Certified Refurbished 2012 iPod touches for up to $70 off MSRP. Apple’s one-year warranty is included with each model, and shipping is free: -... Read more
27″ Apple Display (refurbished) available for...
The Apple Store has Apple Certified Refurbished 27″ Thunderbolt Displays available for $799 including free shipping. That’s $200 off the cost of new models. Read more
Apple TV (refurbished) now available for only...
The Apple Store has Apple Certified Refurbished 2012 Apple TVs now available for $75 including free shipping. That’s $24 off the cost of new models. Apple’s one-year warranty is standard. Read more
AnandTech Reviews 2013 MacBook Air (11-inch)...
AnandTech is never the first out with Apple new product reviews, but I’m always interested in reading their detailed, in-depth analyses of Macs and iDevices. AnandTech’s Vivek Gowri bought and tried... Read more
iPad, Tab, Nexus, Surface, And Kindle Fire: W...
VentureBeat’s John Koetsier says: The iPad may have lost the tablet wars to an army of Android tabs, but its still first in peoples hearts. Second place, however, belongs to a somewhat unlikely... Read more
Should You Buy An iPad mini Or An iPad 4?
Macworld UK’s David Price addresses the conundrum of which iPAd to buy? Apple iPad 4, iPad 2, iPad mini? Or hold out for the iPad mini 2 or the iPad 5? Price notes that potential Apple iPad... Read more
iDraw 2.3 A More Economical Alternative To Ad...
If you’re a working graphics pro, you can probably justify paying the stiff monthly rental fee to use Adobe’s Creative Cloud, including the paradigm-setting vector drawing app. Adobe Illustrator. If... Read more
New Documentary By Director Werner Herzog Sho...
Injuring or even killing someone because you were texting while driving is a life-changing experience. There are countless stories of people who took their eyes off the road for a second and ended up... Read more
AppleCare Protection Plans on sale for up to...
B&H Photo has 3-Year AppleCare Warranties on sale for up to $105 off MSRP including free shipping plus NY sales tax only: - Mac Laptops 15″ and Above: $244 $105 off MSRP - Mac Laptops 13″ and... Read more

Jobs Board

Sales Representative - *Apple* Honda - Appl...
APPLE HONDA AUTOMOTIVE CAREER FAIR! NOW HIRING AUTO SALES REPS, AUTO SERVICE BDC REPS & AUTOMOTIVE BILLER! NO EXPERIENCE NEEDED! Apple Honda is offering YOU a Read more
*Apple* Developer Support Advisor - Portugue...
Changing the world is all in a day's work at Apple . If you love innovation, here's your chance to make a career of it. You'll work hard. But the job comes with more than Read more
RBB - *Apple* OS X Platform Engineer - Barc...
RBB - Apple OS X Platform Engineer Ref 63198 Country USA…protected by law. Main Function | The engineering of Apple OS X based solutions, in line with customer and Read more
RBB - Core Software Engineer - Mac Platform (...
RBB - Core Software Engineer - Mac Platform ( Apple OS X) Ref 63199 Country USA City Dallas Business Area Global Technology Contract Type Permanent Estimated publish end Read more
*Apple* Desktop Analyst - Infinity Consultin...
Job Title: Apple Desktop Analyst Location: Yonkers, NY Job Type: Contract to hire Ref No: 13-02843 Date: 2013-07-30 Find other jobs in Yonkers Desktop Analyst The Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.