Apple docs help needed: Objc_msgSendSuper? (OS X, iOS)

I am experimenting a bit with the Objective C Runtime library, trying to get some custom controls running.
The problem with those built on a complex structure of views and subviews is that on a simple declare you usually don’t get all the components drawn. A simple custom TextField only reserves space to type into but shows neither frame nor other subcontrols. That’s why custom controls often mimic their originals by using custom draw routines when their layoutSubviews or drawRect method gets called.
While this is totally fine, chances are high the controls won’t look right once Apple changes the platform GUI design, which happens quite often. I think a better way would be to implement their original draw routines, probably together with a boolean value that gives the user a chance to replace the draw routines with own implementations. This would mean calling their superobject’s drawRect or layoutSubviews routines.

I couldn’t figure out how to call super like in Obj C directly, but it’s easy to build an objc_super structure by hand.

Only problem now is the structure of the objc_msgSendSuper declare. According to Apple it is

[quote]id objc_msgSendSuper ( struct objc_super *super, SEL op, … );
Parameters
super
A pointer to an objc_super data structure. Pass values identifying the context the message was sent to, including the instance of the class that is to receive the message and the superclass at which to start searching for the method implementation.
op
A pointer of type SEL. Pass the selector of the method that will handle the message.

A variable argument list containing the arguments to the method.[/quote]

I have found examples using this method without additional parameters, and an ellipse is no object that could be programmed. Does this comment mean the method exists in two flavors, one without additional parameters and one with a Ptr to a memoryblock(?) that contains the values, NIL- terminated?

First you’ll need a structure:

Structure objc_super receiver As Ptr pClass As Ptr End

And some declares:

Declare Function object_getClass Lib "libobjc.A.dylib" (receiver As Ptr) As Ptr Declare Function class_getSuperclass Lib "libobjc.A.dylib" (cls As Ptr) As Ptr Declare Function sel_registerName Lib "libobjc.A.dylib" (str As CString) As Ptr

Then you will need a declare for each different parameter list. For example for this NSView method you’ll have:

// - (void)prepareForReuse Declare Sub objc_msgSendSuper Lib "libobjc.A.dylib" (sup As objc_super, op As Ptr)

For this NSView method you will need a different declare:

// - (void)beginPageInRect:(NSRect)aRect atPlacement:(NSPoint)location Declare Sub objc_msgSendSuper Lib "libobjc.A.dylib" (sup As objc_super, op As Ptr, aRect As NSRect, location As NSPoint)
… and so on.

You could try to wrap libffi, which is pre-installed on all Macs. It is a C library which allows to dynamically add arguments to a C function (line objc_msgSend). It is used by Objective C bridges like PyObjC.

If the return value is a structure you will have to look at:

objc_msgSendSuper_stret (stret = structure return)

Great, Eli, thanks a lot! I already figured out the structure and the basic call. Wouldn’t have found the selective declare by myself - excellent!

The sel_registername is only in there by accident, isn’t it?

No, you need it to get op As Ptr in the objc_msgSendSuper call.

For example:

// - (void)beginPageInRect:(NSRect)aRect atPlacement:(NSPoint)location Dim op As Ptr = sel_registername("beginPageInRect:atPlacement:")

That’s why I got console error messages with a garbled selector name! Thanks again!