Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

It is illegal to call out while inside message filter.

3,015 views
Skip to first unread message

JimMcGowanInlet

unread,
Feb 13, 2008, 10:47:04 AM2/13/08
to
I'm getting the following error in my application.

ERROR: ModuleName, -2147418107, Automation error
It is illegal to call out while inside message filter.

I've read the Microsoft articles on how to prevent reentrancy into a call
while waiting for a COM control. I used the method of setting a flag to
prevent re-entry but the error continues to occure. The Technotes I've
located are VERY basic and I wonder if I'm mis-interpreting them. The
examples all show one Timer but I have many Timers in my app. I've created a
unique Flag for each timer in my code as in the example.

Code:
Private Sub Timer1_Timer()
Static flagA as Boolean
If Not flagA Then
flagA = True
Do Stuff Here
flagA = False
End If
End Sub


Private Sub Timer2_Timer()
Static flagB as Boolean
If Not flagB Then
flagB = True
Do Stuff Here
flagB = False
End If
End Sub

But the error still continues to occure I'm starting to think I need a
single global flag to prevent re-entry into ANY Timer. Not just re-entry
into the same Timer. For example

Code:

Public flag as Boolean

Private Sub Timer1_Timer()
If Not flag Then
flag = True
Do Stuff Here
flag = False
End If
End Sub


Private Sub Timer2_Timer()
Static flag as Boolean
If Not flag Then
flag = True
Do Stuff Here
flag = False
End If
End Sub

But the articles are not clear on exactly what needs to be prevented. Can
anyone familure with this please expand on the problem and its solution.

Thanks
Jim

Ken Halter

unread,
Feb 13, 2008, 10:58:08 AM2/13/08
to
"JimMcGowanInlet" <JimMcGo...@discussions.microsoft.com> wrote in
message news:246D595D-B3B1-4A98...@microsoft.com...

> I'm getting the following error in my application.
>
> ERROR: ModuleName, -2147418107, Automation error
> It is illegal to call out while inside message filter.

...assuming the article you read was...

PRB: VB5.0 OLE Automation Error -2147418107 (80010005)
http://support.microsoft.com/kb/176399


...personally, I've never seen that problem. "Call Out" to what? An ActiveX
EXE (running in another process).

This isn't VBA, right?

How many timers? You can share timers by using State flags, etc.... believe
me... VB3/NT3 had specific limitations on the number of timers allowed (16?)
so sharing them became fairly common.

Hopefully you're not relying on the accuracy of a timer event for anything
critical. They're simply not accurate and weren't designed to be.

--
Ken Halter - MS-MVP-VB - Please keep all discussions in the groups..
In Loving Memory - http://www.vbsight.com/Remembrance.htm


Jeff Johnson

unread,
Feb 13, 2008, 11:13:22 AM2/13/08
to
"Ken Halter" <Ken_Halter@Use_Sparingly_Hotmail.com> wrote in message
news:ukTmColb...@TK2MSFTNGP06.phx.gbl...

>> I'm getting the following error in my application.
>>
>> ERROR: ModuleName, -2147418107, Automation error
>> It is illegal to call out while inside message filter.
>
> ...assuming the article you read was...
>
> PRB: VB5.0 OLE Automation Error -2147418107 (80010005)
> http://support.microsoft.com/kb/176399
>
>
> ...personally, I've never seen that problem. "Call Out" to what?

"In COM, no one can hear you scream."


JimMcGowanInlet

unread,
Feb 13, 2008, 11:27:01 AM2/13/08
to
I have roughly 20 Timers across various forms. They are just to trip things I
want checked or updated at certain intervals. Accuracy is not critical. I
am making calls to various controls both ocx and exe. I'm using VB6 - SP6
Enterprise. (I hope this is the correct forum.)

The key question is, when in a Timer calling a control, do I prevent
re-entry into just that timer or do I need to prevent it from entering any
other timer? The article isn't clear to me.

Thanks
Jim

"Ken Halter" wrote:

> "JimMcGowanInlet" <JimMcGo...@discussions.microsoft.com> wrote in
> message news:246D595D-B3B1-4A98...@microsoft.com...
> > I'm getting the following error in my application.
> >
> > ERROR: ModuleName, -2147418107, Automation error
> > It is illegal to call out while inside message filter.
>

> ....assuming the article you read was...


>
> PRB: VB5.0 OLE Automation Error -2147418107 (80010005)
> http://support.microsoft.com/kb/176399
>
>

> ....personally, I've never seen that problem. "Call Out" to what? An ActiveX

Ken Halter

unread,
Feb 13, 2008, 12:27:04 PM2/13/08
to
"JimMcGowanInlet" <JimMcGo...@discussions.microsoft.com> wrote in
message news:3D3ECCCA-B9EC-450E...@microsoft.com...

