| Index: visual_studio/NativeClientVSAddIn/UnitTests/ComMessageFilter.cs
|
| diff --git a/visual_studio/NativeClientVSAddIn/UnitTests/ComMessageFilter.cs b/visual_studio/NativeClientVSAddIn/UnitTests/ComMessageFilter.cs
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8614336516a5a4d460ddc15c30f1ed67b2bba8d9
|
| --- /dev/null
|
| +++ b/visual_studio/NativeClientVSAddIn/UnitTests/ComMessageFilter.cs
|
| @@ -0,0 +1,95 @@
|
| +using System;
|
| +using System.Collections.Generic;
|
| +using System.Linq;
|
| +using System.Text;
|
| +using EnvDTE;
|
| +using EnvDTE80;
|
| +using System.Runtime.InteropServices;
|
| +
|
| +namespace UnitTests
|
| +{
|
| + /// <summary>
|
| + /// This class receives messages from the COM calls to Visual Studio
|
| + /// and auto-retries them if they fail because VS is busy
|
| + /// </summary>
|
| + public class ComMessageFilter : IOleMessageFilter
|
| + {
|
| + // Start the filter.
|
| + // Note that this registers the filter only for the current thread
|
| + public static void Register()
|
| + {
|
| + IOleMessageFilter newFilter = new ComMessageFilter();
|
| + IOleMessageFilter oldFilter = null;
|
| + CoRegisterMessageFilter(newFilter, out oldFilter);
|
| + }
|
| +
|
| + // Done with the filter, close it.
|
| + // Note that this revokes the filter only for the current thread
|
| + public static void Revoke()
|
| + {
|
| + IOleMessageFilter oldFilter = null;
|
| + CoRegisterMessageFilter(null, out oldFilter);
|
| + }
|
| +
|
| + // Handle incoming thread requests.
|
| + int IOleMessageFilter.HandleInComingCall(int dwCallType,
|
| + System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr
|
| + lpInterfaceInfo)
|
| + {
|
| + //Return the flag SERVERCALL_ISHANDLED.
|
| + return 0;
|
| + }
|
| +
|
| + // Thread call was rejected, so try again.
|
| + int IOleMessageFilter.RetryRejectedCall(System.IntPtr
|
| + hTaskCallee, int dwTickCount, int dwRejectType)
|
| + {
|
| + if (dwRejectType == 2)
|
| + // flag = SERVERCALL_RETRYLATER.
|
| + {
|
| + // Retry the thread call immediately if return >=0 &
|
| + // <100.
|
| + return 99;
|
| + }
|
| + // Too busy; cancel call.
|
| + return -1;
|
| + }
|
| +
|
| + int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee,
|
| + int dwTickCount, int dwPendingType)
|
| + {
|
| + //Return the flag PENDINGMSG_WAITDEFPROCESS.
|
| + return 2;
|
| + }
|
| +
|
| + // Implement the IOleMessageFilter interface.
|
| + [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);
|
| + }
|
| +}
|
|
|