Thursday, April 24, 2003 2:03 AM
Shawn A. Van Ness
All quiet along the Toolbox front...
The saga continues. Soon after I reported the terrible timing-sensitive bug in the VS automation layer, I got a friendly email from someone smarter than me, and with a microsoft.com email address. That's the kind I like..!
I've forgotten how most of this COM/OLE goo works, but this kind soul reminded me that OLE message filters (ala IMessageFilter, but not the one you're thinking of!) are the key to avoiding call-rejected errors from COM plumbing.
Code follows. Caveat emptor -- but it works for me!
using System;
using System.Runtime.InteropServices;
class MessageFilter : IOleMessageFilter
{
public static void Register()
{
IOleMessageFilter newfilter = new MessageFilter();
IOleMessageFilter oldfilter = null;
CoRegisterMessageFilter(newfilter, out oldfilter);
}
public static void Revoke()
{
IOleMessageFilter oldfilter = null;
CoRegisterMessageFilter(null, out oldfilter);
}
int IOleMessageFilter.HandleInComingCall(int dwCallType, System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr lpInterfaceInfo)
{
System.Diagnostics.Debug.WriteLine("IOleMessageFilter::HandleInComingCall");
return 0; }
int IOleMessageFilter.RetryRejectedCall(System.IntPtr hTaskCallee, int dwTickCount, int dwRejectType)
{
System.Diagnostics.Debug.WriteLine("IOleMessageFilter::RetryRejectedCall");
if (dwRejectType == 2 ) {
System.Diagnostics.Debug.WriteLine("Retry call later");
return 99; }
return -1; }
int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, int dwTickCount, int dwPendingType)
{
System.Diagnostics.Debug.WriteLine("IOleMessageFilter::MessagePending");
return 2; }
[DllImport("Ole32.dll")]
private static extern int CoRegisterMessageFilter(IOleMessageFilter newfilter, out IOleMessageFilter oldfilter);
}
[ComImport(), Guid("00000016-0000-0000-C000-000000000046"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
interface IOleMessageFilter {
[PreserveSig]
int HandleInComingCall(
int dwCallType,
IntPtr hTaskCaller,
int dwTickCount,
IntPtr lpInterfaceInfo);
[PreserveSig]
int RetryRejectedCall(
IntPtr hTaskCallee,
int dwTickCount,
int dwRejectType);
[PreserveSig]
int MessagePending(
IntPtr hTaskCallee,
int dwTickCount,
int dwPendingType);
}