>I have roughly 20 Timers across various forms. They are just to trip things
>I
> want checked or updated at certain intervals. Accuracy is not critical.
> I
> am making calls to various controls both ocx and exe. I'm using VB6 -
> SP6
> Enterprise. (I hope this is the correct forum.)
>
> The key question is, when in a Timer calling a control, do I prevent
> re-entry into just that timer or do I need to prevent it from entering any
> other timer? The article isn't clear to me.
>
> Thanks
> Jim

"making calls to various controls both ocx and exe"

So, these are out of process exe's that return before the operation is
complete? (Async behavior)

This is a bit confusing because, by design, a timer shouldn't have the
ability to fire again before reaching its "End Sub" in its timer event
handler... which means there should be no need to protect against
reentrancy.

If you start a new project, drop a command button and a timer on the form
and run this code, you'll see that, even though the timer interval's set to
fire 100 times per second, it won't because it's waiting for the 'Pause' sub
to return.
'=================
Option Explicit

Private Sub Command1_Click()
Static bEnabled As Boolean
bEnabled = Not bEnabled
Timer1.Enabled = bEnabled
End Sub

Private Sub Form_Load()
Timer1.Enabled = False
Timer1.Interval = 10
End Sub

Private Sub Form_Unload(Cancel As Integer)
Timer1.Enabled = False
End Sub

Private Sub Timer1_Timer()
Debug.Print "Timer Fired", Timer
Call Pause(1)
End Sub

Private Sub Pause(Seconds As Single)
Dim f As Single
Dim l As Long

Debug.Print "PAUSE", Timer

f = Timer + Seconds 'fails if overlapping midnight

Do While Timer < f
l = l - 1
If l < 0 Then
l = 2500
DoEvents
End If
Loop

End Sub
'=================

But... if the flags seem to help, I'd set a "global" that prevented any
timers (no matter where they are) from doing their work, until I found out
what the real issue is.

Another option would be to dump the VB timer all together and use this
component....

TimerObj
Code-based timer object for use in non-windowed (or VBA) situations. OCX
included.

While you're there, this may be worth a peek

SyncEvts
Several ways to share events (timers, in this demo) amongst multiple
objects.

http://vb.mvps.org/samples/

Ken Halter

unread,
Feb 13, 2008, 1:27:05 PM2/13/08
to
"JimMcGowanInlet" <JimMcGo...@discussions.microsoft.com> wrote in
message news:58301B37-C07F-4184...@microsoft.com...
> The article http://support.microsoft.com/kb/176399 shows how to reproduce
> the
> error and does its best to explain the problem in the "More Information"
> section. I'm just not advanced enough to understand what they are saying.
> The core issue doesn't seem to be Timers. Its RPC calls. But the timers
> initiate the problem so I fear swithing to a TimerObj would have the same
> effect.

Ok... this is confusing <g> Their "Steps to Reproduce Behavior" don't
"Reproduce Behavior" here <g> It just works. (VB6/SP5)

The *only* difference in my test project(s) and theirs is.... I set up
Binary Compatibility... I have to... it's hard-wired into my brain... in
fact, my add-in does it for me every time I create a new component.

Other than that, I followed their steps to the letter.

If it *did* raise the error, the first thing I was going to try was:
'===============
Private Sub Timer1_Timer()
Timer1.Enabled = False '<--new
RetStr = t.Test(100000)
Text1.Text = RetStr
Timer1.Enabled = True '<--new
End Sub
'===============

Second thing I'd have tried was... placing a static flag in the external
procedure, instead of the timer event... but that's only possible if you're
in charge of everything (exe, ax-exe, etc) If these are 3rd party
components, your options are cut in half, right off the bat.

Another option (if you have source for everything) would be....

'===============
Private Sub Timer1_Timer()
Timer1.Enabled = False '<--disable the timer.... Period
RetStr = t.Test(100000)
Text1.Text = RetStr
End Sub
'===============

That disables the timer all together. You can add an event to the ActiveX
exe that fires when some operation is complete.... when that event fires,
you can re-enable the timer in the "operation_is_complete" event handler.

JimMcGowanInlet

unread,
Feb 14, 2008, 11:25:00 PM2/14/08
to
Ok I think I've worked it out, and it is I need a global flag to prevent
re-entry into any timer while called out to an external ActiveX control.

Thanks
Jim

Bob Butler

unread,
Feb 15, 2008, 8:47:52 AM2/15/08
to
"JimMcGowanInlet" <JimMcGo...@discussions.microsoft.com> wrote in
message news:C0DE61D7-2A61-49FF...@microsoft.com...

> Ok I think I've worked it out, and it is I need a global flag to prevent
> re-entry into any timer while called out to an external ActiveX control.

You may want to consider dropping all but a single timer and maintaing a
queue of events and when they should run next. When the timer fires you
scan the queue, run any that are due and advance each run time to the next
interval. It's a little more work up front but is simpler and easier to
maintain and extend.

0 new messages