CustomControl WithEvents?

riktek

Member
Local time
Today, 15:16
Joined
Dec 15, 2023
Messages
174
Can a CustomControl be assigned to a CustomControl variable declared WithEvents?

I have an ActiveX control wrapper that successfully binds the ActiveX control and the form to suitably typed variables declared WithEvents.

The CustomControl class exposes a distinct set of events, however, so I was hoping to also sink those in the class, but no go. I get error 459, Object or class does not support the set of events. This seems quite odd because the class quite clearly is an event source, not to mention being a member of the Access library.

Is there a solution, or did someone forget to define a COM events interface for this control?

I'm also curious whether and how the CreateControl method might be exploited to add a COM-callable control not in the Access library to a form without use of the CustomControl class. Especially if the control is an event source that provides a COM events interface.

I'm developing in A2007 for the moment, if that matters.
 
I asked CoPilot:
Forum question: Can an Access ActiveX CustomControl be assigned to a CustomControl variable declared WithEvents?

First the slightly worrying thing: As I have this thread open, CoPilot can reference it!

Here’s the architectural truth of it, Colin — and it lines up exactly with what you’re seeing in that forum thread:

Short answer: No.
An Access CustomControl cannot be assigned to a WithEvents variable, even though the underlying ActiveX control does expose events.
Access simply never implemented a COM events interface for the CustomControl wrapper class.

This is not a bug in your code — it’s a limitation of Access’s internal COM plumbing.

NOTE: I haven't checked all the details in its longer answer below, It could well be full of errors!

Longer Answer:
Why it fails (the real reason behind error 459)

For Access’s built‑in CustomControl class, the answer is no. The class is a thin wrapper around an ActiveX control instance, but Access never defined or published an events interface for the wrapper itself.

So VBA throws:
459 – Object or class does not support the set of events
because it literally cannot find an IDispatch-based event interface to hook.

This is why:
  • You can sink events from the underlying ActiveX control (because that COM class exposes events).
  • You cannot sink events from the Access CustomControl wrapper (because Access never exposed its own event interface).
This is consistent across Access versions, including 2007.

Why Access behaves this way
Access’s form engine treats ActiveX controls as “black boxes”:
  • It instantiates the COM control.
  • It exposes the control’s properties/methods through CustomControl.
  • It forwards events only to the form module, not to external class modules.
The form module is the only place Access wires up ActiveX events automatically.Class modules are not part of that pipeline.

Can CreateControl help?
Unfortunately, no.

CreateControl can instantiate:
  • Access-native controls
  • ActiveX controls registered on the system
…but it does not expose any additional COM event interfaces beyond what Access already supports. It still wraps the control in the same CustomControl class, with the same missing events interface.

So even if you dynamically add an ActiveX control, you still cannot sink its events through a WithEvents variable.

Is there any workaround?
There are only two viable patterns:
1. Sink events directly from the ActiveX control instance (if you can get it)
But Access usually hides the underlying COM object behind the Object property, and that property is not a WithEvents‑bindable reference.

2. Use the form module as the event sink and forward events
This is the only universally reliable pattern:
It’s not elegant, but it’s the only architecture Access actually supports.
 
Last edited:
I asked CoPilot:
Forum question: Can an Access ActiveX CustomControl be assigned to a CustomControl variable declared WithEvents?

First the slightly worrying thing: As I have this thread open, CoPilot can reference it!
Here’s the architectural truth of it, Colin — and it lines up exactly with what you’re seeing in that forum thread:

Short answer: No.
An Access CustomControl cannot be assigned to a WithEvents variable, even though the underlying ActiveX control does expose events.
Access simply never implemented a COM events interface for the CustomControl wrapper class.

This is not a bug in your code — it’s a limitation of Access’s internal COM plumbing.

NOTE: I haven't checked all the details in its longer answer below, It could well be full of errors!

Longer Answer:
Why it fails (the real reason behind error 459)

For Access’s built‑in CustomControl class, the answer is no. The class is a thin wrapper around an ActiveX control instance, but Access never defined or published an events interface for the wrapper itself.

So VBA throws:
459 – Object or class does not support the set of events
because it literally cannot find an IDispatch-based event interface to hook.

This is why:
  • You can sink events from the underlying ActiveX control (because that COM class exposes events).
  • You cannot sink events from the Access CustomControl wrapper (because Access never exposed its own event interface).
This is consistent across Access versions, including 2007.

Why Access behaves this way
Access’s form engine treats ActiveX controls as “black boxes”:
  • It instantiates the COM control.
  • It exposes the control’s properties/methods through CustomControl.
  • It forwards events only to the form module, not to external class modules.
The form module is the only place Access wires up ActiveX events automatically.Class modules are not part of that pipeline.

Can CreateControl help?
Unfortunately, no.

CreateControl can instantiate:
  • Access-native controls
  • ActiveX controls registered on the system
…but it does not expose any additional COM event interfaces beyond what Access already supports. It still wraps the control in the same CustomControl class, with the same missing events interface.

So even if you dynamically add an ActiveX control, you still cannot sink its events through a WithEvents variable.

Is there any workaround?
There are only two viable patterns:
1. Sink events directly from the ActiveX control instance (if you can get it)
But Access usually hides the underlying COM object behind the Object property, and that property is not a WithEvents‑bindable reference.

2. Use the form module as the event sink and forward events
This is the only universally reliable pattern:
It’s not elegant, but it’s the only architecture Access actually supports.
Colin:

Thanks. I had suspected something missing in the COM programming underlying the Access.CustomControl class, specifically the absence of an IDispatch events interface in that class.

Copilot's longer answer goes off the rails when it says it forwards ActiveX events only to the form module, and when it says that a class can't sink an ActiveX control's events via a WithEvents variable. I'm currently sinking ActiveX control events in my wrapper class in precisely that way. So, the Object property actually is in fact a WithEvents-bindable reference. It's just a pointer, after all. What matters insofar as WithEvents is concerned, seems to be whether the object it references provides an IDispatch events interface.

This said, I can sink the CustomControl's events in the form's module even if I can't in my wrapper class, so that much of the Copilot response is correct. It turns out, however, that it is the CustomControl itself that is not a WithEvents-bindable reference, not its Object property, probably by reason of the absence of an IDispatch events interface.

A better explanation might be that WithEvents works just fine if the object assigned to it is an instance of a class that provides an IDispatch events interface. ActiveX controls providing such an interface can have their events sunk via a WithEvents variable anywhere without difficulty, as my wrapper class does. WithEvents fails when such an events interface is not present, even if the class is otherwise an event source.

So, whether by oversight or deliberate choice, Access.CustomControl apparently lacks an IDispatch events interface, and is is incomplete and handicapped as a consequence.

Otherwise, the operation of the CreateControl method remains murky. I'll have to tinker with that otherwise.
 
Last edited:

Users who are viewing this thread

Back
Top Bottom