提交 5cc8349a 编写于 作者: S Sam Harwell

Extract MessageFilter to a top level test utility class

上级 3146b8b4
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.IntegrationTest.Utilities;
using Microsoft.VisualStudio.IntegrationTest.Utilities.Harness;
using Microsoft.VisualStudio.IntegrationTest.Utilities.Input;
using Microsoft.Win32.SafeHandles;
using Xunit;
using IMessageFilter = Microsoft.VisualStudio.OLE.Interop.IMessageFilter;
using INTERFACEINFO = Microsoft.VisualStudio.OLE.Interop.INTERFACEINFO;
using PENDINGMSG = Microsoft.VisualStudio.OLE.Interop.PENDINGMSG;
using SERVERCALL = Microsoft.VisualStudio.OLE.Interop.SERVERCALL;
namespace Roslyn.VisualStudio.IntegrationTests
{
......@@ -109,110 +103,5 @@ protected KeyPress Shift(VirtualKey virtualKey)
protected KeyPress Alt(VirtualKey virtualKey)
=> new KeyPress(virtualKey, ShiftState.Alt);
protected class MessageFilter : IMessageFilter, IDisposable
{
protected const uint CancelCall = ~0U;
private readonly MessageFilterSafeHandle _messageFilterRegistration;
private readonly TimeSpan _timeout;
private readonly TimeSpan _retryDelay;
public MessageFilter()
: this(timeout: TimeSpan.FromSeconds(60), retryDelay: TimeSpan.FromMilliseconds(150))
{
}
public MessageFilter(TimeSpan timeout, TimeSpan retryDelay)
{
_timeout = timeout;
_retryDelay = retryDelay;
_messageFilterRegistration = MessageFilterSafeHandle.Register(this);
}
public virtual uint HandleInComingCall(uint dwCallType, IntPtr htaskCaller, uint dwTickCount, INTERFACEINFO[] lpInterfaceInfo)
{
return (uint)SERVERCALL.SERVERCALL_ISHANDLED;
}
public virtual uint RetryRejectedCall(IntPtr htaskCallee, uint dwTickCount, uint dwRejectType)
{
if ((SERVERCALL)dwRejectType != SERVERCALL.SERVERCALL_RETRYLATER
&& (SERVERCALL)dwRejectType != SERVERCALL.SERVERCALL_REJECTED)
{
return CancelCall;
}
if (dwTickCount >= _timeout.TotalMilliseconds)
{
return CancelCall;
}
return (uint)_retryDelay.TotalMilliseconds;
}
public virtual uint MessagePending(IntPtr htaskCallee, uint dwTickCount, uint dwPendingType)
{
return (uint)PENDINGMSG.PENDINGMSG_WAITDEFPROCESS;
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_messageFilterRegistration.Dispose();
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
private sealed class MessageFilterSafeHandle : SafeHandleMinusOneIsInvalid
{
private readonly IntPtr _oldFilter;
private MessageFilterSafeHandle(IntPtr handle)
: base(true)
{
SetHandle(handle);
try
{
if (CoRegisterMessageFilter(handle, out _oldFilter) != VSConstants.S_OK)
{
throw new InvalidOperationException("Failed to register a new message filter");
}
}
catch
{
SetHandleAsInvalid();
throw;
}
}
[DllImport("ole32", SetLastError = true)]
private static extern int CoRegisterMessageFilter(IntPtr messageFilter, out IntPtr oldMessageFilter);
public static MessageFilterSafeHandle Register<T>(T messageFilter)
where T : IMessageFilter
{
var handle = Marshal.GetComInterfaceForObject<T, IMessageFilter>(messageFilter);
return new MessageFilterSafeHandle(handle);
}
protected override bool ReleaseHandle()
{
if (CoRegisterMessageFilter(_oldFilter, out _) == VSConstants.S_OK)
{
Marshal.Release(handle);
}
return true;
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using IMessageFilter = Microsoft.VisualStudio.OLE.Interop.IMessageFilter;
using INTERFACEINFO = Microsoft.VisualStudio.OLE.Interop.INTERFACEINFO;
using PENDINGMSG = Microsoft.VisualStudio.OLE.Interop.PENDINGMSG;
using SERVERCALL = Microsoft.VisualStudio.OLE.Interop.SERVERCALL;
namespace Microsoft.VisualStudio.IntegrationTest.Utilities.Harness
{
public class MessageFilter : IMessageFilter, IDisposable
{
protected const uint CancelCall = ~0U;
private readonly MessageFilterSafeHandle _messageFilterRegistration;
private readonly TimeSpan _timeout;
private readonly TimeSpan _retryDelay;
public MessageFilter()
: this(timeout: TimeSpan.FromSeconds(60), retryDelay: TimeSpan.FromMilliseconds(150))
{
}
public MessageFilter(TimeSpan timeout, TimeSpan retryDelay)
{
_timeout = timeout;
_retryDelay = retryDelay;
_messageFilterRegistration = MessageFilterSafeHandle.Register(this);
}
public virtual uint HandleInComingCall(uint dwCallType, IntPtr htaskCaller, uint dwTickCount, INTERFACEINFO[] lpInterfaceInfo)
{
return (uint)SERVERCALL.SERVERCALL_ISHANDLED;
}
public virtual uint RetryRejectedCall(IntPtr htaskCallee, uint dwTickCount, uint dwRejectType)
{
if ((SERVERCALL)dwRejectType != SERVERCALL.SERVERCALL_RETRYLATER
&& (SERVERCALL)dwRejectType != SERVERCALL.SERVERCALL_REJECTED)
{
return CancelCall;
}
if (dwTickCount >= _timeout.TotalMilliseconds)
{
return CancelCall;
}
return (uint)_retryDelay.TotalMilliseconds;
}
public virtual uint MessagePending(IntPtr htaskCallee, uint dwTickCount, uint dwPendingType)
{
return (uint)PENDINGMSG.PENDINGMSG_WAITDEFPROCESS;
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_messageFilterRegistration.Dispose();
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using IMessageFilter = Microsoft.VisualStudio.OLE.Interop.IMessageFilter;
namespace Microsoft.VisualStudio.IntegrationTest.Utilities.Harness
{
internal sealed class MessageFilterSafeHandle : SafeHandleMinusOneIsInvalid
{
private readonly IntPtr _oldFilter;
private MessageFilterSafeHandle(IntPtr handle)
: base(true)
{
SetHandle(handle);
try
{
if (CoRegisterMessageFilter(handle, out _oldFilter) != VSConstants.S_OK)
{
throw new InvalidOperationException("Failed to register a new message filter");
}
}
catch
{
SetHandleAsInvalid();
throw;
}
}
[DllImport("ole32", SetLastError = true)]
private static extern int CoRegisterMessageFilter(IntPtr messageFilter, out IntPtr oldMessageFilter);
public static MessageFilterSafeHandle Register<T>(T messageFilter)
where T : IMessageFilter
{
var handle = Marshal.GetComInterfaceForObject<T, IMessageFilter>(messageFilter);
return new MessageFilterSafeHandle(handle);
}
protected override bool ReleaseHandle()
{
if (CoRegisterMessageFilter(_oldFilter, out _) == VSConstants.S_OK)
{
Marshal.Release(handle);
}
return true;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册