Is it possible to reimplement the IControlView interface for an EditBox control
Is it possible to reimplement the IControlView interface for an EditBox control in order to achieve a custom appearance for the EditBox?
My goal is to render text in different colors within a multi-line EditBox control.
To achieve this, I defined my own EditBox control like this:
type EVEMyMultilineTextEditBoxWidget(kViewRsrcType) : EVEMultilineTextEditBoxWidget(ClassID = kMyTextEditBoxWidgetBoss) { };Class registration:
Class
{
kMyTextEditBoxWidgetBoss,
kTextEditBoxWidgetBoss,
{
IID_ICONTROLVIEW, kMyTextEditBoxViewImpl,
IID_IEVENTHANDLER, kMyTextEditBoxEHImpl,
IID_MYEDITBOXPROXYVIEW, kNudgeEditBoxViewImpl,
}
}, kNudgeEditBoxViewImpl is the default implementation of IID_ICONTROLVIEW for kTextEditBoxWidgetBoss.
Since the SDK does not expose the header files or base classes for some components,
a common workaround for reimplementing an interface without public base classes is to use delegation (or proxy),
as demonstrated in the SDK sample project PanelTreeView. For example:
class PnlTrvNodeEH : public CEventHandler
{
public:
PnlTrvNodeEH(IPMUnknown* boss);
virtual ~PnlTrvNodeEH(){}
virtual bool16 Activate(IEvent* e) {
bool16 retval;
InterfacePtr<IEventHandler> delegate(this, IID_IPNLTRVSHADOWEVENTHANDLER);
retval = delegate->Activate(e);
return retval;
}
//... all other functions follow similar pattern
};
So in my custom kMyTextEditBoxWidgetBoss, I define a custom implementation for:
IID_ICONTROLVIEW, kMyTextEditBoxViewImpl
And I also include the default base implementation as:
IID_MYEDITBOXPROXYVIEW, kNudgeEditBoxViewImplBelow is part of the implementation of kMyTextEditBoxViewImpl. This is an experimental test.
I didn’t implement my own Draw() function yet.
Instead, I reimplemented all virtual functions of IControlView in the following way:
each method simply forwards the call to the corresponding method in kNudgeEditBoxViewImpl.
class MyTextEditBoxView : public DVControlView
{
typedef DVControlView inherited;
public:
MyTextEditBoxView (IPMUnknown* boss) : inherited(boss) {}
virtual ~MyTextEditBoxView () {}
virtual void Init(const WidgetID& widgetId = kDefaultWidgetId,
const PMRect& fFrame = kZeroRect,
RsrcID rsrcID = 0)
{
InterfacePtr<IControlView> delegate(this, IID_MYEDITBOXPROXYVIEW);
delegate->Init(widgetId, fFrame, rsrcID);
}
virtual void DoPostCreate() {
InterfacePtr<IControlView> delegate(this, IID_MYEDITBOXPROXYVIEW);
delegate->DoPostCreate();
}
// ... all other functions follow similar pattern
};
CREATE_PERSIST_PMINTERFACE(MyTextEditBoxView, kMyTextEditBoxViewImpl)
However, after debugging, I noticed that none of the functions in kMyTextEditBoxViewImpl are actually being called,
except the constructor. Even Init() doesn’t seem to be invoked.
This made me wonder whether kNudgeEditBoxViewImpl actually implements IControlView or implements some other undocumented/private interface.
So I suspect that the line:
class MyTextEditBoxView : public DVControlViewmay be incorrect, or that the issue lies elsewhere.
So, here are the questions I would like to have answered:
Is it possible, using the current SDK, to reimplement the EditBox appearance drawing?
If it is possible, should class MyTextEditBoxView : public DVControlView indeed inherit from DVControlView?
Is there a better way to achieve text in multiple colors inside a multi-line EditBox?
