Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / UIAutomation / Win32Providers / MS / Internal / AutomationProxies / MSAAWinEventWrap.cs / 1 / MSAAWinEventWrap.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
//
// Description: Lightweight class to wrap Win32 WinEvents.
//
// THIS IS VIRTUALLY AN IDENTICAL COPY TO A FILE OF THE SAME NAME IN UIAUTOMATION!
// IF YOU FIX A
using System;
using System.Collections;
using System.Runtime.InteropServices;
using MS.Win32;
namespace MS.Internal.AutomationProxies
{
// Lightweight class to wrap Win32 WinEvents. Users of this class would
// inherit from MSAAWinEventWrap do the following:
// 1. Call the base constructor with a params array of event identifiers
// 2. Override WinEventProc to provide an implementation.
internal class MSAAWinEventWrap
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
// ctor that takes a range of events
internal MSAAWinEventWrap(int eventMin, int eventMax)
{
_eventMin = eventMin;
_eventMax = eventMax;
_hHooks = new IntPtr[1];
Init();
}
~MSAAWinEventWrap()
{
Clear();
}
#endregion Constructors
//------------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
#region Internal Methods
internal virtual void WinEventProc(int eventId, IntPtr hwnd, int idObject, int idChild)
{
// override this to provide an implementation
}
internal void Clear()
{
StopListening();
lock(this)
{
_clientCallbacks.Clear ();
}
if (_gchThis.IsAllocated)
{
_gchThis.Free();
}
}
internal void StartListening()
{
_fBusy = true;
{
// in a single hook, listen for a range of WinEvent types
_hHooks[0] = Misc.SetWinEventHook(_eventMin, _eventMax, IntPtr.Zero, _winEventProc, 0, 0, _fFlags);
if (_hHooks[0] == IntPtr.Zero)
{
StopListening();
}
}
_fBusy = false;
}
internal void StopListening()
{
// ASSUMPTION: Before StopListening is called, all callback delegates have been removed
// so that any events received while hooks are being removed become noops (since there's
// no handlers for them to call).
_fBusy = true;
for (int i=0;i<_hHooks.Length;i++)
{
if (_hHooks[i] != IntPtr.Zero)
{
Misc.UnhookWinEvent(_hHooks[i]);
_hHooks[i] = IntPtr.Zero;
}
}
if (_qEvents != null)
{
_qEvents.Clear();
}
_fBusy = false;
}
#endregion Internal Methods
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
// queue winevents so that the get processed in the order we receive them. If we just
// dispatch them as we get them, we'll end up getting some _while_ we are processing others,
// and end up completing those events out of order, making the event order appear backwards.
// This code checks whether we are currently processing an event, and if so, queues it so that
// we process it when we're done with the current event.
private void WinEventReentrancyFilter(int winEventHook, int eventId, IntPtr hwnd, int idObject, int idChild, int eventThread, uint eventTime)
{
if (_fBusy)
{
_qEvents.Enqueue(new WinEvent(eventId, hwnd, idObject, idChild));
}
else
{
_fBusy = true;
try
{
WinEventProc( eventId, hwnd, idObject, idChild ); // deliver this event
}
catch (Exception e)
{
if (Misc.IsCriticalException(e))
{
throw;
}
// ignore exceptions for now since we've no way to let clients add exception handlers
}
while (_qEvents.Count > 0)
{
WinEvent winEvent = (WinEvent)_qEvents.Dequeue(); // process queued events
try
{
WinEventProc(winEvent._eventId, winEvent._hwnd, winEvent._idObject, winEvent._idChild);
}
catch (Exception e)
{
if (Misc.IsCriticalException(e))
{
throw;
}
// ignore exceptions for now since we've no way to let clients add exception handlers
}
}
_fBusy = false;
}
}
private void Init()
{
// Keep the garbage collector from moving things around
_winEventProc = new NativeMethods.WinEventProcDef(WinEventReentrancyFilter);
_gchThis = GCHandle.Alloc(_winEventProc);
_clientCallbacks = new ArrayList(2);
_qEvents = new Queue(16, (float)2.0); // (initial cap, growth factor)
_fFlags = NativeMethods.WINEVENT_OUTOFCONTEXT;
}
#endregion Private Methods
#region Internal Types
// -----------------------------------------------------
//
// Internal Types Declaration
//
// ------------------------------------------------------
// Function call to either the Start or Stop Listener
internal delegate void StartStopDelegate();
#endregion Internal Types
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Fields
private class WinEvent
{
internal WinEvent(int eventId, IntPtr hwnd, int idObject, int idChild)
{
_eventId = eventId;
_hwnd = hwnd;
_idObject = idObject;
_idChild = idChild;
}
public int _eventId;
public IntPtr _hwnd;
public int _idObject;
public int _idChild;
}
private Queue _qEvents; // Queue of events waiting to be processed
private int _eventMin; // minimum WinEvent type in range
private int _eventMax; // maximium WinEventType in range
private IntPtr [] _hHooks; // the returned handles(s) from SetWinEventHook
private bool _fBusy; // Flag indicating if we're busy processing
private int _fFlags; // SetWinEventHook flags
private GCHandle _gchThis; // GCHandle to keep GCs from moving this callback
private NativeMethods.WinEventProcDef _winEventProc; // the callback handed to USER for WinEvents
protected ArrayList _clientCallbacks; // the client callback interface objects
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
//
// Description: Lightweight class to wrap Win32 WinEvents.
//
// THIS IS VIRTUALLY AN IDENTICAL COPY TO A FILE OF THE SAME NAME IN UIAUTOMATION!
// IF YOU FIX A
using System;
using System.Collections;
using System.Runtime.InteropServices;
using MS.Win32;
namespace MS.Internal.AutomationProxies
{
// Lightweight class to wrap Win32 WinEvents. Users of this class would
// inherit from MSAAWinEventWrap do the following:
// 1. Call the base constructor with a params array of event identifiers
// 2. Override WinEventProc to provide an implementation.
internal class MSAAWinEventWrap
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
// ctor that takes a range of events
internal MSAAWinEventWrap(int eventMin, int eventMax)
{
_eventMin = eventMin;
_eventMax = eventMax;
_hHooks = new IntPtr[1];
Init();
}
~MSAAWinEventWrap()
{
Clear();
}
#endregion Constructors
//------------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
#region Internal Methods
internal virtual void WinEventProc(int eventId, IntPtr hwnd, int idObject, int idChild)
{
// override this to provide an implementation
}
internal void Clear()
{
StopListening();
lock(this)
{
_clientCallbacks.Clear ();
}
if (_gchThis.IsAllocated)
{
_gchThis.Free();
}
}
internal void StartListening()
{
_fBusy = true;
{
// in a single hook, listen for a range of WinEvent types
_hHooks[0] = Misc.SetWinEventHook(_eventMin, _eventMax, IntPtr.Zero, _winEventProc, 0, 0, _fFlags);
if (_hHooks[0] == IntPtr.Zero)
{
StopListening();
}
}
_fBusy = false;
}
internal void StopListening()
{
// ASSUMPTION: Before StopListening is called, all callback delegates have been removed
// so that any events received while hooks are being removed become noops (since there's
// no handlers for them to call).
_fBusy = true;
for (int i=0;i<_hHooks.Length;i++)
{
if (_hHooks[i] != IntPtr.Zero)
{
Misc.UnhookWinEvent(_hHooks[i]);
_hHooks[i] = IntPtr.Zero;
}
}
if (_qEvents != null)
{
_qEvents.Clear();
}
_fBusy = false;
}
#endregion Internal Methods
//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
#region Private Methods
// queue winevents so that the get processed in the order we receive them. If we just
// dispatch them as we get them, we'll end up getting some _while_ we are processing others,
// and end up completing those events out of order, making the event order appear backwards.
// This code checks whether we are currently processing an event, and if so, queues it so that
// we process it when we're done with the current event.
private void WinEventReentrancyFilter(int winEventHook, int eventId, IntPtr hwnd, int idObject, int idChild, int eventThread, uint eventTime)
{
if (_fBusy)
{
_qEvents.Enqueue(new WinEvent(eventId, hwnd, idObject, idChild));
}
else
{
_fBusy = true;
try
{
WinEventProc( eventId, hwnd, idObject, idChild ); // deliver this event
}
catch (Exception e)
{
if (Misc.IsCriticalException(e))
{
throw;
}
// ignore exceptions for now since we've no way to let clients add exception handlers
}
while (_qEvents.Count > 0)
{
WinEvent winEvent = (WinEvent)_qEvents.Dequeue(); // process queued events
try
{
WinEventProc(winEvent._eventId, winEvent._hwnd, winEvent._idObject, winEvent._idChild);
}
catch (Exception e)
{
if (Misc.IsCriticalException(e))
{
throw;
}
// ignore exceptions for now since we've no way to let clients add exception handlers
}
}
_fBusy = false;
}
}
private void Init()
{
// Keep the garbage collector from moving things around
_winEventProc = new NativeMethods.WinEventProcDef(WinEventReentrancyFilter);
_gchThis = GCHandle.Alloc(_winEventProc);
_clientCallbacks = new ArrayList(2);
_qEvents = new Queue(16, (float)2.0); // (initial cap, growth factor)
_fFlags = NativeMethods.WINEVENT_OUTOFCONTEXT;
}
#endregion Private Methods
#region Internal Types
// -----------------------------------------------------
//
// Internal Types Declaration
//
// ------------------------------------------------------
// Function call to either the Start or Stop Listener
internal delegate void StartStopDelegate();
#endregion Internal Types
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Fields
private class WinEvent
{
internal WinEvent(int eventId, IntPtr hwnd, int idObject, int idChild)
{
_eventId = eventId;
_hwnd = hwnd;
_idObject = idObject;
_idChild = idChild;
}
public int _eventId;
public IntPtr _hwnd;
public int _idObject;
public int _idChild;
}
private Queue _qEvents; // Queue of events waiting to be processed
private int _eventMin; // minimum WinEvent type in range
private int _eventMax; // maximium WinEventType in range
private IntPtr [] _hHooks; // the returned handles(s) from SetWinEventHook
private bool _fBusy; // Flag indicating if we're busy processing
private int _fFlags; // SetWinEventHook flags
private GCHandle _gchThis; // GCHandle to keep GCs from moving this callback
private NativeMethods.WinEventProcDef _winEventProc; // the callback handed to USER for WinEvents
protected ArrayList _clientCallbacks; // the client callback interface objects
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WebRequestModuleElementCollection.cs
- CompoundFileStreamReference.cs
- WindowsFormsLinkLabel.cs
- CodeArrayCreateExpression.cs
- AutomationPattern.cs
- TextRangeBase.cs
- MILUtilities.cs
- OracleRowUpdatingEventArgs.cs
- Validator.cs
- TableFieldsEditor.cs
- TrustManagerMoreInformation.cs
- WebScriptClientGenerator.cs
- EmbeddedObject.cs
- XmlKeywords.cs
- MarkupObject.cs
- HelpInfo.cs
- x509utils.cs
- MemberAssignment.cs
- PointAnimationUsingKeyFrames.cs
- WinFormsSpinner.cs
- HttpResponseInternalWrapper.cs
- XmlCountingReader.cs
- DataGridViewButtonCell.cs
- WindowsFormsHostPropertyMap.cs
- DiscoveryDocumentSerializer.cs
- CommandID.cs
- UInt64Storage.cs
- SizeValueSerializer.cs
- GPRECT.cs
- HexParser.cs
- ApplicationManager.cs
- FixedTextPointer.cs
- Int64AnimationBase.cs
- TextServicesDisplayAttributePropertyRanges.cs
- CodeDirectionExpression.cs
- DataBindEngine.cs
- SplitterCancelEvent.cs
- ImpersonateTokenRef.cs
- ConnectionConsumerAttribute.cs
- ToolStripStatusLabel.cs
- ContainerUIElement3D.cs
- WebHttpElement.cs
- ProgressBar.cs
- GroupDescription.cs
- OutOfProcStateClientManager.cs
- ClientTarget.cs
- TraceSwitch.cs
- TextBreakpoint.cs
- EventDescriptor.cs
- ImageListStreamer.cs
- URLIdentityPermission.cs
- NameSpaceExtractor.cs
- MetabaseServerConfig.cs
- MobileControlPersister.cs
- PreviousTrackingServiceAttribute.cs
- Effect.cs
- StorageComplexPropertyMapping.cs
- VirtualizedCellInfoCollection.cs
- ExeConfigurationFileMap.cs
- Path.cs
- HttpsHostedTransportConfiguration.cs
- DecimalStorage.cs
- SqlFacetAttribute.cs
- ResourcesBuildProvider.cs
- Double.cs
- TypeGenericEnumerableViewSchema.cs
- OpCopier.cs
- PresentationAppDomainManager.cs
- XmlNodeWriter.cs
- XmlSchemaSimpleTypeUnion.cs
- ConsumerConnectionPointCollection.cs
- EventSchemaTraceListener.cs
- ScrollChangedEventArgs.cs
- SQLInt32Storage.cs
- ChangesetResponse.cs
- XmlTextAttribute.cs
- CookieParameter.cs
- ResolvedKeyFrameEntry.cs
- RecordManager.cs
- ValidationRule.cs
- HandlerMappingMemo.cs
- DockEditor.cs
- ConfigXmlSignificantWhitespace.cs
- IndicFontClient.cs
- PolicyValidationException.cs
- AppDomainUnloadedException.cs
- ADMembershipProvider.cs
- EventLogPermission.cs
- HistoryEventArgs.cs
- BeginStoryboard.cs
- Rectangle.cs
- WindowsFormsSynchronizationContext.cs
- PropVariant.cs
- StructuredTypeEmitter.cs
- ByteAnimationBase.cs
- CharStorage.cs
- TextEditorThreadLocalStore.cs
- Vector3D.cs
- FaultDesigner.cs
- DatePickerAutomationPeer.cs