| 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..e5ccb7fb6e9caacbb8435b75afbbc2659b3e6df4
|
| --- /dev/null
|
| +++ b/visual_studio/NativeClientVSAddIn/UnitTests/ComMessageFilter.cs
|
| @@ -0,0 +1,108 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +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
|
| + {
|
| + /// <summary>
|
| + /// Note this registers the filter only for the current thread.
|
| + /// </summary>
|
| + public static void Register()
|
| + {
|
| + IOleMessageFilter oldFilter = null;
|
| + CoRegisterMessageFilter(new ComMessageFilter(), out oldFilter);
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Note this only closes the filter for the current thread.
|
| + /// </summary>
|
| + public static void Revoke()
|
| + {
|
| + IOleMessageFilter oldFilter = null;
|
| + CoRegisterMessageFilter(null, out oldFilter);
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Handles calls for the thread
|
| + /// </summary>
|
| + /// <param name="dwCallType">Unused</param>
|
| + /// <param name="hTaskCaller">Unused</param>
|
| + /// <param name="dwTickCount">Unused</param>
|
| + /// <param name="lpInterfaceInfo">Unused</param>
|
| + /// <returns>Code indicating message was handled</returns>
|
| + int IOleMessageFilter.HandleInComingCall(int dwCallType, System.IntPtr hTaskCaller,
|
| + int dwTickCount, System.IntPtr lpInterfaceInfo)
|
| + {
|
| + return 0; // SERVERCALL_ISHANDLED.
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Automatically retries the failed call
|
| + /// </summary>
|
| + /// <param name="hTaskCallee">Unused</param>
|
| + /// <param name="dwTickCount">Unused</param>
|
| + /// <param name="dwRejectType">Unused</param>
|
| + /// <returns>Code indicating call should be retried</returns>
|
| + int IOleMessageFilter.RetryRejectedCall(System.IntPtr hTaskCallee,
|
| + int dwTickCount, int dwRejectType)
|
| + {
|
| + if (dwRejectType == 2) // SERVERCALL_RETRYLATER
|
| + {
|
| + // Immediate retry
|
| + return 99;
|
| + }
|
| + // Cancel call
|
| + return -1;
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Handles an incoming message by indicating it should be dispatched always
|
| + /// </summary>
|
| + /// <param name="hTaskCallee">Unused</param>
|
| + /// <param name="dwTickCount">Unused</param>
|
| + /// <param name="dwPendingType"><Unused/param>
|
| + /// <returns>Code indicating message should be dispatched</returns>
|
| + int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee,
|
| + int dwTickCount, int dwPendingType)
|
| + {
|
| + return 2; // PENDINGMSG_WAITDEFPROCESS
|
| + }
|
| +
|
| + // Implement the IOleMessageFilter interface.
|
| + [DllImport("Ole32.dll")]
|
| + private static extern int CoRegisterMessageFilter(
|
| + IOleMessageFilter newFilter, out IOleMessageFilter oldFilter);
|
| + }
|
| +
|
| + /// <summary>
|
| + /// Interface for IOleMessageFilter
|
| + /// </summary>
|
| + [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);
|
| + }
|
| +}
|
|
|